From 4ccf02137627f18d5e8e02075d1ab0f7adb6c804 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 15 Jul 2014 01:01:37 +0200 Subject: [PATCH 001/233] Fixed EulerAngles operator+= return type Thanks to Raakz Former-commit-id: 2247fe952cd593adea90336ea7f8507e83dea3b1 --- include/Nazara/Math/EulerAngles.hpp | 4 ++-- include/Nazara/Math/EulerAngles.inl | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/Nazara/Math/EulerAngles.hpp b/include/Nazara/Math/EulerAngles.hpp index 6b6cabc2d..73f86e25f 100644 --- a/include/Nazara/Math/EulerAngles.hpp +++ b/include/Nazara/Math/EulerAngles.hpp @@ -43,8 +43,8 @@ template class NzEulerAngles /*NzEulerAngles operator*(const NzEulerAngles& angles) const; NzEulerAngles operator/(const NzEulerAngles& angles) const;*/ - NzEulerAngles operator+=(const NzEulerAngles& angles); - NzEulerAngles operator-=(const NzEulerAngles& angles); + NzEulerAngles& operator+=(const NzEulerAngles& angles); + NzEulerAngles& operator-=(const NzEulerAngles& angles); /*NzEulerAngles operator*=(const NzEulerAngles& angles); NzEulerAngles operator/=(const NzEulerAngles& angles);*/ diff --git a/include/Nazara/Math/EulerAngles.inl b/include/Nazara/Math/EulerAngles.inl index a085d99cf..af9f8e521 100644 --- a/include/Nazara/Math/EulerAngles.inl +++ b/include/Nazara/Math/EulerAngles.inl @@ -123,7 +123,7 @@ NzEulerAngles NzEulerAngles::operator-(const NzEulerAngles& angles) const } template -NzEulerAngles NzEulerAngles::operator+=(const NzEulerAngles& angles) +NzEulerAngles& NzEulerAngles::operator+=(const NzEulerAngles& angles) { pitch += angles.pitch; yaw += angles.yaw; @@ -133,7 +133,7 @@ NzEulerAngles NzEulerAngles::operator+=(const NzEulerAngles& angles) } template -NzEulerAngles NzEulerAngles::operator-=(const NzEulerAngles& angles) +NzEulerAngles& NzEulerAngles::operator-=(const NzEulerAngles& angles) { pitch -= angles.pitch; yaw -= angles.yaw; From fba2e5ae012caa9f554e5204f1bb8e2104bc4e85 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 17 Jul 2014 20:15:29 +0200 Subject: [PATCH 002/233] Moved MD5[Anim|Mesh]Parser loading code to Loader Similary to OBJParser Former-commit-id: 243b05f2fbc3899089ef05a29672979d3bbca695 --- src/Nazara/Graphics/Loaders/OBJ/OBJParser.cpp | 14 +- src/Nazara/Utility/Loaders/MD5Anim/Loader.cpp | 54 +++- src/Nazara/Utility/Loaders/MD5Anim/Parser.cpp | 78 ++--- src/Nazara/Utility/Loaders/MD5Anim/Parser.hpp | 37 ++- src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp | 287 ++++++++++++++++- src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp | 296 ++---------------- src/Nazara/Utility/Loaders/MD5Mesh/Parser.hpp | 53 ++-- 7 files changed, 451 insertions(+), 368 deletions(-) diff --git a/src/Nazara/Graphics/Loaders/OBJ/OBJParser.cpp b/src/Nazara/Graphics/Loaders/OBJ/OBJParser.cpp index 933deeca6..a527008f8 100644 --- a/src/Nazara/Graphics/Loaders/OBJ/OBJParser.cpp +++ b/src/Nazara/Graphics/Loaders/OBJ/OBJParser.cpp @@ -27,7 +27,7 @@ NzOBJParser::~NzOBJParser() const NzString* NzOBJParser::GetMaterials() const { - return &m_materials[0]; + return m_materials.data(); } unsigned int NzOBJParser::GetMaterialCount() const @@ -37,7 +37,7 @@ unsigned int NzOBJParser::GetMaterialCount() const const NzOBJParser::Mesh* NzOBJParser::GetMeshes() const { - return &m_meshes[0]; + return m_meshes.data(); } unsigned int NzOBJParser::GetMeshCount() const @@ -52,7 +52,7 @@ const NzString& NzOBJParser::GetMtlLib() const const NzVector3f* NzOBJParser::GetNormals() const { - return &m_normals[0]; + return m_normals.data(); } unsigned int NzOBJParser::GetNormalCount() const @@ -62,7 +62,7 @@ unsigned int NzOBJParser::GetNormalCount() const const NzVector4f* NzOBJParser::GetPositions() const { - return &m_positions[0]; + return m_positions.data(); } unsigned int NzOBJParser::GetPositionCount() const @@ -72,7 +72,7 @@ unsigned int NzOBJParser::GetPositionCount() const const NzVector3f* NzOBJParser::GetTexCoords() const { - return &m_texCoords[0]; + return m_texCoords.data(); } unsigned int NzOBJParser::GetTexCoordCount() const @@ -265,8 +265,8 @@ bool NzOBJParser::Parse() break; } + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING case 's': - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING if (m_currentLine.GetSize() <= 2 || m_currentLine[1] == ' ') { NzString param = m_currentLine.SubString(2); @@ -275,8 +275,8 @@ bool NzOBJParser::Parse() } else UnrecognizedLine(); - #endif break; + #endif case 'u': #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING diff --git a/src/Nazara/Utility/Loaders/MD5Anim/Loader.cpp b/src/Nazara/Utility/Loaders/MD5Anim/Loader.cpp index 8f9a34783..6558029d1 100644 --- a/src/Nazara/Utility/Loaders/MD5Anim/Loader.cpp +++ b/src/Nazara/Utility/Loaders/MD5Anim/Loader.cpp @@ -15,14 +15,62 @@ namespace nzTernary Check(NzInputStream& stream, const NzAnimationParams& parameters) { - NzMD5AnimParser parser(stream, parameters); + NzMD5AnimParser parser(stream); return parser.Check(); } bool Load(NzAnimation* animation, NzInputStream& stream, const NzAnimationParams& parameters) { - NzMD5AnimParser parser(stream, parameters); - return parser.Parse(animation); + NzMD5AnimParser parser(stream); + + if (!parser.Parse()) + { + NazaraError("MD5Anim parser failed"); + return false; + } + + const NzMD5AnimParser::Frame* frames = parser.GetFrames(); + unsigned int frameCount = parser.GetFrameCount(); + unsigned int frameRate = parser.GetFrameRate(); + const NzMD5AnimParser::Joint* joints = parser.GetJoints(); + unsigned int jointCount = parser.GetJointCount(); + + // À ce stade, nous sommes censés avoir assez d'informations pour créer l'animation + animation->CreateSkeletal(frameCount, jointCount); + + NzSequence sequence; + sequence.firstFrame = 0; + sequence.frameCount = frameCount; + sequence.frameRate = frameRate; + sequence.name = stream.GetPath().SubStringFrom(NAZARA_DIRECTORY_SEPARATOR, -1, true); + + animation->AddSequence(sequence); + + NzSequenceJoint* sequenceJoints = animation->GetSequenceJoints(); + + // Pour que le squelette soit correctement aligné, il faut appliquer un quaternion "de correction" aux joints à la base du squelette + NzQuaternionf rotationQuat = NzEulerAnglesf(-90.f, 90.f, 0.f); + for (unsigned int i = 0; i < jointCount; ++i) + { + int parent = joints[i].parent; + for (unsigned int j = 0; j < frameCount; ++j) + { + NzSequenceJoint& sequenceJoint = sequenceJoints[j*jointCount + i]; + + if (parent >= 0) + { + sequenceJoint.position = frames[j].joints[i].pos; + sequenceJoint.rotation = frames[j].joints[i].orient; + } + else + { + sequenceJoint.position = rotationQuat * frames[j].joints[i].pos; + sequenceJoint.rotation = rotationQuat * frames[j].joints[i].orient; + } + + sequenceJoint.scale.Set(1.f); + } + } } } diff --git a/src/Nazara/Utility/Loaders/MD5Anim/Parser.cpp b/src/Nazara/Utility/Loaders/MD5Anim/Parser.cpp index 8d5399596..4b035a5e7 100644 --- a/src/Nazara/Utility/Loaders/MD5Anim/Parser.cpp +++ b/src/Nazara/Utility/Loaders/MD5Anim/Parser.cpp @@ -13,9 +13,8 @@ #include #include -NzMD5AnimParser::NzMD5AnimParser(NzInputStream& stream, const NzAnimationParams& parameters) : +NzMD5AnimParser::NzMD5AnimParser(NzInputStream& stream) : m_stream(stream), -m_parameters(parameters), m_keepLastLine(false), m_frameIndex(0), m_frameRate(0), @@ -47,7 +46,37 @@ nzTernary NzMD5AnimParser::Check() return nzTernary_False; } -bool NzMD5AnimParser::Parse(NzAnimation* animation) +unsigned int NzMD5AnimParser::GetAnimatedComponentCount() const +{ + return m_animatedComponents.size(); +} + +const NzMD5AnimParser::Frame* NzMD5AnimParser::GetFrames() const +{ + return m_frames.data(); +} + +unsigned int NzMD5AnimParser::GetFrameCount() const +{ + return m_frames.size(); +} + +unsigned int NzMD5AnimParser::GetFrameRate() const +{ + return m_frameRate; +} + +const NzMD5AnimParser::Joint* NzMD5AnimParser::GetJoints() const +{ + return m_joints.data(); +} + +unsigned int NzMD5AnimParser::GetJointCount() const +{ + return m_joints.size(); +} + +bool NzMD5AnimParser::Parse() { while (Advance(false)) { @@ -204,47 +233,6 @@ bool NzMD5AnimParser::Parse(NzAnimation* animation) m_frameRate = 24; } - // À ce stade, nous sommes censés avoir assez d'informations pour créer l'animation - if (!animation->CreateSkeletal(frameCount, jointCount)) - { - NazaraError("Failed to create animation"); - return false; - } - - NzSequence sequence; - sequence.firstFrame = 0; - sequence.frameCount = m_frames.size(); - sequence.frameRate = m_frameRate; - sequence.name = m_stream.GetPath().SubStringFrom(NAZARA_DIRECTORY_SEPARATOR, -1, true); - if (!animation->AddSequence(sequence)) - NazaraWarning("Failed to add sequence"); - - NzSequenceJoint* sequenceJoints = animation->GetSequenceJoints(); - - // Pour que le squelette soit correctement aligné, il faut appliquer un quaternion "de correction" aux joints à la base du squelette - NzQuaternionf rotationQuat = NzEulerAnglesf(-90.f, 90.f, 0.f); - for (unsigned int i = 0; i < jointCount; ++i) - { - int parent = m_joints[i].parent; - for (unsigned int j = 0; j < frameCount; ++j) - { - NzSequenceJoint& sequenceJoint = sequenceJoints[j*jointCount + i]; - - if (parent >= 0) - { - sequenceJoint.position = m_frames[j].joints[i].pos; - sequenceJoint.rotation = m_frames[j].joints[i].orient; - } - else - { - sequenceJoint.position = rotationQuat * m_frames[j].joints[i].pos; - sequenceJoint.rotation = rotationQuat * m_frames[j].joints[i].orient; - } - - sequenceJoint.scale.Set(1.f); - } - } - return true; } @@ -340,7 +328,7 @@ bool NzMD5AnimParser::ParseBounds() return false; } - m_frames[i].aabb.Set(min, max); + m_frames[i].bounds.Set(min, max); } if (!Advance()) diff --git a/src/Nazara/Utility/Loaders/MD5Anim/Parser.hpp b/src/Nazara/Utility/Loaders/MD5Anim/Parser.hpp index 1fc097f59..e3b9e19c8 100644 --- a/src/Nazara/Utility/Loaders/MD5Anim/Parser.hpp +++ b/src/Nazara/Utility/Loaders/MD5Anim/Parser.hpp @@ -18,23 +18,16 @@ class NzMD5AnimParser { public: - NzMD5AnimParser(NzInputStream& stream, const NzAnimationParams& parameters); - ~NzMD5AnimParser(); + struct FrameJoint + { + NzQuaternionf orient; + NzVector3f pos; + }; - nzTernary Check(); - bool Parse(NzAnimation* animation); - - private: struct Frame { - struct Joint - { - NzQuaternionf orient; - NzVector3f pos; - }; - - std::vector joints; - NzBoxf aabb; + std::vector joints; + NzBoxf bounds; }; struct Joint @@ -47,6 +40,21 @@ class NzMD5AnimParser unsigned int index; }; + NzMD5AnimParser(NzInputStream& stream); + ~NzMD5AnimParser(); + + nzTernary Check(); + + unsigned int GetAnimatedComponentCount() const; + const Frame* GetFrames() const; + unsigned int GetFrameCount() const; + unsigned int GetFrameRate() const; + const Joint* GetJoints() const; + unsigned int GetJointCount() const; + + bool Parse(); + + private: bool Advance(bool required = true); void Error(const NzString& message); bool ParseBaseframe(); @@ -61,7 +69,6 @@ class NzMD5AnimParser std::vector m_joints; NzInputStream& m_stream; NzString m_currentLine; - const NzAnimationParams& m_parameters; bool m_keepLastLine; unsigned int m_frameIndex; unsigned int m_frameRate; diff --git a/src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp b/src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp index 9973fbc84..ae3e22977 100644 --- a/src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp +++ b/src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp @@ -4,6 +4,11 @@ #include #include +#include +#include +#include +#include +#include #include namespace @@ -15,14 +20,290 @@ namespace nzTernary Check(NzInputStream& stream, const NzMeshParams& parameters) { - NzMD5MeshParser parser(stream, parameters); + NazaraUnused(parameters); + + NzMD5MeshParser parser(stream); return parser.Check(); } bool Load(NzMesh* mesh, NzInputStream& stream, const NzMeshParams& parameters) { - NzMD5MeshParser parser(stream, parameters); - return parser.Parse(mesh); + NzMD5MeshParser parser(stream); + if (!parser.Parse()) + { + NazaraError("MD5Mesh parser failed"); + return false; + } + + // Pour que le squelette soit correctement aligné, il faut appliquer un quaternion "de correction" aux joints à la base du squelette + NzQuaternionf rotationQuat = NzEulerAnglesf(-90.f, 180.f, 0.f); + NzString baseDir = stream.GetDirectory(); + + // Le hellknight de Doom 3 fait ~120 unités, et il est dit qu'il fait trois mètres + // Nous réduisons donc la taille générale des fichiers MD5 de 1/40 + NzVector3f scale(parameters.scale/40.f); + + const NzMD5MeshParser::Joint* joints = parser.GetJoints(); + const NzMD5MeshParser::Mesh* meshes = parser.GetMeshes(); + unsigned int jointCount = parser.GetJointCount(); + unsigned int meshCount = parser.GetMeshCount(); + + if (parameters.animated) + { + mesh->CreateSkeletal(jointCount); + + NzSkeleton* skeleton = mesh->GetSkeleton(); + for (unsigned int i = 0; i < jointCount; ++i) + { + NzJoint* joint = skeleton->GetJoint(i); + + int parent = joints[i].parent; + if (parent >= 0) + joint->SetParent(skeleton->GetJoint(parent)); + + joint->SetName(joints[i].name); + + NzMatrix4f bindMatrix; + + if (parent >= 0) + bindMatrix.MakeTransform(joints[i].bindPos, joints[i].bindOrient); + else + bindMatrix.MakeTransform(rotationQuat * joints[i].bindPos, rotationQuat * joints[i].bindOrient); + + joint->SetInverseBindMatrix(bindMatrix.InverseAffine()); + } + + mesh->SetMaterialCount(meshCount); + for (unsigned int i = 0; i < meshCount; ++i) + { + const NzMD5MeshParser::Mesh& md5Mesh = meshes[i]; + + unsigned int indexCount = md5Mesh.triangles.size()*3; + unsigned int vertexCount = md5Mesh.vertices.size(); + + bool largeIndices = (vertexCount > std::numeric_limits::max()); + + std::unique_ptr indexBuffer(new NzIndexBuffer(largeIndices, indexCount, parameters.storage)); + indexBuffer->SetPersistent(false); + + std::unique_ptr vertexBuffer(new NzVertexBuffer(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Normal_UV_Tangent_Skinning), vertexCount, parameters.storage, nzBufferUsage_Static)); + vertexBuffer->SetPersistent(false); + + // Index buffer + NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_DiscardAndWrite); + + // Le format définit un set de triangles nous permettant de retrouver facilement les indices + // Cependant les sommets des triangles ne sont pas spécifiés dans le même ordre que ceux du moteur + // (On parle ici de winding) + unsigned int index = 0; + for (const NzMD5MeshParser::Triangle& triangle : md5Mesh.triangles) + { + // On les respécifie dans le bon ordre (inversion du winding) + indexMapper.Set(index++, triangle.x); + indexMapper.Set(index++, triangle.z); + indexMapper.Set(index++, triangle.y); + } + + indexMapper.Unmap(); + + // Vertex buffer + struct Weight + { + float bias; + unsigned int jointIndex; + }; + + std::vector tempWeights; + + NzBufferMapper vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly); + NzSkeletalMeshVertex* vertices = static_cast(vertexMapper.GetPointer()); + for (const NzMD5MeshParser::Vertex& vertex : md5Mesh.vertices) + { + // Skinning MD5 (Formule d'Id Tech) + NzVector3f finalPos(NzVector3f::Zero()); + + // On stocke tous les poids dans le tableau temporaire en même temps qu'on calcule la position finale du sommet. + tempWeights.resize(vertex.weightCount); + for (unsigned int j = 0; j < vertex.weightCount; ++j) + { + const NzMD5MeshParser::Weight& weight = md5Mesh.weights[vertex.startWeight + j]; + const NzMD5MeshParser::Joint& joint = joints[weight.joint]; + + finalPos += (joint.bindPos + joint.bindOrient*weight.pos) * weight.bias; + + // Avant d'ajouter les poids, il faut s'assurer qu'il n'y en ait pas plus que le maximum supporté + // et dans le cas contraire, garder les poids les plus importants et les renormaliser + tempWeights[j] = {weight.bias, weight.joint}; + } + + // Avons nous plus de poids que le moteur ne peut en supporter ? + unsigned int weightCount = vertex.weightCount; + if (weightCount > NAZARA_UTILITY_SKINNING_MAX_WEIGHTS) + { + // Pour augmenter la qualité du skinning tout en ne gardant que X poids, on ne garde que les poids + // les plus importants, ayant le plus d'impact sur le sommet final + std::sort(tempWeights.begin(), tempWeights.end(), [] (const Weight& a, const Weight& b) -> bool { + return a.bias > b.bias; + }); + + // Sans oublier bien sûr de renormaliser les poids (que leur somme soit 1) + float weightSum = 0.f; + for (unsigned int j = 0; j < NAZARA_UTILITY_SKINNING_MAX_WEIGHTS; ++j) + weightSum += tempWeights[j].bias; + + for (unsigned int j = 0; j < NAZARA_UTILITY_SKINNING_MAX_WEIGHTS; ++j) + tempWeights[j].bias /= weightSum; + + weightCount = NAZARA_UTILITY_SKINNING_MAX_WEIGHTS; + } + + vertices->weightCount = weightCount; + for (unsigned int j = 0; j < NAZARA_UTILITY_SKINNING_MAX_WEIGHTS; ++j) + { + if (j < weightCount) + { + // On donne une valeur aux poids présents + vertices->weights[j] = tempWeights[j].bias; + vertices->jointIndexes[j] = tempWeights[j].jointIndex; + } + else + { + // Et un poids de 0 sur le joint 0 pour les autres (nécessaire pour le GPU Skinning) + // La raison est que le GPU ne tiendra pas compte du nombre de poids pour des raisons de performances. + vertices->weights[j] = 0.f; + vertices->jointIndexes[j] = 0; + } + } + + vertices->position = finalPos; + + // Le format MD5 spécifie ses UV avec l'origine en bas à gauche, contrairement au moteur + // dont l'origine est en haut à gauche, nous inversons donc la valeur en Y. + vertices->uv.Set(vertex.uv.x, 1.f - vertex.uv.y); + vertices++; + } + + vertexMapper.Unmap(); + + // Material + mesh->SetMaterial(i, baseDir + md5Mesh.shader); + + // Submesh + std::unique_ptr subMesh(new NzSkeletalMesh(mesh)); + subMesh->Create(vertexBuffer.get()); + vertexBuffer.release(); + + if (parameters.optimizeIndexBuffers) + indexBuffer->Optimize(); + + subMesh->SetIndexBuffer(indexBuffer.get()); + indexBuffer.release(); + + subMesh->GenerateNormalsAndTangents(); + subMesh->SetMaterialIndex(i); + subMesh->SetPrimitiveMode(nzPrimitiveMode_TriangleList); + + mesh->AddSubMesh(subMesh.get()); + subMesh.release(); + + // Animation + // Il est peut-être éventuellement possible que la probabilité que l'animation ait le même nom soit non-nulle. + NzString path = stream.GetPath(); + if (!path.IsEmpty()) + { + path.Replace(".md5mesh", ".md5anim", -8, NzString::CaseInsensitive); + if (NzFile::Exists(path)) + mesh->SetAnimation(path); + } + } + } + else + { + if (!mesh->CreateStatic()) // Ne devrait jamais échouer + { + NazaraInternalError("Failed to create mesh"); + return false; + } + + mesh->SetMaterialCount(meshCount); + for (unsigned int i = 0; i < meshCount; ++i) + { + const NzMD5MeshParser::Mesh& md5Mesh = meshes[i]; + unsigned int indexCount = md5Mesh.triangles.size()*3; + unsigned int vertexCount = md5Mesh.vertices.size(); + + // Index buffer + bool largeIndices = (vertexCount > std::numeric_limits::max()); + + std::unique_ptr indexBuffer(new NzIndexBuffer(largeIndices, indexCount, parameters.storage)); + indexBuffer->SetPersistent(false); + + NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_DiscardAndWrite); + NzIndexIterator index = indexMapper.begin(); + + for (const NzMD5MeshParser::Triangle& triangle : md5Mesh.triangles) + { + // On les respécifie dans le bon ordre + *index++ = triangle.x; + *index++ = triangle.z; + *index++ = triangle.y; + } + indexMapper.Unmap(); + + // Vertex buffer + std::unique_ptr vertexBuffer(new NzVertexBuffer(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Normal_UV_Tangent), vertexCount, parameters.storage)); + NzBufferMapper vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly); + + NzMeshVertex* vertex = reinterpret_cast(vertexMapper.GetPointer()); + for (const NzMD5MeshParser::Vertex& md5Vertex : md5Mesh.vertices) + { + // Skinning MD5 (Formule d'Id Tech) + NzVector3f finalPos(NzVector3f::Zero()); + for (unsigned int j = 0; j < md5Vertex.weightCount; ++j) + { + const NzMD5MeshParser::Weight& weight = md5Mesh.weights[md5Vertex.startWeight + j]; + const NzMD5MeshParser::Joint& joint = joints[weight.joint]; + + finalPos += (joint.bindPos + joint.bindOrient*weight.pos) * weight.bias; + } + + // On retourne le modèle dans le bon sens + vertex->position = scale * (rotationQuat * finalPos); + vertex->uv.Set(md5Vertex.uv.x, 1.f - md5Vertex.uv.y); + vertex++; + } + + vertexMapper.Unmap(); + + // Submesh + std::unique_ptr subMesh(new NzStaticMesh(mesh)); + subMesh->Create(vertexBuffer.get()); + + vertexBuffer->SetPersistent(false); + vertexBuffer.release(); + + if (parameters.optimizeIndexBuffers) + indexBuffer->Optimize(); + + subMesh->SetIndexBuffer(indexBuffer.get()); + indexBuffer.release(); + + // Material + mesh->SetMaterial(i, baseDir + md5Mesh.shader); + + subMesh->GenerateAABB(); + subMesh->GenerateNormalsAndTangents(); + subMesh->SetMaterialIndex(i); + + if (parameters.center) + subMesh->Center(); + + mesh->AddSubMesh(subMesh.get()); + subMesh.release(); + } + } + + return true; } } diff --git a/src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp b/src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp index 03e244a0c..c9747371f 100644 --- a/src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp +++ b/src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp @@ -19,9 +19,8 @@ #include #include -NzMD5MeshParser::NzMD5MeshParser(NzInputStream& stream, const NzMeshParams& parameters) : +NzMD5MeshParser::NzMD5MeshParser(NzInputStream& stream) : m_stream(stream), -m_parameters(parameters), m_keepLastLine(false), m_lineCount(0), m_meshIndex(0), @@ -52,7 +51,27 @@ nzTernary NzMD5MeshParser::Check() return nzTernary_False; } -bool NzMD5MeshParser::Parse(NzMesh* mesh) +const NzMD5MeshParser::Joint* NzMD5MeshParser::GetJoints() const +{ + return m_joints.data(); +} + +unsigned int NzMD5MeshParser::GetJointCount() const +{ + return m_joints.size(); +} + +const NzMD5MeshParser::Mesh* NzMD5MeshParser::GetMeshes() const +{ + return m_meshes.data(); +} + +unsigned int NzMD5MeshParser::GetMeshCount() const +{ + return m_meshes.size(); +} + +bool NzMD5MeshParser::Parse() { while (Advance(false)) { @@ -151,271 +170,6 @@ bool NzMD5MeshParser::Parse(NzMesh* mesh) } } - // Pour que le squelette soit correctement aligné, il faut appliquer un quaternion "de correction" aux joints à la base du squelette - NzQuaternionf rotationQuat = NzEulerAnglesf(-90.f, 180.f, 0.f); - NzString baseDir = m_stream.GetDirectory(); - - // Le hellknight de Doom 3 fait ~120 unités, et il est dit qu'il fait trois mètres - // Nous réduisons donc la taille générale des fichiers MD5 de 1/40 - NzVector3f scale(m_parameters.scale/40.f); - - if (m_parameters.animated) - { - if (!mesh->CreateSkeletal(m_joints.size())) // Ne devrait jamais échouer - { - NazaraInternalError("Failed to create mesh"); - return false; - } - - NzSkeleton* skeleton = mesh->GetSkeleton(); - for (unsigned int i = 0; i < m_joints.size(); ++i) - { - NzJoint* joint = skeleton->GetJoint(i); - - int parent = m_joints[i].parent; - if (parent >= 0) - joint->SetParent(skeleton->GetJoint(parent)); - - joint->SetName(m_joints[i].name); - - NzMatrix4f bindMatrix; - - if (parent >= 0) - bindMatrix.MakeTransform(m_joints[i].bindPos, m_joints[i].bindOrient); - else - bindMatrix.MakeTransform(rotationQuat * m_joints[i].bindPos, rotationQuat * m_joints[i].bindOrient); - - joint->SetInverseBindMatrix(bindMatrix.InverseAffine()); - } - - mesh->SetMaterialCount(m_meshes.size()); - for (unsigned int i = 0; i < m_meshes.size(); ++i) - { - const Mesh& md5Mesh = m_meshes[i]; - - unsigned int indexCount = md5Mesh.triangles.size()*3; - unsigned int vertexCount = md5Mesh.vertices.size(); - - bool largeIndices = (vertexCount > std::numeric_limits::max()); - - std::unique_ptr indexBuffer(new NzIndexBuffer(largeIndices, indexCount, m_parameters.storage)); - indexBuffer->SetPersistent(false); - - std::unique_ptr vertexBuffer(new NzVertexBuffer(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Normal_UV_Tangent_Skinning), vertexCount, m_parameters.storage, nzBufferUsage_Static)); - vertexBuffer->SetPersistent(false); - - // Index buffer - NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_DiscardAndWrite); - - unsigned int index = 0; - for (const Mesh::Triangle& triangle : md5Mesh.triangles) - { - // On les respécifie dans le bon ordre - indexMapper.Set(index++, triangle.x); - indexMapper.Set(index++, triangle.z); - indexMapper.Set(index++, triangle.y); - } - - indexMapper.Unmap(); - - // Vertex buffer - struct Weight - { - float bias; - unsigned int jointIndex; - }; - - std::vector tempWeights(NAZARA_UTILITY_SKINNING_MAX_WEIGHTS); - - NzBufferMapper vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly); - NzSkeletalMeshVertex* vertices = static_cast(vertexMapper.GetPointer()); - for (const Mesh::Vertex& vertex : md5Mesh.vertices) - { - // Skinning MD5 (Formule d'Id Tech) - NzVector3f finalPos(NzVector3f::Zero()); - - tempWeights.resize(vertex.weightCount); - for (unsigned int j = 0; j < vertex.weightCount; ++j) - { - const Mesh::Weight& weight = md5Mesh.weights[vertex.startWeight + j]; - const Joint& joint = m_joints[weight.joint]; - - finalPos += (joint.bindPos + joint.bindOrient*weight.pos) * weight.bias; - - // Avant d'ajouter les poids, il faut s'assurer qu'il n'y en ait pas plus que le maximum supporté - // et dans le cas contraire, garder les poids les plus importants et les renormaliser - tempWeights[j] = {weight.bias, weight.joint}; - } - - unsigned int weightCount = vertex.weightCount; - if (weightCount > NAZARA_UTILITY_SKINNING_MAX_WEIGHTS) - { - // Pour augmenter la qualité du skinning tout en ne gardant que X poids, on ne garde que les poids - // les plus importants, ayant le plus d'impact sur le sommet final - std::sort(tempWeights.begin(), tempWeights.end(), [] (const Weight& a, const Weight& b) -> bool { - return a.bias > b.bias; - }); - - // Sans oublier bien sûr de renormaliser les poids (que leur somme soit 1) - float weightSum = 0.f; - for (unsigned int j = 0; j < NAZARA_UTILITY_SKINNING_MAX_WEIGHTS; ++j) - weightSum += tempWeights[j].bias; - - for (unsigned int j = 0; j < NAZARA_UTILITY_SKINNING_MAX_WEIGHTS; ++j) - tempWeights[j].bias /= weightSum; - - weightCount = NAZARA_UTILITY_SKINNING_MAX_WEIGHTS; - } - - vertices->weightCount = weightCount; - for (unsigned int j = 0; j < NAZARA_UTILITY_SKINNING_MAX_WEIGHTS; ++j) - { - // On donne une valeur aux poids présents, et 0 pour les autres (nécessaire pour le GPU Skinning) - if (j < weightCount) - { - vertices->weights[j] = tempWeights[j].bias; - vertices->jointIndexes[j] = tempWeights[j].jointIndex; - } - else - { - vertices->weights[j] = 0.f; - vertices->jointIndexes[j] = 0; - } - } - - vertices->position = finalPos; - vertices->uv.Set(vertex.uv.x, 1.f-vertex.uv.y); - vertices++; - } - - vertexMapper.Unmap(); - - // Material - mesh->SetMaterial(i, baseDir + md5Mesh.shader); - - // Submesh - std::unique_ptr subMesh(new NzSkeletalMesh(mesh)); - if (!subMesh->Create(vertexBuffer.get())) - { - NazaraError("Failed to create skeletal mesh"); - continue; - } - vertexBuffer.release(); - - if (m_parameters.optimizeIndexBuffers) - indexBuffer->Optimize(); - - subMesh->SetIndexBuffer(indexBuffer.get()); - indexBuffer.release(); - - subMesh->GenerateNormalsAndTangents(); - subMesh->SetMaterialIndex(i); - subMesh->SetPrimitiveMode(nzPrimitiveMode_TriangleList); - - mesh->AddSubMesh(subMesh.get()); - subMesh.release(); - - // Animation - // Il est peut-être éventuellement possible que la probabilité que l'animation ait le même nom soit non-nulle. - NzString path = m_stream.GetPath(); - if (!path.IsEmpty()) - { - path.Replace(".md5mesh", ".md5anim", -8, NzString::CaseInsensitive); - if (NzFile::Exists(path)) - mesh->SetAnimation(path); - } - } - } - else - { - if (!mesh->CreateStatic()) // Ne devrait jamais échouer - { - NazaraInternalError("Failed to create mesh"); - return false; - } - - mesh->SetMaterialCount(m_meshes.size()); - for (unsigned int i = 0; i < m_meshes.size(); ++i) - { - const Mesh& md5Mesh = m_meshes[i]; - unsigned int indexCount = md5Mesh.triangles.size()*3; - unsigned int vertexCount = md5Mesh.vertices.size(); - - // Index buffer - bool largeIndices = (vertexCount > std::numeric_limits::max()); - - std::unique_ptr indexBuffer(new NzIndexBuffer(largeIndices, indexCount, m_parameters.storage)); - indexBuffer->SetPersistent(false); - - NzIndexMapper indexMapper(indexBuffer.get(), nzBufferAccess_DiscardAndWrite); - NzIndexIterator index = indexMapper.begin(); - - for (const Mesh::Triangle& triangle : md5Mesh.triangles) - { - // On les respécifie dans le bon ordre - *index++ = triangle.x; - *index++ = triangle.z; - *index++ = triangle.y; - } - indexMapper.Unmap(); - - // Vertex buffer - std::unique_ptr vertexBuffer(new NzVertexBuffer(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Normal_UV_Tangent), vertexCount, m_parameters.storage)); - NzBufferMapper vertexMapper(vertexBuffer.get(), nzBufferAccess_WriteOnly); - - NzMeshVertex* vertex = reinterpret_cast(vertexMapper.GetPointer()); - for (const Mesh::Vertex& md5Vertex : md5Mesh.vertices) - { - // Skinning MD5 (Formule d'Id Tech) - NzVector3f finalPos(NzVector3f::Zero()); - for (unsigned int j = 0; j < md5Vertex.weightCount; ++j) - { - const Mesh::Weight& weight = md5Mesh.weights[md5Vertex.startWeight + j]; - const Joint& joint = m_joints[weight.joint]; - - finalPos += (joint.bindPos + joint.bindOrient*weight.pos) * weight.bias; - } - - // On retourne le modèle dans le bon sens - vertex->position = scale * (rotationQuat * finalPos); - vertex->uv.Set(md5Vertex.uv.x, 1.f - md5Vertex.uv.y); - vertex++; - } - - vertexMapper.Unmap(); - - // Submesh - std::unique_ptr subMesh(new NzStaticMesh(mesh)); - if (!subMesh->Create(vertexBuffer.get())) - { - NazaraError("Failed to create static submesh"); - continue; - } - - vertexBuffer->SetPersistent(false); - vertexBuffer.release(); - - if (m_parameters.optimizeIndexBuffers) - indexBuffer->Optimize(); - - subMesh->SetIndexBuffer(indexBuffer.get()); - indexBuffer.release(); - - // Material - mesh->SetMaterial(i, baseDir + md5Mesh.shader); - - subMesh->GenerateAABB(); - subMesh->GenerateNormalsAndTangents(); - subMesh->SetMaterialIndex(i); - - if (m_parameters.center) - subMesh->Center(); - - mesh->AddSubMesh(subMesh.get()); - subMesh.release(); - } - } - return true; } @@ -555,7 +309,7 @@ bool NzMD5MeshParser::ParseMesh() if (!Advance()) return false; - Mesh::Triangle& triangle = m_meshes[m_meshIndex].triangles[i]; + Triangle& triangle = m_meshes[m_meshIndex].triangles[i]; unsigned int index; if (std::sscanf(&m_currentLine[0], "tri %u %u %u %u", &index, &triangle.x, &triangle.y, &triangle.z) != 4) { @@ -578,7 +332,7 @@ bool NzMD5MeshParser::ParseMesh() if (!Advance()) return false; - Mesh::Vertex& vertex = m_meshes[m_meshIndex].vertices[i]; + Vertex& vertex = m_meshes[m_meshIndex].vertices[i]; unsigned int index; if (std::sscanf(&m_currentLine[0], "vert %u ( %f %f ) %u %u", &index, &vertex.uv.x, &vertex.uv.y, &vertex.startWeight, &vertex.weightCount) != 5) { @@ -601,7 +355,7 @@ bool NzMD5MeshParser::ParseMesh() if (!Advance()) return false; - Mesh::Weight& weight = m_meshes[m_meshIndex].weights[i]; + Weight& weight = m_meshes[m_meshIndex].weights[i]; unsigned int index; if (std::sscanf(&m_currentLine[0], "weight %u %u %f ( %f %f %f )", &index, &weight.joint, &weight.bias, &weight.pos.x, &weight.pos.y, &weight.pos.z) != 6) diff --git a/src/Nazara/Utility/Loaders/MD5Mesh/Parser.hpp b/src/Nazara/Utility/Loaders/MD5Mesh/Parser.hpp index 18f0dbc39..cb63af487 100644 --- a/src/Nazara/Utility/Loaders/MD5Mesh/Parser.hpp +++ b/src/Nazara/Utility/Loaders/MD5Mesh/Parser.hpp @@ -18,13 +18,6 @@ class NzMD5MeshParser { public: - NzMD5MeshParser(NzInputStream& stream, const NzMeshParams& parameters); - ~NzMD5MeshParser(); - - nzTernary Check(); - bool Parse(NzMesh* mesh); - - private: struct Joint { NzQuaternionf bindOrient; @@ -33,30 +26,43 @@ class NzMD5MeshParser int parent; }; + typedef NzVector3ui Triangle; + + struct Vertex + { + NzVector2f uv; + unsigned int startWeight; + unsigned int weightCount; + }; + + struct Weight + { + NzVector3f pos; + float bias; + unsigned int joint; + }; + struct Mesh { - typedef NzVector3ui Triangle; - - struct Vertex - { - NzVector2f uv; - unsigned int startWeight; - unsigned int weightCount; - }; - - struct Weight - { - NzVector3f pos; - float bias; - unsigned int joint; - }; - std::vector triangles; std::vector vertices; std::vector weights; NzString shader; }; + NzMD5MeshParser(NzInputStream& stream); + ~NzMD5MeshParser(); + + nzTernary Check(); + + const Joint* GetJoints() const; + unsigned int GetJointCount() const; + const Mesh* GetMeshes() const; + unsigned int GetMeshCount() const; + + bool Parse(); + + private: bool Advance(bool required = true); void Error(const NzString& message); bool ParseJoints(); @@ -68,7 +74,6 @@ class NzMD5MeshParser std::vector m_meshes; NzInputStream& m_stream; NzString m_currentLine; - const NzMeshParams& m_parameters; bool m_keepLastLine; unsigned int m_lineCount; unsigned int m_meshIndex; From e6dea541a76ea54776671b7e7845dad0646dc6b4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 22 Jul 2014 17:26:31 +0200 Subject: [PATCH 003/233] Added memory helpers This will protect some memory-related code from new redefinition Former-commit-id: 337e69e70acd0bf8dbc3ba1657c6bb0bddfd5df4 --- include/Nazara/Core/MemoryHelper.hpp | 20 ++++++++++ include/Nazara/Core/MemoryHelper.inl | 45 +++++++++++++++++++++++ include/Nazara/Core/MemoryPool.inl | 18 ++------- include/Nazara/Lua/LuaClass.inl | 3 +- src/Nazara/Core/Debug/NewRedefinition.cpp | 6 +-- src/Nazara/Core/ParameterList.cpp | 10 ++--- src/Nazara/Lua/LuaInstance.cpp | 5 +-- 7 files changed, 79 insertions(+), 28 deletions(-) create mode 100644 include/Nazara/Core/MemoryHelper.hpp create mode 100644 include/Nazara/Core/MemoryHelper.inl diff --git a/include/Nazara/Core/MemoryHelper.hpp b/include/Nazara/Core/MemoryHelper.hpp new file mode 100644 index 000000000..472f10f9d --- /dev/null +++ b/include/Nazara/Core/MemoryHelper.hpp @@ -0,0 +1,20 @@ +// Copyright (C) 2014 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 + +#pragma once + +#ifndef NAZARA_MEMORYHELPER_HPP +#define NAZARA_MEMORYHELPER_HPP + +#include + +void NzOperatorDelete(void* ptr); +void* NzOperatorNew(std::size_t size); + +template +T* NzPlacementNew(void* ptr, Args... args); + +#include + +#endif // NAZARA_MEMORYHELPER_HPP diff --git a/include/Nazara/Core/MemoryHelper.inl b/include/Nazara/Core/MemoryHelper.inl new file mode 100644 index 000000000..0e27c5462 --- /dev/null +++ b/include/Nazara/Core/MemoryHelper.inl @@ -0,0 +1,45 @@ +// Copyright (C) 2014 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 + +// Je ne suis pas fier des cinq lignes qui suivent mais difficile de faire autrement pour le moment... +#ifdef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION + #define NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION_DEFINED +#else + #define NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION +#endif + +#include +#include +#include + +inline void NzOperatorDelete(void* ptr) +{ + #if NAZARA_CORE_MANAGE_MEMORY + NzMemoryManager::Free(ptr); + #else + operator delete(ptr); + #endif +} + +inline void* NzOperatorNew(std::size_t size) +{ + #if NAZARA_CORE_MANAGE_MEMORY + return NzMemoryManager::Allocate(size); + #else + return operator new(size); + #endif +} + +template +T* NzPlacementNew(void* ptr, Args... args) +{ + return new (ptr) T(args...); +} + +#include + +// Si c'est nous qui avons défini la constante, alors il nous faut l'enlever (Pour éviter que le moteur entier n'en souffre) +#ifndef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION_DEFINED + #undef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION +#endif diff --git a/include/Nazara/Core/MemoryPool.inl b/include/Nazara/Core/MemoryPool.inl index 5521e790d..8e8034814 100644 --- a/include/Nazara/Core/MemoryPool.inl +++ b/include/Nazara/Core/MemoryPool.inl @@ -2,14 +2,7 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp -// Je ne suis pas fier des cinq lignes qui suivent mais difficile de faire autrement pour le moment... -#ifdef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION - #define NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION_DEFINED -#else - #define NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION -#endif - -#include +#include #include template @@ -58,7 +51,7 @@ void* NzMemoryPool::Allocate(unsigned int size) } } - return operator new(size); + return NzOperatorNew(size); } template @@ -93,7 +86,7 @@ void NzMemoryPool::Free(void* ptr) if (m_next) m_next->Free(ptr); else - operator delete(ptr); + NzOperatorDelete(ptr); } } } @@ -111,8 +104,3 @@ unsigned int NzMemoryPool::GetSize() const } #include - -// Si c'est nous qui avons défini la constante, alors il nous faut l'enlever (Pour éviter que le moteur entier n'en souffre) -#ifndef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION_DEFINED - #undef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION -#endif diff --git a/include/Nazara/Lua/LuaClass.inl b/include/Nazara/Lua/LuaClass.inl index ac79d2468..a63adc081 100644 --- a/include/Nazara/Lua/LuaClass.inl +++ b/include/Nazara/Lua/LuaClass.inl @@ -4,6 +4,7 @@ #include #include +#include #include template @@ -31,7 +32,7 @@ void NzLuaClass::Register(NzLuaInstance& lua) // Ainsi c'est Lua qui va s'occuper de la destruction pour nous :-) // De même, l'utilisation d'un shared_ptr permet de garder la structure en vie même si l'instance est libérée avant le LuaClass void* info = lua.PushUserdata(sizeof(std::shared_ptr)); - new (info) std::shared_ptr(m_info); + NzPlacementNew>(info, m_info); // On créé la table qui contiendra une méthode (Le finalizer) pour libérer le ClassInfo lua.PushTable(0, 1); diff --git a/src/Nazara/Core/Debug/NewRedefinition.cpp b/src/Nazara/Core/Debug/NewRedefinition.cpp index b4c06b816..b5707192e 100644 --- a/src/Nazara/Core/Debug/NewRedefinition.cpp +++ b/src/Nazara/Core/Debug/NewRedefinition.cpp @@ -5,12 +5,12 @@ #include #if NAZARA_CORE_MANAGE_MEMORY -#define NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION - -#include #include #include // Nécessaire ? +#define NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION +#include + void* operator new(std::size_t size, const char* file, unsigned int line) { return NzMemoryManager::Allocate(size, false, file, line); diff --git a/src/Nazara/Core/ParameterList.cpp b/src/Nazara/Core/ParameterList.cpp index ba0e7322e..6ac8e9c54 100644 --- a/src/Nazara/Core/ParameterList.cpp +++ b/src/Nazara/Core/ParameterList.cpp @@ -2,11 +2,9 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp -// Notre utilisation du placement new n'est pas (encore ?) compatible avec les définitions du MLT -#define NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION - #include #include +#include #include #include #include @@ -309,7 +307,7 @@ void NzParameterList::SetParameter(const NzString& name, const NzString& value) parameter.type = nzParameterType_String; - new (¶meter.value.stringVal) NzString(value); + NzPlacementNew(¶meter.value.stringVal, value); } void NzParameterList::SetParameter(const NzString& name, const char* value) @@ -322,7 +320,7 @@ void NzParameterList::SetParameter(const NzString& name, const char* value) parameter.type = nzParameterType_String; - new (¶meter.value.stringVal) NzString(value); + NzPlacementNew(¶meter.value.stringVal, value); } void NzParameterList::SetParameter(const NzString& name, void* value) @@ -405,7 +403,7 @@ NzParameterList& NzParameterList::operator=(const NzParameterList& list) case nzParameterType_String: parameter.type = nzParameterType_String; - new (¶meter.value.stringVal) NzString(it->second.value.stringVal); + NzPlacementNew(¶meter.value.stringVal, it->second.value.stringVal); break; case nzParameterType_Userdata: diff --git a/src/Nazara/Lua/LuaInstance.cpp b/src/Nazara/Lua/LuaInstance.cpp index 2db6aeb80..f6436138b 100644 --- a/src/Nazara/Lua/LuaInstance.cpp +++ b/src/Nazara/Lua/LuaInstance.cpp @@ -2,8 +2,6 @@ // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp -#define NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION - #include #include #include @@ -11,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -621,7 +620,7 @@ void NzLuaInstance::PushCFunction(NzLuaCFunction func, int upvalueCount) void NzLuaInstance::PushFunction(NzLuaFunction func) { NzLuaFunction* luaFunc = reinterpret_cast(lua_newuserdata(m_state, sizeof(NzLuaFunction))); - new (luaFunc) NzLuaFunction(std::move(func)); + NzPlacementNew(luaFunc, std::move(func)); lua_pushcclosure(m_state, ProxyFunc, 1); } From 221e2583acd956170236aca0c01b565b9e80f0c7 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 23 Jul 2014 10:21:49 +0200 Subject: [PATCH 004/233] Removed useless file Former-commit-id: 162cc21adea7dbdf6604ed8d8b25485ec1442d90 --- include/Nazara/Graphics.hpp | 1 - include/Nazara/Graphics/ScreenNode.hpp | 52 -------------------------- 2 files changed, 53 deletions(-) delete mode 100644 include/Nazara/Graphics/ScreenNode.hpp diff --git a/include/Nazara/Graphics.hpp b/include/Nazara/Graphics.hpp index 689572165..4d0787084 100644 --- a/include/Nazara/Graphics.hpp +++ b/include/Nazara/Graphics.hpp @@ -61,7 +61,6 @@ #include #include #include -#include #include #include #include diff --git a/include/Nazara/Graphics/ScreenNode.hpp b/include/Nazara/Graphics/ScreenNode.hpp deleted file mode 100644 index 214362b1b..000000000 --- a/include/Nazara/Graphics/ScreenNode.hpp +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (C) 2014 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_SCENENODE_HPP -#define NAZARA_SCENENODE_HPP - -#include -#include -#include -#include -#include -#include - -class NAZARA_API NzSceneNode : public NzNode -{ - friend class NzScene; - - public: - NzSceneNode(); - NzSceneNode(const NzSceneNode& node); - virtual ~NzSceneNode(); - - virtual void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const = 0; - - virtual const NzBoundingVolumef& GetBoundingVolume() const = 0; - nzNodeType GetNodeType() const final; - NzScene* GetScene() const; - virtual nzSceneNodeType GetSceneNodeType() const = 0; - - bool IsVisible() const; - - protected: - virtual void OnParenting(const NzNode* parent) override; - virtual void OnVisibilityChange(bool visibility); - void RecursiveSetScene(NzScene* scene, NzNode* node); - virtual void Register(); - void SetScene(NzScene* scene); - virtual void Unregister(); - virtual void Update(); - virtual bool VisibilityTest(const NzCamera* camera) = 0; - - NzScene* m_scene; - bool m_visible; - - private: - void UpdateVisibility(const NzCamera& camera); -}; - -#endif // NAZARA_SCENENODE_HPP From 8b34e21e2f03684714e8950fb595bfa1b0267b18 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 23 Jul 2014 11:57:04 +0200 Subject: [PATCH 005/233] Improved code Fixed Directory being copyable Fixed ByteArray and String self-assignation Made it clear Clock is copyable Former-commit-id: 36702d8a389abe6d3faa1e283d9a20f0326041a6 --- include/Nazara/Core/Clock.hpp | 3 +++ include/Nazara/Core/Directory.hpp | 3 ++- src/Nazara/Core/ByteArray.cpp | 11 +++++++---- src/Nazara/Core/String.cpp | 32 ++++++++----------------------- 4 files changed, 20 insertions(+), 29 deletions(-) diff --git a/include/Nazara/Core/Clock.hpp b/include/Nazara/Core/Clock.hpp index b510137b7..ba39018fb 100644 --- a/include/Nazara/Core/Clock.hpp +++ b/include/Nazara/Core/Clock.hpp @@ -19,6 +19,7 @@ class NAZARA_API NzClock { public: NzClock(nzUInt64 startingValue = 0, bool paused = false); + NzClock(const NzClock& clock) = default; float GetSeconds() const; nzUInt64 GetMicroseconds() const; @@ -30,6 +31,8 @@ class NAZARA_API NzClock void Restart(); void Unpause(); + NzClock& operator=(const NzClock& clock) = default; + private: NazaraMutexAttrib(m_mutex, mutable) diff --git a/include/Nazara/Core/Directory.hpp b/include/Nazara/Core/Directory.hpp index 1a7ae5905..393914473 100644 --- a/include/Nazara/Core/Directory.hpp +++ b/include/Nazara/Core/Directory.hpp @@ -8,6 +8,7 @@ #define NAZARA_DIRECTORY_HPP #include +#include #include #if defined(NAZARA_PLATFORM_WINDOWS) @@ -27,7 +28,7 @@ class NzDirectoryImpl; -class NAZARA_API NzDirectory +class NAZARA_API NzDirectory : NzNonCopyable { public: NzDirectory(); diff --git a/src/Nazara/Core/ByteArray.cpp b/src/Nazara/Core/ByteArray.cpp index 94903dd4d..4636b826e 100644 --- a/src/Nazara/Core/ByteArray.cpp +++ b/src/Nazara/Core/ByteArray.cpp @@ -404,11 +404,14 @@ nzUInt8 NzByteArray::operator[](unsigned int pos) const NzByteArray& NzByteArray::operator=(const NzByteArray& array) { - ReleaseArray(); + if (this != &array) + { + ReleaseArray(); - m_sharedArray = array.m_sharedArray; - if (m_sharedArray != &emptyArray) - m_sharedArray->refCount++; + m_sharedArray = array.m_sharedArray; + if (m_sharedArray != &emptyArray) + m_sharedArray->refCount++; + } return *this; } diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index 54e5b3eb7..cac71d221 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -2785,35 +2785,19 @@ NzString& NzString::Set(const char* string, unsigned int length) NzString& NzString::Set(const std::string& string) { - if (string.size() > 0) - { - if (m_sharedString->capacity >= string.size()) - EnsureOwnership(true); - else - { - ReleaseString(); - - m_sharedString = new SharedString; - m_sharedString->capacity = string.size(); - m_sharedString->string = new char[string.size()+1]; - } - - m_sharedString->size = string.size(); - std::memcpy(m_sharedString->string, string.c_str(), string.size()+1); - } - else - ReleaseString(); - - return *this; + return Set(string.data(), string.size()); } NzString& NzString::Set(const NzString& string) { - ReleaseString(); + if (this != &string) + { + ReleaseString(); - m_sharedString = string.m_sharedString; - if (m_sharedString != &emptyString) - m_sharedString->refCount++; + m_sharedString = string.m_sharedString; + if (m_sharedString != &emptyString) + m_sharedString->refCount++; + } return *this; } From bd0f38092eecdf8824a8c323811246ae7e75037d Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 24 Jul 2014 09:45:42 +0200 Subject: [PATCH 006/233] Updated PhongLighting shader I can't remember why I commented these lines. Former-commit-id: 3da37915073f94c9c44adfd84c968cb2d70982cf --- .../Resources/Shaders/PhongLighting/compatibility.vert | 4 ++-- .../Shaders/PhongLighting/compatibility.vert.h | 2 +- .../Graphics/Resources/Shaders/PhongLighting/core.vert | 10 +++++----- .../Resources/Shaders/PhongLighting/core.vert.h | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.vert b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.vert index 37fafc556..8ef9700b3 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.vert +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.vert @@ -61,9 +61,9 @@ void main() #endif #if TEXTURE_MAPPING -/* #if FLAG_FLIP_UVS + #if FLAG_FLIP_UVS vTexCoord = vec2(VertexTexCoord.x, 1.0 - VertexTexCoord.y); - #else*/ + #else vTexCoord = VertexTexCoord; #endif #endif diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.vert.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.vert.h index 8437da5c7..48cbdb6e4 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.vert.h +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.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,118,97,114,121,105,110,103,32,109,97,116,52,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,86,101,114,116,101,120,78,111,114,109,97,108,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,86,101,114,116,101,120,84,97,110,103,101,110,116,59,13,10,118,97,114,121,105,110,103,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,118,97,114,121,105,110,103,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,118,78,111,114,109,97,108,59,13,10,118,97,114,121,105,110,103,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,118,97,114,121,105,110,103,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,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,73,78,83,84,65,78,67,73,78,71,13,10,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,35,101,108,115,101,13,10,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,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,35,101,108,115,101,13,10,9,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,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,13,10,35,101,108,115,101,13,10,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,35,101,108,115,101,13,10,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,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,35,101,108,115,101,13,10,9,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,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,13,10,35,101,110,100,105,102,13,10,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,91,48,93,46,120,121,122,44,32,73,110,115,116,97,110,99,101,68,97,116,97,48,91,49,93,46,120,121,122,44,32,73,110,115,116,97,110,99,101,68,97,116,97,48,91,50,93,46,120,121,122,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,91,48,93,46,120,121,122,44,32,87,111,114,108,100,77,97,116,114,105,120,91,49,93,46,120,121,122,44,32,87,111,114,108,100,77,97,116,114,105,120,91,50,93,46,120,121,122,41,59,13,10,9,35,101,110,100,105,102,13,10,9,13,10,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,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,47,42,9,35,105,102,32,70,76,65,71,95,70,76,73,80,95,85,86,83,13,10,9,118,84,101,120,67,111,111,114,100,32,61,32,118,101,99,50,40,86,101,114,116,101,120,84,101,120,67,111,111,114,100,46,120,44,32,49,46,48,32,45,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,46,121,41,59,13,10,9,35,101,108,115,101,42,47,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,9,35,101,110,100,105,102,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,118,97,114,121,105,110,103,32,109,97,116,52,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,86,101,114,116,101,120,78,111,114,109,97,108,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,86,101,114,116,101,120,84,97,110,103,101,110,116,59,13,10,118,97,114,121,105,110,103,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,118,97,114,121,105,110,103,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,118,78,111,114,109,97,108,59,13,10,118,97,114,121,105,110,103,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,118,97,114,121,105,110,103,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,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,73,78,83,84,65,78,67,73,78,71,13,10,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,35,101,108,115,101,13,10,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,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,35,101,108,115,101,13,10,9,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,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,13,10,35,101,108,115,101,13,10,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,35,101,108,115,101,13,10,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,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,35,101,108,115,101,13,10,9,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,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,13,10,35,101,110,100,105,102,13,10,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,91,48,93,46,120,121,122,44,32,73,110,115,116,97,110,99,101,68,97,116,97,48,91,49,93,46,120,121,122,44,32,73,110,115,116,97,110,99,101,68,97,116,97,48,91,50,93,46,120,121,122,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,91,48,93,46,120,121,122,44,32,87,111,114,108,100,77,97,116,114,105,120,91,49,93,46,120,121,122,44,32,87,111,114,108,100,77,97,116,114,105,120,91,50,93,46,120,121,122,41,59,13,10,9,35,101,110,100,105,102,13,10,9,13,10,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,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,35,105,102,32,70,76,65,71,95,70,76,73,80,95,85,86,83,13,10,9,118,84,101,120,67,111,111,114,100,32,61,32,118,101,99,50,40,86,101,114,116,101,120,84,101,120,67,111,111,114,100,46,120,44,32,49,46,48,32,45,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,46,121,41,59,13,10,9,35,101,108,115,101,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,9,35,101,110,100,105,102,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 diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert index ca9c5c3eb..09430bb06 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert @@ -44,7 +44,7 @@ void main() #endif #endif -//#if LIGHTING +#if LIGHTING #if FLAG_INSTANCING mat3 rotationMatrix = mat3(InstanceData0); #else @@ -59,14 +59,14 @@ void main() #else vNormal = normalize(rotationMatrix * VertexNormal); #endif -//#endif +#endif #if TEXTURE_MAPPING -/* #if FLAG_FLIP_UVS + #if FLAG_FLIP_UVS vTexCoord = vec2(VertexTexCoord.x, 1.0 - VertexTexCoord.y); - #else*/ + #else vTexCoord = VertexTexCoord; -// #endif + #endif #endif #if LIGHTING && PARALLAX_MAPPING diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert.h index dddde34f9..c920136a2 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,105,110,32,109,97,116,52,32,73,110,115,116,97,110,99,101,68,97,116,97,48,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,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,73,78,83,84,65,78,67,73,78,71,13,10,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,35,101,108,115,101,13,10,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,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,35,101,108,115,101,13,10,9,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,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,13,10,35,101,108,115,101,13,10,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,35,101,108,115,101,13,10,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,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,35,101,108,115,101,13,10,9,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,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,13,10,35,101,110,100,105,102,13,10,13,10,47,47,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,47,47,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,47,42,9,35,105,102,32,70,76,65,71,95,70,76,73,80,95,85,86,83,13,10,9,118,84,101,120,67,111,111,114,100,32,61,32,118,101,99,50,40,86,101,114,116,101,120,84,101,120,67,111,111,114,100,46,120,44,32,49,46,48,32,45,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,46,121,41,59,13,10,9,35,101,108,115,101,42,47,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,47,47,9,35,101,110,100,105,102,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,105,110,32,109,97,116,52,32,73,110,115,116,97,110,99,101,68,97,116,97,48,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,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,73,78,83,84,65,78,67,73,78,71,13,10,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,35,101,108,115,101,13,10,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,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,35,101,108,115,101,13,10,9,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,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,13,10,35,101,108,115,101,13,10,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,35,101,108,115,101,13,10,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,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,35,101,108,115,101,13,10,9,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,35,101,110,100,105,102,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,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,35,105,102,32,70,76,65,71,95,70,76,73,80,95,85,86,83,13,10,9,118,84,101,120,67,111,111,114,100,32,61,32,118,101,99,50,40,86,101,114,116,101,120,84,101,120,67,111,111,114,100,46,120,44,32,49,46,48,32,45,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,46,121,41,59,13,10,9,35,101,108,115,101,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,9,35,101,110,100,105,102,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 4a1d7bc5037aafb9d2d96f6e70d4a17e67100687 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 24 Jul 2014 10:33:26 +0200 Subject: [PATCH 007/233] Improved some code (smart pointers) Former-commit-id: 67729603eb41ce06c9b3857311146b7cd6faa4e9 --- src/Nazara/Audio/Music.cpp | 6 +++--- src/Nazara/Audio/SoundBuffer.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Nazara/Audio/Music.cpp b/src/Nazara/Audio/Music.cpp index 16dfc64ec..f6704bf4d 100644 --- a/src/Nazara/Audio/Music.cpp +++ b/src/Nazara/Audio/Music.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -18,8 +19,8 @@ bool NzMusicParams::IsValid() const struct NzMusicImpl { ALenum audioFormat; + std::unique_ptr stream; std::vector chunkSamples; - NzSoundStream* stream; NzThread thread; bool loop = false; bool paused = false; @@ -50,7 +51,7 @@ bool NzMusic::Create(NzSoundStream* soundStream) m_impl->sampleRate = soundStream->GetSampleRate(); m_impl->audioFormat = NzOpenAL::AudioFormat[format]; m_impl->chunkSamples.resize(format * m_impl->sampleRate); // Une seconde de samples - m_impl->stream = soundStream; + m_impl->stream.reset(soundStream); return true; } @@ -61,7 +62,6 @@ void NzMusic::Destroy() { Stop(); - delete m_impl->stream; delete m_impl; m_impl = nullptr; } diff --git a/src/Nazara/Audio/SoundBuffer.cpp b/src/Nazara/Audio/SoundBuffer.cpp index 7cd831313..7d6dcfe41 100644 --- a/src/Nazara/Audio/SoundBuffer.cpp +++ b/src/Nazara/Audio/SoundBuffer.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -23,7 +24,7 @@ struct NzSoundBufferImpl ALuint buffer; nzAudioFormat format; nzUInt32 duration; - nzInt16* samples; + std::unique_ptr samples; unsigned int sampleCount; unsigned int sampleRate; }; @@ -104,7 +105,7 @@ bool NzSoundBuffer::Create(nzAudioFormat format, unsigned int sampleCount, unsig m_impl->format = format; m_impl->sampleCount = sampleCount; m_impl->sampleRate = sampleRate; - m_impl->samples = new nzInt16[sampleCount]; + m_impl->samples.reset(new nzInt16[sampleCount]); std::memcpy(&m_impl->samples[0], samples, sampleCount*sizeof(nzInt16)); NotifyCreated(); @@ -117,7 +118,6 @@ void NzSoundBuffer::Destroy() { NotifyDestroy(); - delete[] m_impl->samples; delete m_impl; m_impl = nullptr; } @@ -159,7 +159,7 @@ const nzInt16* NzSoundBuffer::GetSamples() const } #endif - return m_impl->samples; + return m_impl->samples.get(); } unsigned int NzSoundBuffer::GetSampleCount() const From 35c0bc7087f996ed115b997befbab37b230ddc3b Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 28 Jul 2014 12:20:47 +0200 Subject: [PATCH 008/233] Used std::forward for PlacementNew function Former-commit-id: e77b64bb90d849d856d93426a68b4d76cb499971 --- include/Nazara/Core/MemoryHelper.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Core/MemoryHelper.inl b/include/Nazara/Core/MemoryHelper.inl index 0e27c5462..841f5d4c5 100644 --- a/include/Nazara/Core/MemoryHelper.inl +++ b/include/Nazara/Core/MemoryHelper.inl @@ -34,7 +34,7 @@ inline void* NzOperatorNew(std::size_t size) template T* NzPlacementNew(void* ptr, Args... args) { - return new (ptr) T(args...); + return new (ptr) T(std::forward(args)...); } #include From dc146fdf61ac421ff87505b39b11764254470986 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 28 Jul 2014 12:21:05 +0200 Subject: [PATCH 009/233] Removed useless forward-declaration Former-commit-id: b68020d18b9f4b62b8f060574a46433af56a599e --- include/Nazara/Audio/Music.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/include/Nazara/Audio/Music.hpp b/include/Nazara/Audio/Music.hpp index e16592583..bff875cb5 100644 --- a/include/Nazara/Audio/Music.hpp +++ b/include/Nazara/Audio/Music.hpp @@ -21,7 +21,6 @@ struct NzMusicParams class NzMusic; class NzSoundStream; -class NzThread; using NzMusicLoader = NzResourceLoader; From 4a0dbcb338d12269106a4a7861aebaef10239d8f Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 28 Jul 2014 12:24:57 +0200 Subject: [PATCH 010/233] Updated Basic.inl Fixed StringToNumber not working with lowercase numbers Moved functions order to be alphabetical Former-commit-id: ff58d17afe38c39527a6ae898bfeb7f3282b2142 --- include/Nazara/Math/Basic.hpp | 4 +- include/Nazara/Math/Basic.inl | 85 ++++++++++++++++++----------------- 2 files changed, 45 insertions(+), 44 deletions(-) diff --git a/include/Nazara/Math/Basic.hpp b/include/Nazara/Math/Basic.hpp index c100da41c..a7c90e5a0 100644 --- a/include/Nazara/Math/Basic.hpp +++ b/include/Nazara/Math/Basic.hpp @@ -24,8 +24,6 @@ template T NzApproach(T value, T objective, T increment); template constexpr T NzClamp(T value, T min, T max); template constexpr T NzDegrees(T degrees); template constexpr T NzDegreeToRadian(T degrees); -template T NzMultiplyAdd(T x, T y, T z); -unsigned int NzIntegralPow(unsigned int base, unsigned int exponent); unsigned int NzGetNearestPowerOfTwo(unsigned int number); unsigned int NzGetNumberLength(signed char number); unsigned int NzGetNumberLength(unsigned char number); @@ -36,7 +34,9 @@ unsigned int NzGetNumberLength(unsigned long long number); unsigned int NzGetNumberLength(float number, nzUInt8 precision = NAZARA_CORE_DECIMAL_DIGITS); unsigned int NzGetNumberLength(double number, nzUInt8 precision = NAZARA_CORE_DECIMAL_DIGITS); unsigned int NzGetNumberLength(long double number, nzUInt8 precision = NAZARA_CORE_DECIMAL_DIGITS); +unsigned int NzIntegralPow(unsigned int base, unsigned int exponent); template T NzLerp(T from, T to, T2 interpolation); +template T NzMultiplyAdd(T x, T y, T z); template T NzNormalizeAngle(T angle); template bool NzNumberEquals(T a, T b, T maxDifference = std::numeric_limits::epsilon()); NzString NzNumberToString(long long number, nzUInt8 radix = 10); diff --git a/include/Nazara/Math/Basic.inl b/include/Nazara/Math/Basic.inl index a90c291d8..6fc2f7506 100644 --- a/include/Nazara/Math/Basic.inl +++ b/include/Nazara/Math/Basic.inl @@ -46,46 +46,6 @@ constexpr T NzDegreeToRadian(T degrees) return degrees * F(M_PI/180.0); } -template -T NzMultiplyAdd(T x, T y, T z) -{ - return x*y + z; -} - -#ifdef FP_FAST_FMAF -template<> -inline float NzMultiplyAdd(float x, float y, float z) -{ - return std::fmaf(x, y, z); -} -#endif - -#ifdef FP_FAST_FMA -template<> -inline double NzMultiplyAdd(double x, double y, double z) -{ - return std::fma(x, y, z); -} -#endif - -#ifdef FP_FAST_FMAL -template<> -inline long double NzMultiplyAdd(long double x, long double y, long double z) -{ - return std::fmal(x, y, z); -} -#endif - -inline unsigned int NzIntegralPow(unsigned int base, unsigned int exponent) -{ - ///TODO: Marquer comme constexpr en C++14 - unsigned int r = 1; - for (unsigned int i = 0; i < exponent; ++i) - r *= base; - - return r; -} - inline unsigned int NzGetNearestPowerOfTwo(unsigned int number) { ///TODO: Marquer comme constexpr en C++14 @@ -181,6 +141,16 @@ inline unsigned int NzGetNumberLength(long double number, nzUInt8 precision) return NzGetNumberLength(static_cast(number)) + precision + 1; // Plus un pour le point } +inline unsigned int NzIntegralPow(unsigned int base, unsigned int exponent) +{ + ///TODO: Marquer comme constexpr en C++14 + unsigned int r = 1; + for (unsigned int i = 0; i < exponent; ++i) + r *= base; + + return r; +} + template T NzLerp(T from, T to, T2 interpolation) { @@ -192,6 +162,36 @@ T NzLerp(T from, T to, T2 interpolation) return from + interpolation*(to - from); } +template +T NzMultiplyAdd(T x, T y, T z) +{ + return x*y + z; +} + +#ifdef FP_FAST_FMAF +template<> +inline float NzMultiplyAdd(float x, float y, float z) +{ + return std::fmaf(x, y, z); +} +#endif + +#ifdef FP_FAST_FMA +template<> +inline double NzMultiplyAdd(double x, double y, double z) +{ + return std::fma(x, y, z); +} +#endif + +#ifdef FP_FAST_FMAL +template<> +inline long double NzMultiplyAdd(long double x, long double y, long double z) +{ + return std::fmal(x, y, z); +} +#endif + template T NzNormalizeAngle(T angle) { @@ -298,12 +298,13 @@ inline long long NzStringToNumber(NzString str, nzUInt8 radix, bool* ok) } #endif + static const char* symbols = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + str.Simplify(); if (radix > 10) - str.ToUpper(); + str = str.ToUpper(); bool negative = str.StartsWith('-'); - static const char* symbols = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; char* digit = &str[(negative) ? 1 : 0]; unsigned long long total = 0; From 095a44e9b15aed61f458ff37d3fcec465bad8b70 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 28 Jul 2014 12:25:59 +0200 Subject: [PATCH 011/233] Improved MD5 loaders code Fixed missing return Former-commit-id: b5fb298ab8b147bbfda07ffb2090d248156b96c7 --- src/Nazara/Utility/Loaders/MD5Anim/Loader.cpp | 9 ++++++++- src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp | 4 +++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Nazara/Utility/Loaders/MD5Anim/Loader.cpp b/src/Nazara/Utility/Loaders/MD5Anim/Loader.cpp index 6558029d1..7035c3de8 100644 --- a/src/Nazara/Utility/Loaders/MD5Anim/Loader.cpp +++ b/src/Nazara/Utility/Loaders/MD5Anim/Loader.cpp @@ -15,12 +15,15 @@ namespace nzTernary Check(NzInputStream& stream, const NzAnimationParams& parameters) { + NazaraUnused(parameters); + NzMD5AnimParser parser(stream); return parser.Check(); } bool Load(NzAnimation* animation, NzInputStream& stream, const NzAnimationParams& parameters) { + ///TODO: Utiliser les paramètres NzMD5AnimParser parser(stream); if (!parser.Parse()) @@ -49,7 +52,9 @@ namespace NzSequenceJoint* sequenceJoints = animation->GetSequenceJoints(); // Pour que le squelette soit correctement aligné, il faut appliquer un quaternion "de correction" aux joints à la base du squelette - NzQuaternionf rotationQuat = NzEulerAnglesf(-90.f, 90.f, 0.f); + NzQuaternionf rotationQuat = NzQuaternionf::RotationBetween(NzVector3f::UnitX(), NzVector3f::Forward()) * + NzQuaternionf::RotationBetween(NzVector3f::UnitZ(), NzVector3f::Up()); + for (unsigned int i = 0; i < jointCount; ++i) { int parent = joints[i].parent; @@ -71,6 +76,8 @@ namespace sequenceJoint.scale.Set(1.f); } } + + return true; } } diff --git a/src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp b/src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp index ae3e22977..8b0a88802 100644 --- a/src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp +++ b/src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp @@ -36,7 +36,9 @@ namespace } // Pour que le squelette soit correctement aligné, il faut appliquer un quaternion "de correction" aux joints à la base du squelette - NzQuaternionf rotationQuat = NzEulerAnglesf(-90.f, 180.f, 0.f); + NzQuaternionf rotationQuat = NzQuaternionf::RotationBetween(NzVector3f::UnitX(), NzVector3f::Forward()) * + NzQuaternionf::RotationBetween(NzVector3f::UnitZ(), NzVector3f::Up()); + NzString baseDir = stream.GetDirectory(); // Le hellknight de Doom 3 fait ~120 unités, et il est dit qu'il fait trois mètres From 90a616a26f57902bf9985441b4fecbb1e03e4db8 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 28 Jul 2014 12:26:37 +0200 Subject: [PATCH 012/233] Made code more readable (Weeeee) Former-commit-id: fa2a7686130fe67aa4da9f590a8f74c1b5e75ca9 --- include/Nazara/Math/BoundingVolume.inl | 1 + 1 file changed, 1 insertion(+) diff --git a/include/Nazara/Math/BoundingVolume.inl b/include/Nazara/Math/BoundingVolume.inl index ed84258a1..32378d9e4 100644 --- a/include/Nazara/Math/BoundingVolume.inl +++ b/include/Nazara/Math/BoundingVolume.inl @@ -175,6 +175,7 @@ template void NzBoundingVolume::Update(const NzMatrix4& transformMatrix) { obb.Update(transformMatrix); + aabb.Set(obb(0), obb(1)); for (unsigned int i = 2; i < 8; ++i) aabb.ExtendTo(obb(i)); From 60d5c09c189833efc1dd4124671285eb12e08802 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 28 Jul 2014 15:18:39 +0200 Subject: [PATCH 013/233] Renamed Basic.hpp to Algorithm.hpp Former-commit-id: ba2858d26fb55069313fafc3e4464dc2e9224b7d --- include/Nazara/Math/{Basic.hpp => Algorithm.hpp} | 8 ++++---- include/Nazara/Math/{Basic.inl => Algorithm.inl} | 6 +++--- include/Nazara/Math/BoundingVolume.inl | 2 +- include/Nazara/Math/Box.inl | 2 +- include/Nazara/Math/EulerAngles.inl | 2 +- include/Nazara/Math/Frustum.inl | 2 +- include/Nazara/Math/Matrix4.inl | 5 +---- include/Nazara/Math/OrientedBox.inl | 2 +- include/Nazara/Math/Plane.inl | 2 +- include/Nazara/Math/Quaternion.inl | 2 +- include/Nazara/Math/Rect.inl | 2 +- include/Nazara/Math/Sphere.inl | 2 +- include/Nazara/Math/Vector2.inl | 2 +- include/Nazara/Math/Vector3.inl | 2 +- include/Nazara/Math/Vector4.inl | 2 +- src/Nazara/Core/ByteArray.cpp | 2 +- src/Nazara/Core/Log.cpp | 1 - src/Nazara/Core/String.cpp | 2 +- src/Nazara/Graphics/Light.cpp | 2 +- src/Nazara/Noise/Abstract2DNoise.cpp | 1 - src/Nazara/Noise/Abstract3DNoise.cpp | 1 - src/Nazara/Noise/Abstract4DNoise.cpp | 1 - src/Nazara/Noise/MappedNoiseBase.cpp | 2 +- src/Nazara/Renderer/OpenGL.cpp | 2 +- src/Nazara/Utility/Algorithm.cpp | 7 +++---- src/Nazara/Utility/Loaders/MD2/Loader.cpp | 2 +- src/Nazara/Utility/Loaders/MD5Anim/Parser.cpp | 2 +- src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp | 2 +- src/Nazara/Utility/Mesh.cpp | 2 +- 29 files changed, 32 insertions(+), 40 deletions(-) rename include/Nazara/Math/{Basic.hpp => Algorithm.hpp} (93%) rename include/Nazara/Math/{Basic.inl => Algorithm.inl} (99%) diff --git a/include/Nazara/Math/Basic.hpp b/include/Nazara/Math/Algorithm.hpp similarity index 93% rename from include/Nazara/Math/Basic.hpp rename to include/Nazara/Math/Algorithm.hpp index a7c90e5a0..46d11645f 100644 --- a/include/Nazara/Math/Basic.hpp +++ b/include/Nazara/Math/Algorithm.hpp @@ -4,8 +4,8 @@ #pragma once -#ifndef NAZARA_BASIC_HPP -#define NAZARA_BASIC_HPP +#ifndef NAZARA_ALGORITHM_MATH_HPP +#define NAZARA_ALGORITHM_MATH_HPP #include #include @@ -44,6 +44,6 @@ template T NzRadians(T radians); template T NzRadianToDegree(T radians); long long NzStringToNumber(NzString str, nzUInt8 radix = 10, bool* ok = nullptr); -#include +#include -#endif // NAZARA_BASIC_HPP +#endif // NAZARA_ALGORITHM_MATH_HPP diff --git a/include/Nazara/Math/Basic.inl b/include/Nazara/Math/Algorithm.inl similarity index 99% rename from include/Nazara/Math/Basic.inl rename to include/Nazara/Math/Algorithm.inl index 6fc2f7506..7f6884da8 100644 --- a/include/Nazara/Math/Basic.inl +++ b/include/Nazara/Math/Algorithm.inl @@ -125,19 +125,19 @@ inline unsigned int NzGetNumberLength(unsigned long long number) inline unsigned int NzGetNumberLength(float number, nzUInt8 precision) { - // L'imprécision des flottants nécessite un cast (log10(9.99999) = 1) + // L'imprécision des flottants nécessite un cast (log10(9.99999) = 0.99999) return NzGetNumberLength(static_cast(number)) + precision + 1; // Plus un pour le point } inline unsigned int NzGetNumberLength(double number, nzUInt8 precision) { - // L'imprécision des flottants nécessite un cast (log10(9.99999) = 1) + // L'imprécision des flottants nécessite un cast (log10(9.99999) = 0.99999) return NzGetNumberLength(static_cast(number)) + precision + 1; // Plus un pour le point } inline unsigned int NzGetNumberLength(long double number, nzUInt8 precision) { - // L'imprécision des flottants nécessite un cast (log10(9.99999) = 1) + // L'imprécision des flottants nécessite un cast (log10(9.99999) = 0.99999) return NzGetNumberLength(static_cast(number)) + precision + 1; // Plus un pour le point } diff --git a/include/Nazara/Math/BoundingVolume.inl b/include/Nazara/Math/BoundingVolume.inl index 32378d9e4..71c0c2cea 100644 --- a/include/Nazara/Math/BoundingVolume.inl +++ b/include/Nazara/Math/BoundingVolume.inl @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/Nazara/Math/Box.inl b/include/Nazara/Math/Box.inl index e8f9b8fed..744d513ab 100644 --- a/include/Nazara/Math/Box.inl +++ b/include/Nazara/Math/Box.inl @@ -3,7 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include +#include #include #include #include diff --git a/include/Nazara/Math/EulerAngles.inl b/include/Nazara/Math/EulerAngles.inl index af9f8e521..d92821189 100644 --- a/include/Nazara/Math/EulerAngles.inl +++ b/include/Nazara/Math/EulerAngles.inl @@ -3,7 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include +#include #include #include #include diff --git a/include/Nazara/Math/Frustum.inl b/include/Nazara/Math/Frustum.inl index 8541a34f1..0a7b02215 100644 --- a/include/Nazara/Math/Frustum.inl +++ b/include/Nazara/Math/Frustum.inl @@ -7,7 +7,7 @@ // http://www.lighthouse3d.com/tutorials/view-frustum-culling/ #include -#include +#include #include #include diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index 989302bd1..7caa3cb04 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include #include @@ -640,8 +640,6 @@ NzMatrix4& NzMatrix4::MakeTransform(const NzVector3& translation, const m34 = F(0.0); m44 = F(1.0); - // Pas besoin de mettre à jour l'identité (Déjà fait par Set*) - return *this; } @@ -818,7 +816,6 @@ NzVector4 NzMatrix4::Transform(const NzVector4& vector) const template NzMatrix4& NzMatrix4::Transpose() { - // N'affecte pas l'identité (La transposée d'une matrice identité est la matrice identité elle-même) std::swap(m12, m21); std::swap(m13, m31); std::swap(m14, m41); diff --git a/include/Nazara/Math/OrientedBox.inl b/include/Nazara/Math/OrientedBox.inl index 33a131c72..992698bad 100644 --- a/include/Nazara/Math/OrientedBox.inl +++ b/include/Nazara/Math/OrientedBox.inl @@ -3,7 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include +#include #include #include diff --git a/include/Nazara/Math/Plane.inl b/include/Nazara/Math/Plane.inl index 4e7c81029..b87464bc7 100644 --- a/include/Nazara/Math/Plane.inl +++ b/include/Nazara/Math/Plane.inl @@ -3,7 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include +#include #include #include diff --git a/include/Nazara/Math/Quaternion.inl b/include/Nazara/Math/Quaternion.inl index 3e27982f6..76290c0c7 100644 --- a/include/Nazara/Math/Quaternion.inl +++ b/include/Nazara/Math/Quaternion.inl @@ -3,7 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include +#include #include #include #include diff --git a/include/Nazara/Math/Rect.inl b/include/Nazara/Math/Rect.inl index ab35b30c5..611403706 100644 --- a/include/Nazara/Math/Rect.inl +++ b/include/Nazara/Math/Rect.inl @@ -3,7 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include +#include #include #include #include diff --git a/include/Nazara/Math/Sphere.inl b/include/Nazara/Math/Sphere.inl index b9a97eb43..c85f12000 100644 --- a/include/Nazara/Math/Sphere.inl +++ b/include/Nazara/Math/Sphere.inl @@ -3,7 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include +#include #include #include #include diff --git a/include/Nazara/Math/Vector2.inl b/include/Nazara/Math/Vector2.inl index b457f0ad0..7bfe930e0 100644 --- a/include/Nazara/Math/Vector2.inl +++ b/include/Nazara/Math/Vector2.inl @@ -3,7 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include +#include #include #include #include diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index 2ca0c5051..15ad4c95e 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -3,7 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include +#include #include #include #include diff --git a/include/Nazara/Math/Vector4.inl b/include/Nazara/Math/Vector4.inl index 77229fd5c..2f6002fbc 100644 --- a/include/Nazara/Math/Vector4.inl +++ b/include/Nazara/Math/Vector4.inl @@ -3,7 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include +#include #include #include #include diff --git a/src/Nazara/Core/ByteArray.cpp b/src/Nazara/Core/ByteArray.cpp index 4636b826e..135a72895 100644 --- a/src/Nazara/Core/ByteArray.cpp +++ b/src/Nazara/Core/ByteArray.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/Nazara/Core/Log.cpp b/src/Nazara/Core/Log.cpp index 946548479..0726d886c 100644 --- a/src/Nazara/Core/Log.cpp +++ b/src/Nazara/Core/Log.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index cac71d221..259b59006 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/Nazara/Graphics/Light.cpp b/src/Nazara/Graphics/Light.cpp index d3ce97152..ff3d5bfdd 100644 --- a/src/Nazara/Graphics/Light.cpp +++ b/src/Nazara/Graphics/Light.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/Nazara/Noise/Abstract2DNoise.cpp b/src/Nazara/Noise/Abstract2DNoise.cpp index c8cef53f0..86ab9243b 100644 --- a/src/Nazara/Noise/Abstract2DNoise.cpp +++ b/src/Nazara/Noise/Abstract2DNoise.cpp @@ -3,7 +3,6 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include #include #include #include diff --git a/src/Nazara/Noise/Abstract3DNoise.cpp b/src/Nazara/Noise/Abstract3DNoise.cpp index 9a386160c..48a9c5ec9 100644 --- a/src/Nazara/Noise/Abstract3DNoise.cpp +++ b/src/Nazara/Noise/Abstract3DNoise.cpp @@ -3,7 +3,6 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include #include #include #include diff --git a/src/Nazara/Noise/Abstract4DNoise.cpp b/src/Nazara/Noise/Abstract4DNoise.cpp index 5e9afe9ff..e8ca084e3 100644 --- a/src/Nazara/Noise/Abstract4DNoise.cpp +++ b/src/Nazara/Noise/Abstract4DNoise.cpp @@ -3,7 +3,6 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include #include #include #include diff --git a/src/Nazara/Noise/MappedNoiseBase.cpp b/src/Nazara/Noise/MappedNoiseBase.cpp index 2200fdb8f..cb5a2717f 100644 --- a/src/Nazara/Noise/MappedNoiseBase.cpp +++ b/src/Nazara/Noise/MappedNoiseBase.cpp @@ -3,8 +3,8 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include #include +#include #include #include #include diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index 3d57503a6..b7d2675bd 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/Nazara/Utility/Algorithm.cpp b/src/Nazara/Utility/Algorithm.cpp index 7d7e6c939..628444000 100644 --- a/src/Nazara/Utility/Algorithm.cpp +++ b/src/Nazara/Utility/Algorithm.cpp @@ -26,7 +26,7 @@ */ #include -#include +#include #include #include #include @@ -546,15 +546,14 @@ namespace TriangleCacheData* t = &m_triangles[tri]; // calculate vertex scores - float sum = 0.0f; + float sum = 0.f; for (unsigned int i = 0; i < 3; ++i) { VertexCacheData *v = &m_vertices[t->verts[i]]; float sc = v->current_score; if (!v->calculated) - { sc = CalculateVertexScore(t->verts[i]); - } + v->current_score = sc; v->calculated = true; sum += sc; diff --git a/src/Nazara/Utility/Loaders/MD2/Loader.cpp b/src/Nazara/Utility/Loaders/MD2/Loader.cpp index 84653a8ae..693711f75 100644 --- a/src/Nazara/Utility/Loaders/MD2/Loader.cpp +++ b/src/Nazara/Utility/Loaders/MD2/Loader.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/Nazara/Utility/Loaders/MD5Anim/Parser.cpp b/src/Nazara/Utility/Loaders/MD5Anim/Parser.cpp index 4b035a5e7..2e3abc7d3 100644 --- a/src/Nazara/Utility/Loaders/MD5Anim/Parser.cpp +++ b/src/Nazara/Utility/Loaders/MD5Anim/Parser.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp b/src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp index c9747371f..4bc76d018 100644 --- a/src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp +++ b/src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index fc1c7109b..61427fa3d 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include #include From 454a5b128198784883ab7609435cfb576268ad95 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 28 Jul 2014 16:16:32 +0200 Subject: [PATCH 014/233] Added Matrix4::Get[Column|Row] Former-commit-id: 5dc655f97d8523714c69627e70b3bf8dfdcdb1ae --- include/Nazara/Math/Matrix4.hpp | 2 ++ include/Nazara/Math/Matrix4.inl | 38 +++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/include/Nazara/Math/Matrix4.hpp b/include/Nazara/Math/Matrix4.hpp index 2def3428d..90a5ae967 100644 --- a/include/Nazara/Math/Matrix4.hpp +++ b/include/Nazara/Math/Matrix4.hpp @@ -38,12 +38,14 @@ class NzMatrix4 NzMatrix4& Concatenate(const NzMatrix4& matrix); NzMatrix4& ConcatenateAffine(const NzMatrix4& matrix); + NzVector4 GetColumn(unsigned int column) const; T GetDeterminant() const; T GetDeterminantAffine() const; bool GetInverse(NzMatrix4* dest) const; bool GetInverseAffine(NzMatrix4* dest) const; NzQuaternion GetRotation() const; //NzMatrix3 GetRotationMatrix() const; + NzVector4 GetRow(unsigned int row) const; NzVector3 GetScale() const; NzVector3 GetTranslation() const; void GetTransposed(NzMatrix4* dest) const; diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index 7caa3cb04..baab59da6 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -144,6 +144,25 @@ NzMatrix4& NzMatrix4::ConcatenateAffine(const NzMatrix4& matrix) F(1.0)); } +template +NzVector4 NzMatrix4::GetColumn(unsigned int column) const +{ + ///FIXME: Est-ce une bonne idée de gérer la matrice de cette façon ? + + #if NAZARA_MATH_SAFE + if (row > 3) + { + NzStringStream ss; + ss << "Row out of range: (" << row << ") > 3"; + + throw std::out_of_range(ss.ToString()); + } + #endif + + T* ptr = (&m11) + row*4; + return NzVector4(ptr); +} + template T NzMatrix4::GetDeterminant() const { @@ -444,6 +463,25 @@ NzQuaternion NzMatrix4::GetRotation() const return quat; } +template +NzVector4 NzMatrix4::GetRow(unsigned int row) const +{ + ///FIXME: Est-ce une bonne idée de gérer la matrice de cette façon ? + + #if NAZARA_MATH_SAFE + if (column > 3) + { + NzStringStream ss; + ss << "Column out of range: (" << column << ") > 3"; + + throw std::out_of_range(ss.ToString()); + } + #endif + + T* ptr = &m11; + return NzVector4(ptr[column], ptr[column+4], ptr[column+8], ptr[column+12]); +} + template NzVector3 NzMatrix4::GetScale() const { From d9cce5d7ce1f8a37dc1d52ec7ea7dbb9c4f3e712 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 29 Jul 2014 10:30:49 +0200 Subject: [PATCH 015/233] Fixed compilation error Former-commit-id: febc503b22cedaa4edf0efe3677cf38a205d7230 --- include/Nazara/Math/Matrix4.inl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index baab59da6..a3fe4b53a 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -150,16 +150,16 @@ NzVector4 NzMatrix4::GetColumn(unsigned int column) const ///FIXME: Est-ce une bonne idée de gérer la matrice de cette façon ? #if NAZARA_MATH_SAFE - if (row > 3) + if (column > 3) { NzStringStream ss; - ss << "Row out of range: (" << row << ") > 3"; + ss << "Row out of range: (" << column << ") > 3"; throw std::out_of_range(ss.ToString()); } #endif - T* ptr = (&m11) + row*4; + T* ptr = (&m11) + column*4; return NzVector4(ptr); } @@ -469,17 +469,17 @@ NzVector4 NzMatrix4::GetRow(unsigned int row) const ///FIXME: Est-ce une bonne idée de gérer la matrice de cette façon ? #if NAZARA_MATH_SAFE - if (column > 3) + if (row > 3) { NzStringStream ss; - ss << "Column out of range: (" << column << ") > 3"; + ss << "Column out of range: (" << row << ") > 3"; throw std::out_of_range(ss.ToString()); } #endif T* ptr = &m11; - return NzVector4(ptr[column], ptr[column+4], ptr[column+8], ptr[column+12]); + return NzVector4(ptr[row], ptr[row+4], ptr[row+8], ptr[row+12]); } template From bbecdf4a92613c86f66acf87966d202c51c957d8 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 30 Jul 2014 00:40:05 +0200 Subject: [PATCH 016/233] Fixed DrawInstanced required OpenGL version Thanks to Raakz Former-commit-id: c82bf27371817fe05cce789ef84548e3cf64abab --- src/Nazara/Renderer/OpenGL.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index b7d2675bd..a34dce25b 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -1072,7 +1072,7 @@ bool NzOpenGL::Initialize() } // DrawInstanced - if (s_openglVersion >= 330) + if (s_openglVersion >= 310) { try { From 4d06ca39065663fb0e327c18ae91663386f21479 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 2 Aug 2014 21:30:19 +0200 Subject: [PATCH 017/233] Fixed OBJ Loader sometimes creating empty mesh Former-commit-id: 6b5624db279f3818edb6b4544ad0114b7c5e1e27 --- src/Nazara/Graphics/Loaders/OBJ/Loader.cpp | 6 +++++- src/Nazara/Graphics/Loaders/OBJ/OBJParser.cpp | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp b/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp index 3d939f7ea..449a82f2f 100644 --- a/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp +++ b/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp @@ -61,6 +61,8 @@ namespace for (unsigned int i = 0; i < meshCount; ++i) { unsigned int faceCount = meshes[i].faces.size(); + if (faceCount == 0) + continue; std::vector indices; indices.reserve(faceCount*3); // Pire cas si les faces sont des triangles @@ -97,6 +99,7 @@ namespace } } + // Création des buffers std::unique_ptr indexBuffer(new NzIndexBuffer(vertexCount > std::numeric_limits::max(), indices.size(), parameters.mesh.storage, nzBufferUsage_Static)); indexBuffer->SetPersistent(false); @@ -108,7 +111,7 @@ namespace for (unsigned int j = 0; j < indices.size(); ++j) indexMapper.Set(j, indices[j]); - indexMapper.Unmap(); + indexMapper.Unmap(); // Pour laisser les autres tâches affecter l'index buffer // Remplissage des vertices bool hasNormals = true; @@ -170,6 +173,7 @@ namespace if (parameters.mesh.center) subMesh->Center(); + // Ce que nous pouvons générer dépend des données à disposition (par exemple les tangentes nécessitent des coordonnées de texture) if (hasNormals && hasTexCoords) subMesh->GenerateTangents(); else if (hasTexCoords) diff --git a/src/Nazara/Graphics/Loaders/OBJ/OBJParser.cpp b/src/Nazara/Graphics/Loaders/OBJ/OBJParser.cpp index a527008f8..6a404e2c6 100644 --- a/src/Nazara/Graphics/Loaders/OBJ/OBJParser.cpp +++ b/src/Nazara/Graphics/Loaders/OBJ/OBJParser.cpp @@ -93,13 +93,15 @@ bool NzOBJParser::Parse() m_positions.clear(); m_texCoords.clear(); - // Beaucoup de meshs font plus de 100 sommets, on prépare le terrain + // Beaucoup de meshs font plus de 100 sommets, préparons le terrain m_normals.reserve(100); m_positions.reserve(100); m_texCoords.reserve(100); + // On va regrouper les meshs par nom et par matériau std::unordered_map>> meshes; + // On prépare le mesh par défaut std::vector* currentMesh = &meshes[meshName][matName]; while (Advance(false)) From 49b19cd6d1e45ed41029f6319df5e518cf5cb6a2 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 2 Aug 2014 21:30:39 +0200 Subject: [PATCH 018/233] Fixed missing error checking Former-commit-id: 45c849fd91d2072a2dc0d87394ddeb56816af2f9 --- src/Nazara/Utility/VertexBuffer.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Nazara/Utility/VertexBuffer.cpp b/src/Nazara/Utility/VertexBuffer.cpp index 594b77129..5bde1935b 100644 --- a/src/Nazara/Utility/VertexBuffer.cpp +++ b/src/Nazara/Utility/VertexBuffer.cpp @@ -50,6 +50,12 @@ bool NzVertexBuffer::Fill(const void* data, unsigned int startVertex, unsigned i bool NzVertexBuffer::FillRaw(const void* data, unsigned int offset, unsigned int size, bool forceDiscard) { #if NAZARA_UTILITY_SAFE + if (!m_buffer) + { + NazaraError("No buffer"); + return nullptr; + } + if (m_startOffset + offset + size > m_endOffset) { NazaraError("Exceeding virtual buffer size"); @@ -118,6 +124,12 @@ void* NzVertexBuffer::Map(nzBufferAccess access, unsigned int startVertex, unsig void* NzVertexBuffer::Map(nzBufferAccess access, unsigned int startVertex, unsigned int length) const { #if NAZARA_UTILITY_SAFE + if (!m_buffer) + { + NazaraError("No buffer"); + return nullptr; + } + if (!m_vertexDeclaration) { NazaraError("No vertex declaration"); From 0415f32b86fc50e8ed0712e81e5a2dd71e9552f1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 3 Aug 2014 20:57:24 +0200 Subject: [PATCH 019/233] Added some comments Former-commit-id: 42fb1dd19abec2befd7cb065f794e4b765d1411e --- include/Nazara/Utility/VertexDeclaration.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/Nazara/Utility/VertexDeclaration.hpp b/include/Nazara/Utility/VertexDeclaration.hpp index 19fb6931e..3dd5dc6c3 100644 --- a/include/Nazara/Utility/VertexDeclaration.hpp +++ b/include/Nazara/Utility/VertexDeclaration.hpp @@ -45,9 +45,9 @@ class NAZARA_API NzVertexDeclaration : public NzResource struct Component { - nzComponentType type; - bool enabled = false; - unsigned int offset; + nzComponentType type; // Le type de donnée + bool enabled = false; // Ce composant est-il activé ?/ + unsigned int offset; // La position, en octets, de la première donnée /* ** -Lynix: From 7a2a10b390e0f52f79828bd0fe22e9de29612d3d Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 3 Aug 2014 20:58:09 +0200 Subject: [PATCH 020/233] Added VertexMapper constructor Removed useless headers Former-commit-id: e8925f48eec9c52dc4f2ad7bf6a61deb755bc0ee --- include/Nazara/Utility/VertexMapper.hpp | 6 +----- include/Nazara/Utility/VertexMapper.inl | 9 +++++++-- src/Nazara/Utility/VertexMapper.cpp | 13 ++++++++++--- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/include/Nazara/Utility/VertexMapper.hpp b/include/Nazara/Utility/VertexMapper.hpp index 446d1450d..a56ec0e3c 100644 --- a/include/Nazara/Utility/VertexMapper.hpp +++ b/include/Nazara/Utility/VertexMapper.hpp @@ -9,18 +9,15 @@ #include #include -#include -#include #include #include -#include -#include class NzSubMesh; class NAZARA_API NzVertexMapper { public: + NzVertexMapper(NzVertexBuffer* vertexBuffer, unsigned int vertexCount); NzVertexMapper(NzSubMesh* subMesh); ~NzVertexMapper(); @@ -31,7 +28,6 @@ class NAZARA_API NzVertexMapper private: NzBufferMapper m_mapper; - NzVertexDeclarationConstRef m_declaration; unsigned int m_vertexCount; }; diff --git a/include/Nazara/Utility/VertexMapper.inl b/include/Nazara/Utility/VertexMapper.inl index 19bfa18c6..cd7900430 100644 --- a/include/Nazara/Utility/VertexMapper.inl +++ b/include/Nazara/Utility/VertexMapper.inl @@ -3,19 +3,24 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include template NzSparsePtr NzVertexMapper::GetComponentPtr(nzVertexComponent component) { + // On récupère la déclaration depuis le buffer + const NzVertexDeclaration* declaration = m_mapper.GetBuffer()->GetVertexDeclaration(); + + // Ensuite le composant qui nous intéresse bool enabled; nzComponentType type; unsigned int offset; - m_declaration->GetComponent(component, &enabled, &type, &offset); + declaration->GetComponent(component, &enabled, &type, &offset); if (enabled) { ///TODO: Vérifier le rapport entre le type de l'attribut et le type template ? - return NzSparsePtr(static_cast(m_mapper.GetPointer()) + offset, m_declaration->GetStride()); + return NzSparsePtr(static_cast(m_mapper.GetPointer()) + offset, declaration->GetStride()); } else { diff --git a/src/Nazara/Utility/VertexMapper.cpp b/src/Nazara/Utility/VertexMapper.cpp index 08f257f2c..6b1b1ae42 100644 --- a/src/Nazara/Utility/VertexMapper.cpp +++ b/src/Nazara/Utility/VertexMapper.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -13,7 +12,8 @@ NzVertexMapper::NzVertexMapper(NzSubMesh* subMesh) { - NzErrorFlags flags(nzErrorFlag_ThrowException); + NzErrorFlags flags(nzErrorFlag_ThrowException, true); + NzVertexBuffer* buffer = nullptr; switch (subMesh->GetAnimationType()) { @@ -37,12 +37,19 @@ NzVertexMapper::NzVertexMapper(NzSubMesh* subMesh) NazaraInternalError("Animation type not handled (0x" + NzString::Number(subMesh->GetAnimationType(), 16) + ')'); } - m_declaration = buffer->GetVertexDeclaration(); m_vertexCount = subMesh->GetVertexCount(); m_mapper.Map(buffer, nzBufferAccess_ReadWrite); } +NzVertexMapper::NzVertexMapper(NzVertexBuffer* vertexBuffer, unsigned int vertexCount) +{ + NzErrorFlags flags(nzErrorFlag_ThrowException, true); + + m_mapper.Map(vertexBuffer, nzBufferAccess_ReadWrite); + m_vertexCount = vertexCount; +} + NzVertexMapper::~NzVertexMapper() = default; unsigned int NzVertexMapper::GetVertexCount() const From ce01892482c26a62de634954659dc89454dcaa6b Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 5 Aug 2014 09:41:22 +0200 Subject: [PATCH 021/233] Fixed missing include Former-commit-id: 2adfb798af325a6c56244a3218072be74be237fb --- include/Nazara/Utility/VertexMapper.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/Nazara/Utility/VertexMapper.hpp b/include/Nazara/Utility/VertexMapper.hpp index a56ec0e3c..149e73832 100644 --- a/include/Nazara/Utility/VertexMapper.hpp +++ b/include/Nazara/Utility/VertexMapper.hpp @@ -11,6 +11,7 @@ #include #include #include +#include class NzSubMesh; From 43b4f696b2e69a85027d0bfa8e4198d73fc0b64b Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 5 Aug 2014 09:41:57 +0200 Subject: [PATCH 022/233] Added FIXME Former-commit-id: 61dfdb35eb265a34c94913947f4ae9164e79c0d9 --- include/Nazara/Math/Matrix4.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/Nazara/Math/Matrix4.hpp b/include/Nazara/Math/Matrix4.hpp index 90a5ae967..9f53bd227 100644 --- a/include/Nazara/Math/Matrix4.hpp +++ b/include/Nazara/Math/Matrix4.hpp @@ -7,6 +7,8 @@ #ifndef NAZARA_MATRIX4_HPP #define NAZARA_MATRIX4_HPP +///FIXME: Matrices column-major, difficile de bosser avec (Tout passer en row-major et transposer dans les shaders ?) + #include #include From 149ef145a30a3288e3d0930b8efb374af9b5b0cf Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 5 Aug 2014 09:42:37 +0200 Subject: [PATCH 023/233] Fixed DebugOff Former-commit-id: ba77eb95c3b5b3d4d88730c0fa029fd4f40e9c91 --- include/Nazara/Graphics/DebugOff.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Graphics/DebugOff.hpp b/include/Nazara/Graphics/DebugOff.hpp index f5e3b3e1c..17972d2f0 100644 --- a/include/Nazara/Graphics/DebugOff.hpp +++ b/include/Nazara/Graphics/DebugOff.hpp @@ -3,7 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp // On suppose que Debug.hpp a déjà été inclus, tout comme Config.hpp -#if NAZARA_GRAPHICS_HPP +#if NAZARA_GRAPHICS_MANAGE_MEMORY #undef delete #undef new #endif From b413727a219b88d28bedfe29c621eb19f6d197e1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 5 Aug 2014 09:43:19 +0200 Subject: [PATCH 024/233] Added required flags to UberShaderPreprocessor Former-commit-id: 1118fb08d1c0a7f6ebd18042f9a2044738bc4169 --- .../Renderer/UberShaderPreprocessor.hpp | 5 ++- .../Renderer/UberShaderPreprocessor.cpp | 43 +++++++++++++++---- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/include/Nazara/Renderer/UberShaderPreprocessor.hpp b/include/Nazara/Renderer/UberShaderPreprocessor.hpp index 3818c2154..0aa7679ac 100644 --- a/include/Nazara/Renderer/UberShaderPreprocessor.hpp +++ b/include/Nazara/Renderer/UberShaderPreprocessor.hpp @@ -23,8 +23,8 @@ class NAZARA_API NzUberShaderPreprocessor : public NzUberShader NzUberShaderInstance* Get(const NzParameterList& parameters) const; - void SetShader(nzShaderStage stage, const NzString& source, const NzString& flags); - bool SetShaderFromFile(nzShaderStage stage, const NzString& filePath, const NzString& flags); + void SetShader(nzShaderStage stage, const NzString& source, const NzString& shaderFlags, const NzString& requiredFlags = NzString()); + bool SetShaderFromFile(nzShaderStage stage, const NzString& filePath, const NzString& shaderFlags, const NzString& requiredFlags = NzString()); static bool IsSupported(); @@ -33,6 +33,7 @@ class NAZARA_API NzUberShaderPreprocessor : public NzUberShader { mutable std::unordered_map cache; std::unordered_map flags; + nzUInt32 requiredFlags; NzString source; bool present = false; }; diff --git a/src/Nazara/Renderer/UberShaderPreprocessor.cpp b/src/Nazara/Renderer/UberShaderPreprocessor.cpp index cffd8bc6b..5dd74bc32 100644 --- a/src/Nazara/Renderer/UberShaderPreprocessor.cpp +++ b/src/Nazara/Renderer/UberShaderPreprocessor.cpp @@ -32,7 +32,8 @@ NzUberShaderInstance* NzUberShaderPreprocessor::Get(const NzParameterList& param { try { - NzErrorFlags errFlags(nzErrorFlag_Silent | nzErrorFlag_ThrowException); + // Une exception sera lancée à la moindre erreur et celle-ci ne sera pas enregistrée dans le log (car traitée dans le bloc catch) + NzErrorFlags errFlags(nzErrorFlag_Silent | nzErrorFlag_ThrowException, true); std::unique_ptr shader(new NzShader); shader->SetPersistent(false); @@ -42,7 +43,8 @@ NzUberShaderInstance* NzUberShaderPreprocessor::Get(const NzParameterList& param { const Shader& shaderStage = m_shaders[i]; - if (shaderStage.present) + // Le shader stage est-il activé dans cette version du shader ? + if (shaderStage.present && (flags & shaderStage.requiredFlags) == shaderStage.requiredFlags) { nzUInt32 stageFlags = 0; for (auto it = shaderStage.flags.begin(); it != shaderStage.flags.end(); ++it) @@ -73,7 +75,7 @@ NzUberShaderInstance* NzUberShaderPreprocessor::Get(const NzParameterList& param for (auto it = shaderStage.flags.begin(); it != shaderStage.flags.end(); ++it) code << "#define " << it->first << ' ' << ((stageFlags & it->second) ? '1' : '0') << '\n'; - code << "\n#line 1\n"; + code << "\n#line 1\n"; // Pour que les éventuelles erreurs du shader se réfèrent à la bonne ligne code << shaderStage.source; stage.SetSource(code); @@ -90,6 +92,7 @@ NzUberShaderInstance* NzUberShaderPreprocessor::Get(const NzParameterList& param shader->Link(); + // On construit l'instant auto pair = m_cache.emplace(flags, shader.get()); shader.release(); @@ -99,23 +102,23 @@ NzUberShaderInstance* NzUberShaderPreprocessor::Get(const NzParameterList& param { NzErrorFlags errFlags(nzErrorFlag_ThrowExceptionDisabled); - NazaraError("Failed to build uber shader instance: " + NzError::GetLastError()); + NazaraError("Failed to build UberShader instance: " + NzError::GetLastError()); throw; } - } else return &shaderIt->second; } -void NzUberShaderPreprocessor::SetShader(nzShaderStage stage, const NzString& source, const NzString& flagString) +void NzUberShaderPreprocessor::SetShader(nzShaderStage stage, const NzString& source, const NzString& shaderFlags, const NzString& requiredFlags) { Shader& shader = m_shaders[stage]; shader.present = true; shader.source = source; + // On extrait les flags de la chaîne std::vector flags; - flagString.Split(flags, ' '); + shaderFlags.Split(flags, ' '); for (NzString& flag : flags) { @@ -127,9 +130,31 @@ void NzUberShaderPreprocessor::SetShader(nzShaderStage stage, const NzString& so if (it2 == shader.flags.end()) shader.flags[flag] = 1U << shader.flags.size(); } + + // On construit les flags requis pour l'activation du shader + shader.requiredFlags = 0; + + flags.clear(); + requiredFlags.Split(flags, ' '); + + for (NzString& flag : flags) + { + nzUInt32 flagVal; + + auto it = m_flags.find(flag); + if (it == m_flags.end()) + { + flagVal = 1U << m_flags.size(); + m_flags[flag] = flagVal; + } + else + flagVal = it->second; + + shader.requiredFlags |= flagVal; + } } -bool NzUberShaderPreprocessor::SetShaderFromFile(nzShaderStage stage, const NzString& filePath, const NzString& flags) +bool NzUberShaderPreprocessor::SetShaderFromFile(nzShaderStage stage, const NzString& filePath, const NzString& shaderFlags, const NzString& requiredFlags) { NzFile file(filePath); if (!file.Open(NzFile::ReadOnly | NzFile::Text)) @@ -150,7 +175,7 @@ bool NzUberShaderPreprocessor::SetShaderFromFile(nzShaderStage stage, const NzSt file.Close(); - SetShader(stage, source, flags); + SetShader(stage, source, shaderFlags, requiredFlags); return true; } From 4acd61cf3028a259d1b9a18eb30b2babfc356094 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 5 Aug 2014 17:38:49 +0200 Subject: [PATCH 025/233] Fixed Vector[2|3]::Normalize returning NaN for zero vectors Former-commit-id: e849a14189ff178134358d4ceed87955bc9f8eae --- include/Nazara/Math/Vector2.inl | 12 +++++++----- include/Nazara/Math/Vector3.inl | 12 +++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/include/Nazara/Math/Vector2.inl b/include/Nazara/Math/Vector2.inl index 7bfe930e0..227d95425 100644 --- a/include/Nazara/Math/Vector2.inl +++ b/include/Nazara/Math/Vector2.inl @@ -150,11 +150,13 @@ NzVector2& NzVector2::Minimize(const NzVector2& vec) template NzVector2& NzVector2::Normalize(T* length) { - T norm = std::sqrt(GetSquaredLength()); - T invNorm = F(1.0) / norm; - - x *= invNorm; - y *= invNorm; + T norm = GetLength(); + if (norm > F(0.0)) + { + T invNorm = F(1.0) / norm; + x *= invNorm; + y *= invNorm; + } if (length) *length = norm; diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index 15ad4c95e..f300330b8 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -231,11 +231,13 @@ template NzVector3& NzVector3::Normalize(T* length) { T norm = GetLength(); - T invNorm = F(1.0) / norm; - - x *= invNorm; - y *= invNorm; - z *= invNorm; + if (norm > F(0.0)) + { + T invNorm = F(1.0) / norm; + x *= invNorm; + y *= invNorm; + z *= invNorm; + } if (length) *length = norm; From e9267d7f4305554097fc4c5f38a4eb8dcdd6e02d Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 8 Aug 2014 17:17:58 +0200 Subject: [PATCH 026/233] Added particles first implementation Former-commit-id: 2b98ce2f007927690bdecd4092e211013bf568cb --- include/Nazara/Graphics/Enums.hpp | 43 ++- .../Nazara/Graphics/ParticleController.hpp | 31 ++ .../Nazara/Graphics/ParticleDeclaration.hpp | 67 ++++ include/Nazara/Graphics/ParticleEmitter.hpp | 91 +++++ include/Nazara/Graphics/ParticleGenerator.hpp | 31 ++ include/Nazara/Graphics/ParticleMapper.hpp | 31 ++ include/Nazara/Graphics/ParticleMapper.inl | 50 +++ include/Nazara/Graphics/ParticleRenderer.hpp | 32 ++ include/Nazara/Graphics/ParticleStruct.hpp | 42 ++ src/Nazara/Graphics/Graphics.cpp | 8 + src/Nazara/Graphics/ParticleController.cpp | 14 + src/Nazara/Graphics/ParticleDeclaration.cpp | 231 +++++++++++ src/Nazara/Graphics/ParticleEmitter.cpp | 361 ++++++++++++++++++ src/Nazara/Graphics/ParticleGenerator.cpp | 14 + src/Nazara/Graphics/ParticleMapper.cpp | 15 + src/Nazara/Graphics/ParticleRenderer.cpp | 14 + 16 files changed, 1071 insertions(+), 4 deletions(-) create mode 100644 include/Nazara/Graphics/ParticleController.hpp create mode 100644 include/Nazara/Graphics/ParticleDeclaration.hpp create mode 100644 include/Nazara/Graphics/ParticleEmitter.hpp create mode 100644 include/Nazara/Graphics/ParticleGenerator.hpp create mode 100644 include/Nazara/Graphics/ParticleMapper.hpp create mode 100644 include/Nazara/Graphics/ParticleMapper.inl create mode 100644 include/Nazara/Graphics/ParticleRenderer.hpp create mode 100644 include/Nazara/Graphics/ParticleStruct.hpp create mode 100644 src/Nazara/Graphics/ParticleController.cpp create mode 100644 src/Nazara/Graphics/ParticleDeclaration.cpp create mode 100644 src/Nazara/Graphics/ParticleEmitter.cpp create mode 100644 src/Nazara/Graphics/ParticleGenerator.cpp create mode 100644 src/Nazara/Graphics/ParticleMapper.cpp create mode 100644 src/Nazara/Graphics/ParticleRenderer.cpp diff --git a/include/Nazara/Graphics/Enums.hpp b/include/Nazara/Graphics/Enums.hpp index 59a8104c4..1f19f079e 100644 --- a/include/Nazara/Graphics/Enums.hpp +++ b/include/Nazara/Graphics/Enums.hpp @@ -43,6 +43,40 @@ enum nzMaterialUniform nzMaterialUniform_Max = nzMaterialUniform_SpecularMap }; +enum nzParticleComponent +{ + nzParticleComponent_Unused = -1, + + nzParticleComponent_Color, + nzParticleComponent_Life, + nzParticleComponent_Normal, + nzParticleComponent_Position, + nzParticleComponent_Radius, + nzParticleComponent_Rotation, + nzParticleComponent_Size, + nzParticleComponent_Velocity, + nzParticleComponent_Userdata0, + nzParticleComponent_Userdata1, + nzParticleComponent_Userdata2, + nzParticleComponent_Userdata3, + nzParticleComponent_Userdata4, + nzParticleComponent_Userdata5, + nzParticleComponent_Userdata6, + nzParticleComponent_Userdata7, + nzParticleComponent_Userdata8, + + nzParticleComponent_Max = nzParticleComponent_Userdata8 +}; + +enum nzParticleLayout +{ + nzParticleLayout_Billboard, + nzParticleLayout_Model, + nzParticleLayout_Sprite, + + nzParticleLayout_Max = nzParticleLayout_Sprite +}; + enum nzRenderPassType { nzRenderPassType_AA, @@ -71,10 +105,11 @@ enum nzRenderTechniqueType enum nzSceneNodeType { - nzSceneNodeType_Light, // NzLight - nzSceneNodeType_Model, // NzModel - nzSceneNodeType_Root, // NzSceneRoot - nzSceneNodeType_Sprite, // NzSprite + nzSceneNodeType_Light, // NzLight + nzSceneNodeType_Model, // NzModel + nzSceneNodeType_ParticleEmitter, // NzParticleEmitter + nzSceneNodeType_Root, // NzSceneRoot + nzSceneNodeType_Sprite, // NzSprite nzSceneNodeType_User, nzSceneNodeType_Max = nzSceneNodeType_User diff --git a/include/Nazara/Graphics/ParticleController.hpp b/include/Nazara/Graphics/ParticleController.hpp new file mode 100644 index 000000000..13d8f765f --- /dev/null +++ b/include/Nazara/Graphics/ParticleController.hpp @@ -0,0 +1,31 @@ +// Copyright (C) 2014 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_PARTICLECONTROLLER_HPP +#define NAZARA_PARTICLECONTROLLER_HPP + +#include +#include +#include + +class NzParticleController; +class NzParticleEmitter; +class NzParticleMapper; + +using NzParticleControllerConstRef = NzResourceRef; +using NzParticleControllerRef = NzResourceRef; + +class NAZARA_API NzParticleController : public NzResource +{ + public: + NzParticleController() = default; + NzParticleController(const NzParticleController& controller); + virtual ~NzParticleController(); + + virtual void Apply(NzParticleEmitter& emitter, NzParticleMapper& mapper, unsigned int offset, unsigned int particleCount, float elapsedTime) = 0; +}; + +#endif // NAZARA_PARTICLECONTROLLER_HPP diff --git a/include/Nazara/Graphics/ParticleDeclaration.hpp b/include/Nazara/Graphics/ParticleDeclaration.hpp new file mode 100644 index 000000000..af2cfd7e3 --- /dev/null +++ b/include/Nazara/Graphics/ParticleDeclaration.hpp @@ -0,0 +1,67 @@ +// Copyright (C) 2014 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_PARTICLEDECLARATION_HPP +#define NAZARA_PARTICLEDECLARATION_HPP + +#include +#include +#include +#include +#include + +class NzParticleDeclaration; + +using NzParticleDeclarationConstRef = NzResourceRef; +using NzParticleDeclarationRef = NzResourceRef; + +class NAZARA_API NzParticleDeclaration : public NzResource +{ + friend class NzGraphics; + + public: + NzParticleDeclaration(); + NzParticleDeclaration(const NzParticleDeclaration& declaration); + ~NzParticleDeclaration(); + + void DisableComponent(nzParticleComponent component); + void EnableComponent(nzParticleComponent component, nzComponentType type, unsigned int offset); + + void GetComponent(nzParticleComponent component, bool* enabled, nzComponentType* type, unsigned int* offset) const; + unsigned int GetStride() const; + + void SetStride(unsigned int stride); + + NzParticleDeclaration& operator=(const NzParticleDeclaration& declaration); + + static NzParticleDeclaration* Get(nzParticleLayout layout); + static bool IsTypeSupported(nzComponentType type); + + private: + static bool Initialize(); + static void Uninitialize(); + + struct Component + { + nzComponentType type; + bool enabled = false; + unsigned int offset; + + /* + ** -Lynix: + ** Il serait aussi possible de préciser le stride de façon indépendante, ce que je ne permets pas + ** pour décomplexifier l'interface en enlevant quelque chose que je juge inutile. + ** Si vous pensez que ça peut être utile, n'hésitez pas à me le faire savoir ! + */ + }; + + Component m_components[nzParticleComponent_Max+1]; + unsigned int m_stride; + + static NzParticleDeclaration s_declarations[nzParticleLayout_Max+1]; +}; + +#endif // NAZARA_PARTICLEDECLARATION_HPP diff --git a/include/Nazara/Graphics/ParticleEmitter.hpp b/include/Nazara/Graphics/ParticleEmitter.hpp new file mode 100644 index 000000000..47d6a6b0b --- /dev/null +++ b/include/Nazara/Graphics/ParticleEmitter.hpp @@ -0,0 +1,91 @@ +// Copyright (C) 2014 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_PARTICLEEMITTER_HPP +#define NAZARA_PARTICLEEMITTER_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class NAZARA_API NzParticleEmitter : public NzSceneNode, NzUpdatable +{ + public: + NzParticleEmitter(unsigned int maxParticleCount, nzParticleLayout layout); + NzParticleEmitter(unsigned int maxParticleCount, NzParticleDeclaration* declaration); + NzParticleEmitter(const NzParticleEmitter& emitter); + NzParticleEmitter(NzParticleEmitter&& emitter) = default; + ~NzParticleEmitter(); + + void AddController(NzParticleController* controller); + void AddGenerator(NzParticleGenerator* generator); + void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const; + + void* CreateParticle(); + void* CreateParticles(unsigned int count); + + void* GenerateParticle(); + void* GenerateParticles(unsigned int count); + + const NzBoundingVolumef& GetBoundingVolume() const override; + + unsigned int GetEmissionCount() const; + float GetEmissionRate() const; + unsigned int GetMaxParticleCount() const; + unsigned int GetParticleCount() const; + unsigned int GetParticleSize() const; + + nzSceneNodeType GetSceneNodeType() const override; + + bool IsDrawable() const; + + void KillParticle(unsigned int index); + void KillParticles(); + + void RemoveController(NzParticleController* controller); + void RemoveGenerator(NzParticleGenerator* generator); + + void SetEmissionCount(unsigned int count); + void SetEmissionRate(float rate); + void SetRenderer(NzParticleRenderer* renderer); + + NzParticleEmitter& operator=(const NzParticleEmitter& emitter); + NzParticleEmitter& operator=(NzParticleEmitter&& emitter); + + private: + void GenerateAABB() const; + void Register() override; + void ResizeBuffer(); + void Unregister() override; + void UpdateBoundingVolume() const; + void Update() override; + + std::set> m_dyingParticles; + mutable std::vector m_buffer; + std::vector m_controllers; + std::vector m_generators; + mutable NzBoundingVolumef m_boundingVolume; + NzParticleDeclarationConstRef m_declaration; + NzParticleRendererRef m_renderer; + mutable bool m_boundingVolumeUpdated; + bool m_processing; + float m_emissionAccumulator; + float m_emissionRate; + unsigned int m_emissionCount; + unsigned int m_maxParticleCount; + unsigned int m_particleCount; + unsigned int m_particleSize; +}; + +#endif // NAZARA_PARTICLEEMITTER_HPP diff --git a/include/Nazara/Graphics/ParticleGenerator.hpp b/include/Nazara/Graphics/ParticleGenerator.hpp new file mode 100644 index 000000000..0e8e8eb77 --- /dev/null +++ b/include/Nazara/Graphics/ParticleGenerator.hpp @@ -0,0 +1,31 @@ +// Copyright (C) 2014 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_PARTICLEGENERATOR_HPP +#define NAZARA_PARTICLEGENERATOR_HPP + +#include +#include +#include + +class NzParticleEmitter; +class NzParticleGenerator; +class NzParticleMapper; + +using NzParticleGeneratorConstRef = NzResourceRef; +using NzParticleGeneratorRef = NzResourceRef; + +class NAZARA_API NzParticleGenerator : public NzResource +{ + public: + NzParticleGenerator() = default; + NzParticleGenerator(const NzParticleGenerator& generator); + virtual ~NzParticleGenerator(); + + virtual void Generate(NzParticleEmitter& emitter, NzParticleMapper& mapper, unsigned int offset, unsigned int particleCount) = 0; +}; + +#endif // NAZARA_PARTICLEGENERATOR_HPP diff --git a/include/Nazara/Graphics/ParticleMapper.hpp b/include/Nazara/Graphics/ParticleMapper.hpp new file mode 100644 index 000000000..ac4b8dccf --- /dev/null +++ b/include/Nazara/Graphics/ParticleMapper.hpp @@ -0,0 +1,31 @@ +// Copyright (C) 2014 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_PARTICLEMAPPER_HPP +#define NAZARA_PARTICLEMAPPER_HPP + +#include +#include +#include +#include + +class NAZARA_API NzParticleMapper +{ + public: + NzParticleMapper(void* buffer, const NzParticleDeclaration* declaration); + ~NzParticleMapper(); + + template NzSparsePtr GetComponentPtr(nzParticleComponent component); + template NzSparsePtr GetComponentPtr(nzParticleComponent component) const; + + private: + const NzParticleDeclaration* m_declaration; + nzUInt8* m_ptr; +}; + +#include + +#endif // NAZARA_PARTICLEMAPPER_HPP diff --git a/include/Nazara/Graphics/ParticleMapper.inl b/include/Nazara/Graphics/ParticleMapper.inl new file mode 100644 index 000000000..b2dfdc1b2 --- /dev/null +++ b/include/Nazara/Graphics/ParticleMapper.inl @@ -0,0 +1,50 @@ +// Copyright (C) 2014 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 + +template +NzSparsePtr NzParticleMapper::GetComponentPtr(nzParticleComponent component) +{ + // Ensuite le composant qui nous intéresse + bool enabled; + nzComponentType type; + unsigned int offset; + m_declaration->GetComponent(component, &enabled, &type, &offset); + + if (enabled) + { + ///TODO: Vérifier le rapport entre le type de l'attribut et le type template ? + return NzSparsePtr(m_ptr + offset, m_declaration->GetStride()); + } + else + { + NazaraError("Attribute 0x" + NzString::Number(component, 16) + " is not enabled"); + return NzSparsePtr(); + } +} + +template +NzSparsePtr NzParticleMapper::GetComponentPtr(nzParticleComponent component) const +{ + // Ensuite le composant qui nous intéresse + bool enabled; + nzComponentType type; + unsigned int offset; + m_declaration->GetComponent(component, &enabled, &type, &offset); + + if (enabled) + { + ///TODO: Vérifier le rapport entre le type de l'attribut et le type template ? + return NzSparsePtr(m_ptr + offset, m_declaration->GetStride()); + } + else + { + NazaraError("Attribute 0x" + NzString::Number(component, 16) + " is not enabled"); + return NzSparsePtr(); + } +} + +#include diff --git a/include/Nazara/Graphics/ParticleRenderer.hpp b/include/Nazara/Graphics/ParticleRenderer.hpp new file mode 100644 index 000000000..ea85f3a87 --- /dev/null +++ b/include/Nazara/Graphics/ParticleRenderer.hpp @@ -0,0 +1,32 @@ +// Copyright (C) 2014 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_PARTICLERENDERER_HPP +#define NAZARA_PARTICLERENDERER_HPP + +#include +#include +#include + +class NzAbstractRenderQueue; +class NzParticleEmitter; +class NzParticleMapper; +class NzParticleRenderer; + +using NzParticleRendererConstRef = NzResourceRef; +using NzParticleRendererRef = NzResourceRef; + +class NAZARA_API NzParticleRenderer : public NzResource +{ + public: + NzParticleRenderer() = default; + NzParticleRenderer(const NzParticleRenderer& renderer); + virtual ~NzParticleRenderer(); + + virtual void Render(const NzParticleEmitter& emitter, const NzParticleMapper& mapper, unsigned int offset, unsigned int particleCount, NzAbstractRenderQueue* renderQueue) = 0; +}; + +#endif // NAZARA_PARTICLERENDERER_HPP diff --git a/include/Nazara/Graphics/ParticleStruct.hpp b/include/Nazara/Graphics/ParticleStruct.hpp new file mode 100644 index 000000000..d023b1470 --- /dev/null +++ b/include/Nazara/Graphics/ParticleStruct.hpp @@ -0,0 +1,42 @@ +// Copyright (C) 2014 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_PARTICLESTRUCT_HPP +#define NAZARA_PARTICLESTRUCT_HPP + +#include +#include +#include +#include + +struct NzParticleStruct_Billboard +{ + NzColor color; + NzVector3f normal; + NzVector3f position; + NzVector3f velocity; + nzUInt32 life; + float rotation; +}; + +struct NzParticleStruct_Model +{ + NzVector3f position; + NzVector3f velocity; + nzUInt32 life; + NzQuaternionf rotation; +}; + +struct NzParticleStruct_Sprite +{ + NzColor color; + NzVector2f position; + NzVector2f velocity; + nzUInt32 life; + float rotation; +}; + +#endif // NAZARA_PARTICLESTRUCT_HPP diff --git a/src/Nazara/Graphics/Graphics.cpp b/src/Nazara/Graphics/Graphics.cpp index db8e9c619..1058e484b 100644 --- a/src/Nazara/Graphics/Graphics.cpp +++ b/src/Nazara/Graphics/Graphics.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -44,6 +45,12 @@ bool NzGraphics::Initialize() return false; } + if (!NzParticleDeclaration::Initialize()) + { + NazaraError("Failed to initialize particle declarations"); + return false; + } + if (!NzSkinningManager::Initialize()) { NazaraError("Failed to initialize skinning manager"); @@ -98,6 +105,7 @@ void NzGraphics::Uninitialize() NzDeferredRenderTechnique::Uninitialize(); NzMaterial::Uninitialize(); + NzParticleDeclaration::Uninitialize(); NzSkinningManager::Uninitialize(); NazaraNotice("Uninitialized: Graphics module"); diff --git a/src/Nazara/Graphics/ParticleController.cpp b/src/Nazara/Graphics/ParticleController.cpp new file mode 100644 index 000000000..695fd7d5c --- /dev/null +++ b/src/Nazara/Graphics/ParticleController.cpp @@ -0,0 +1,14 @@ +// Copyright (C) 2014 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 + +NzParticleController::NzParticleController(const NzParticleController& controller) : +NzResource() +{ + NazaraUnused(controller); +} + +NzParticleController::~NzParticleController() = default; diff --git a/src/Nazara/Graphics/ParticleDeclaration.cpp b/src/Nazara/Graphics/ParticleDeclaration.cpp new file mode 100644 index 000000000..b2ab27d68 --- /dev/null +++ b/src/Nazara/Graphics/ParticleDeclaration.cpp @@ -0,0 +1,231 @@ +// Copyright (C) 2014 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 + +NzParticleDeclaration::NzParticleDeclaration() : +m_stride(0) +{ +} + +NzParticleDeclaration::NzParticleDeclaration(const NzParticleDeclaration& declaration) : +NzResource(), +m_stride(declaration.m_stride) +{ + std::memcpy(m_components, declaration.m_components, sizeof(Component)*(nzParticleComponent_Max+1)); +} + +NzParticleDeclaration::~NzParticleDeclaration() +{ + NotifyDestroy(); +} + +void NzParticleDeclaration::DisableComponent(nzParticleComponent component) +{ + #ifdef NAZARA_DEBUG + if (component > nzParticleComponent_Max) + { + NazaraError("Vertex component out of enum"); + return; + } + #endif + + #if NAZARA_GRAPHICS_SAFE + if (component == nzParticleComponent_Unused) + { + NazaraError("Cannot disable \"unused\" component"); + return; + } + #endif + + Component& vertexComponent = m_components[component]; + if (vertexComponent.enabled) + { + vertexComponent.enabled = false; + m_stride -= NzUtility::ComponentStride[vertexComponent.type]; + } +} + +void NzParticleDeclaration::EnableComponent(nzParticleComponent component, nzComponentType type, unsigned int offset) +{ + #ifdef NAZARA_DEBUG + if (component > nzParticleComponent_Max) + { + NazaraError("Vertex component out of enum"); + return; + } + #endif + + #if NAZARA_GRAPHICS_SAFE + if (!IsTypeSupported(type)) + { + NazaraError("Component type 0x" + NzString::Number(type, 16) + " is not supported by particle declarations"); + return; + } + #endif + + if (component != nzParticleComponent_Unused) + { + Component& particleComponent = m_components[component]; + if (particleComponent.enabled) + m_stride -= NzUtility::ComponentStride[particleComponent.type]; + else + particleComponent.enabled = true; + + particleComponent.offset = offset; + particleComponent.type = type; + } + + m_stride += NzUtility::ComponentStride[type]; +} + +void NzParticleDeclaration::GetComponent(nzParticleComponent component, bool* enabled, nzComponentType* type, unsigned int* offset) const +{ + #ifdef NAZARA_DEBUG + if (component > nzParticleComponent_Max) + { + NazaraError("Particle component out of enum"); + return; + } + #endif + + #if NAZARA_GRAPHICS_SAFE + if (component == nzParticleComponent_Unused) + { + NazaraError("Cannot get \"unused\" component"); + return; + } + #endif + + const Component& particleComponent = m_components[component]; + + if (enabled) + *enabled = particleComponent.enabled; + + if (type) + *type = particleComponent.type; + + if (offset) + *offset = particleComponent.offset; +} + +unsigned int NzParticleDeclaration::GetStride() const +{ + return m_stride; +} + +void NzParticleDeclaration::SetStride(unsigned int stride) +{ + m_stride = stride; +} + +NzParticleDeclaration& NzParticleDeclaration::operator=(const NzParticleDeclaration& declaration) +{ + std::memcpy(m_components, declaration.m_components, sizeof(Component)*(nzParticleComponent_Max+1)); + m_stride = declaration.m_stride; + + return *this; +} + +NzParticleDeclaration* NzParticleDeclaration::Get(nzParticleLayout layout) +{ + #ifdef NAZARA_DEBUG + if (layout > nzParticleLayout_Max) + { + NazaraError("Particle layout out of enum"); + return nullptr; + } + #endif + + return &s_declarations[layout]; +} + +bool NzParticleDeclaration::IsTypeSupported(nzComponentType type) +{ + switch (type) + { + case nzComponentType_Color: + case nzComponentType_Double1: + case nzComponentType_Double2: + case nzComponentType_Double3: + case nzComponentType_Double4: + case nzComponentType_Float1: + case nzComponentType_Float2: + case nzComponentType_Float3: + case nzComponentType_Float4: + case nzComponentType_Int1: + case nzComponentType_Int2: + case nzComponentType_Int3: + case nzComponentType_Int4: + case nzComponentType_Quaternion: + return true; + } + + NazaraError("Component type not handled (0x" + NzString::Number(type, 16) + ')'); + return false; +} + +bool NzParticleDeclaration::Initialize() +{ + try + { + NzErrorFlags flags(nzErrorFlag_Silent | nzErrorFlag_ThrowException); + + // Layout : Type + NzParticleDeclaration* declaration; + + // nzParticleLayout_Billboard : NzParticleStruct_Billboard + declaration = &s_declarations[nzParticleLayout_Billboard]; + declaration->EnableComponent(nzParticleComponent_Color, nzComponentType_Color, NzOffsetOf(NzParticleStruct_Billboard, color)); + declaration->EnableComponent(nzParticleComponent_Life, nzComponentType_Int1, NzOffsetOf(NzParticleStruct_Billboard, life)); + declaration->EnableComponent(nzParticleComponent_Normal, nzComponentType_Float3, NzOffsetOf(NzParticleStruct_Billboard, normal)); + declaration->EnableComponent(nzParticleComponent_Position, nzComponentType_Float3, NzOffsetOf(NzParticleStruct_Billboard, position)); + declaration->EnableComponent(nzParticleComponent_Rotation, nzComponentType_Float1, NzOffsetOf(NzParticleStruct_Billboard, rotation)); + declaration->EnableComponent(nzParticleComponent_Velocity, nzComponentType_Float3, NzOffsetOf(NzParticleStruct_Billboard, velocity)); + + NazaraAssert(declaration->GetStride() == sizeof(NzParticleStruct_Billboard), "Invalid stride for declaration nzParticleLayout_Billboard"); + + // nzParticleLayout_Model : NzParticleStruct_Model + declaration = &s_declarations[nzParticleLayout_Model]; + declaration->EnableComponent(nzParticleComponent_Life, nzComponentType_Int1, NzOffsetOf(NzParticleStruct_Model, life)); + declaration->EnableComponent(nzParticleComponent_Position, nzComponentType_Float3, NzOffsetOf(NzParticleStruct_Model, position)); + declaration->EnableComponent(nzParticleComponent_Rotation, nzComponentType_Quaternion, NzOffsetOf(NzParticleStruct_Model, rotation)); + declaration->EnableComponent(nzParticleComponent_Velocity, nzComponentType_Float3, NzOffsetOf(NzParticleStruct_Model, velocity)); + + NazaraAssert(declaration->GetStride() == sizeof(NzParticleStruct_Model), "Invalid stride for declaration nzParticleLayout_Model"); + + // nzParticleLayout_Sprite : NzParticleStruct_Sprite + declaration = &s_declarations[nzParticleLayout_Sprite]; + declaration->EnableComponent(nzParticleComponent_Color, nzComponentType_Color, NzOffsetOf(NzParticleStruct_Sprite, color)); + declaration->EnableComponent(nzParticleComponent_Life, nzComponentType_Int1, NzOffsetOf(NzParticleStruct_Sprite, life)); + declaration->EnableComponent(nzParticleComponent_Position, nzComponentType_Float2, NzOffsetOf(NzParticleStruct_Sprite, position)); + declaration->EnableComponent(nzParticleComponent_Rotation, nzComponentType_Float1, NzOffsetOf(NzParticleStruct_Sprite, rotation)); + declaration->EnableComponent(nzParticleComponent_Velocity, nzComponentType_Float2, NzOffsetOf(NzParticleStruct_Sprite, velocity)); + + NazaraAssert(declaration->GetStride() == sizeof(NzParticleStruct_Sprite), "Invalid stride for declaration nzParticleLayout_Sprite"); + } + catch (const std::exception& e) + { + NazaraError("Failed to initialize particle declarations: " + NzString(e.what())); + return false; + } + + return true; +} + +void NzParticleDeclaration::Uninitialize() +{ + // Rien à faire +} + +NzParticleDeclaration NzParticleDeclaration::s_declarations[nzParticleLayout_Max+1]; diff --git a/src/Nazara/Graphics/ParticleEmitter.cpp b/src/Nazara/Graphics/ParticleEmitter.cpp new file mode 100644 index 000000000..48162155b --- /dev/null +++ b/src/Nazara/Graphics/ParticleEmitter.cpp @@ -0,0 +1,361 @@ +// Copyright (C) 2014 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 + +NzParticleEmitter::NzParticleEmitter(unsigned int maxParticleCount, nzParticleLayout layout) : +NzParticleEmitter(maxParticleCount, NzParticleDeclaration::Get(layout)) +{ +} + +NzParticleEmitter::NzParticleEmitter(unsigned int maxParticleCount, NzParticleDeclaration* declaration) : +m_declaration(declaration), +m_boundingVolumeUpdated(false), +m_emissionAccumulator(0.f), +m_emissionRate(0.f), +m_emissionCount(1), +m_maxParticleCount(maxParticleCount), +m_particleCount(0) +{ + // En cas d'erreur, un constructeur ne peut que lancer une exception + NzErrorFlags flags(nzErrorFlag_ThrowException, true); + + m_particleSize = m_declaration->GetStride(); // La taille de chaque particule + + ResizeBuffer(); +} + +NzParticleEmitter::NzParticleEmitter(const NzParticleEmitter& emitter) : +NzSceneNode(emitter), +m_controllers(emitter.m_controllers), +m_generators(emitter.m_generators), +m_boundingVolume(emitter.m_boundingVolume), +m_declaration(emitter.m_declaration), +m_renderer(emitter.m_renderer), +m_boundingVolumeUpdated(emitter.m_boundingVolumeUpdated), +m_processing(false), +m_emissionAccumulator(0.f), +m_emissionRate(emitter.m_emissionRate), +m_emissionCount(emitter.m_emissionCount), +m_maxParticleCount(emitter.m_maxParticleCount), +m_particleCount(emitter.m_particleCount), +m_particleSize(emitter.m_particleSize) +{ + NzErrorFlags flags(nzErrorFlag_ThrowException, true); + + ResizeBuffer(); + + // On ne copie que les particules vivantes + std::memcpy(m_buffer.data(), emitter.m_buffer.data(), emitter.m_particleCount*m_particleSize); +} + +NzParticleEmitter::~NzParticleEmitter() = default; + +void NzParticleEmitter::AddController(NzParticleController* controller) +{ + m_controllers.emplace_back(controller); +} + +void NzParticleEmitter::AddGenerator(NzParticleGenerator* generator) +{ + m_generators.emplace_back(generator); +} + +void NzParticleEmitter::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const +{ + ///FIXME: Vérifier le renderer + NzParticleMapper mapper(m_buffer.data(), m_declaration); + + m_renderer->Render(*this, mapper, 0, m_particleCount, renderQueue); +} + +void* NzParticleEmitter::CreateParticle() +{ + return CreateParticles(1); +} + +void* NzParticleEmitter::CreateParticles(unsigned int count) +{ + if (m_particleCount+count > m_maxParticleCount) + return nullptr; + + unsigned int particlesIndex = m_particleCount; + m_particleCount += count; + + return &m_buffer[particlesIndex*m_particleSize]; +} + +void* NzParticleEmitter::GenerateParticle() +{ + return GenerateParticles(1); +} + +void* NzParticleEmitter::GenerateParticles(unsigned int count) +{ + void* ptr = CreateParticles(count); + if (!ptr) + return nullptr; + + NzParticleMapper mapper(ptr, m_declaration); + for (NzParticleGenerator* generator : m_generators) + generator->Generate(*this, mapper, 0, m_particleCount); + + return ptr; +} + +const NzBoundingVolumef& NzParticleEmitter::GetBoundingVolume() const +{ + if (!m_boundingVolumeUpdated) + UpdateBoundingVolume(); + + return m_boundingVolume; +} + +unsigned int NzParticleEmitter::GetEmissionCount() const +{ + return m_emissionCount; +} + +float NzParticleEmitter::GetEmissionRate() const +{ + return m_emissionRate; +} + +unsigned int NzParticleEmitter::GetMaxParticleCount() const +{ + return m_maxParticleCount; +} + +unsigned int NzParticleEmitter::GetParticleCount() const +{ + return m_particleCount; +} + +unsigned int NzParticleEmitter::GetParticleSize() const +{ + return m_particleSize; +} + +nzSceneNodeType NzParticleEmitter::GetSceneNodeType() const +{ + return nzSceneNodeType_ParticleEmitter; +} + +bool NzParticleEmitter::IsDrawable() const +{ + return true; +} + +void NzParticleEmitter::KillParticle(unsigned int index) +{ + ///FIXME: Vérifier index + + if (m_processing) + { + // Le buffer est en train d'être modifié, nous ne pouvons pas réduire sa taille, on place alors la particule dans une liste de secours + m_dyingParticles.insert(index); + return; + } + + // On déplace la dernière particule vivante à la place de celle-ci + if (--m_particleCount > 0) + std::memcpy(&m_buffer[index*m_particleSize], &m_buffer[m_particleCount*m_particleSize], m_particleSize); +} + +void NzParticleEmitter::KillParticles() +{ + m_particleCount = 0; +} + +void NzParticleEmitter::RemoveController(NzParticleController* controller) +{ + auto it = std::find(m_controllers.begin(), m_controllers.end(), controller); + if (it != m_controllers.end()) + m_controllers.erase(it); +} + +void NzParticleEmitter::RemoveGenerator(NzParticleGenerator* generator) +{ + auto it = std::find(m_generators.begin(), m_generators.end(), generator); + if (it != m_generators.end()) + m_generators.erase(it); +} + +void NzParticleEmitter::SetEmissionCount(unsigned int count) +{ + m_emissionCount = count; +} + +void NzParticleEmitter::SetEmissionRate(float rate) +{ + m_emissionRate = rate; +} + +void NzParticleEmitter::SetRenderer(NzParticleRenderer* renderer) +{ + m_renderer = renderer; +} + +NzParticleEmitter& NzParticleEmitter::operator=(const NzParticleEmitter& emitter) +{ + NzErrorFlags flags(nzErrorFlag_ThrowException, true); + + NzSceneNode::operator=(emitter); + + m_boundingVolume = emitter.m_boundingVolume; + m_boundingVolumeUpdated = emitter.m_boundingVolumeUpdated; + m_controllers = emitter.m_controllers; + m_declaration = emitter.m_declaration; + m_emissionCount = emitter.m_emissionCount; + m_emissionRate = emitter.m_emissionRate; + m_generators = emitter.m_generators; + m_maxParticleCount = emitter.m_maxParticleCount; + m_particleCount = emitter.m_particleCount; + m_particleSize = emitter.m_particleSize; + m_renderer = emitter.m_renderer; + + // La copie ne peut pas (ou plutôt ne devrait pas) avoir lieu pendant une mise à jour, inutile de copier + m_dyingParticles.clear(); + m_emissionAccumulator = 0.f; + m_processing = false; + + m_buffer.clear(); // Pour éviter une recopie lors du resize() qui ne servira pas à grand chose + ResizeBuffer(); + + // On ne copie que les particules vivantes + std::memcpy(m_buffer.data(), emitter.m_buffer.data(), emitter.m_particleCount*m_particleSize); + + return *this; +} + +NzParticleEmitter& NzParticleEmitter::operator=(NzParticleEmitter&& emitter) +{ + NzErrorFlags flags(nzErrorFlag_ThrowException, true); + + NzSceneNode::operator=(emitter); + + m_boundingVolume = std::move(emitter.m_boundingVolume); + m_boundingVolumeUpdated = std::move(emitter.m_boundingVolumeUpdated); + m_buffer = std::move(emitter.m_buffer); + m_controllers = std::move(emitter.m_controllers); + m_declaration = std::move(emitter.m_declaration); + m_dyingParticles = std::move(emitter.m_dyingParticles); + m_emissionAccumulator = std::move(emitter.m_emissionAccumulator); + m_emissionCount = std::move(emitter.m_emissionCount); + m_emissionRate = std::move(emitter.m_emissionRate); + m_generators = std::move(emitter.m_generators); + m_maxParticleCount = std::move(emitter.m_maxParticleCount); + m_particleCount = std::move(emitter.m_particleCount); + m_particleSize = std::move(emitter.m_particleSize); + m_processing = std::move(emitter.m_processing); + m_renderer = std::move(emitter.m_renderer); + + return *this; +} + +void NzParticleEmitter::GenerateAABB() const +{ + m_boundingVolume.MakeInfinite(); +} + +void NzParticleEmitter::Register() +{ + m_scene->RegisterForUpdate(this); +} + +void NzParticleEmitter::ResizeBuffer() +{ + // Histoire de décrire un peu mieux l'erreur en cas d'échec + try + { + m_buffer.resize(m_maxParticleCount*m_particleSize); + } + catch (const std::exception& e) + { + NzStringStream stream; + stream << "Failed to allocate particle buffer (" << e.what() << ") for " << m_maxParticleCount << " particles of size " << m_particleSize; + + NazaraError(stream.ToString()); + } +} + +void NzParticleEmitter::Unregister() +{ + m_scene->UnregisterForUpdate(this); +} + +void NzParticleEmitter::UpdateBoundingVolume() const +{ + if (m_boundingVolume.IsNull()) + GenerateAABB(); + + if (!m_transformMatrixUpdated) + UpdateTransformMatrix(); + + m_boundingVolume.Update(m_transformMatrix); + m_boundingVolumeUpdated = true; +} + +void NzParticleEmitter::Update() +{ + float elapsedTime = m_scene->GetUpdateTime(); + + if (m_emissionRate > 0.f) + { + // On accumule la partie réelle (pour éviter qu'un taux d'update élevé empêche des particules de se former) + m_emissionAccumulator += elapsedTime*m_emissionRate; + + float emissionCount = std::floor(m_emissionAccumulator); // Le nombre d'émissions de cette mise à jour + m_emissionAccumulator -= emissionCount; // On enlève la partie entière + + if (emissionCount >= 1.f) + { + // On calcule le nombre maximum de particules pouvant être émises cette fois-ci + unsigned int maxParticleCount = static_cast(emissionCount)*m_emissionCount; + + // On récupère le nombre de particules qu'il est possible de créer selon l'espace libre + unsigned int particleCount = std::min(maxParticleCount, m_maxParticleCount - m_particleCount); + + // Et on émet nos particules + GenerateParticles(particleCount); + } + } + + NzParticleMapper mapper(m_buffer.data(), m_declaration); + + m_processing = true; + + // Pour éviter un verrouillage en cas d'exception + NzCallOnExit onExit([this]() + { + m_processing = false; + }); + + for (NzParticleController* controller : m_controllers) + controller->Apply(*this, mapper, 0, m_particleCount, elapsedTime); + + m_processing = false; + onExit.Reset(); + + // On tue maintenant les particules mortes durant la mise à jour + if (m_dyingParticles.size() < m_particleCount) + { + // On tue les particules depuis la dernière vers la première (en terme de place), le std::set étant trié via std::greater + // La raison est simple, étant donné que la mort d'une particule signifie le déplacement de la dernière particule du buffer, + // sans cette solution certaines particules pourraient échapper à la mort + for (unsigned int index : m_dyingParticles) + KillParticle(index); + } + else + KillParticles(); // Toutes les particules sont mortes, ceci est beaucoup plus rapide + + m_dyingParticles.clear(); +} diff --git a/src/Nazara/Graphics/ParticleGenerator.cpp b/src/Nazara/Graphics/ParticleGenerator.cpp new file mode 100644 index 000000000..846e2c1ac --- /dev/null +++ b/src/Nazara/Graphics/ParticleGenerator.cpp @@ -0,0 +1,14 @@ +// Copyright (C) 2014 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 + +NzParticleGenerator::NzParticleGenerator(const NzParticleGenerator& generator) : +NzResource() +{ + NazaraUnused(generator); +} + +NzParticleGenerator::~NzParticleGenerator() = default; diff --git a/src/Nazara/Graphics/ParticleMapper.cpp b/src/Nazara/Graphics/ParticleMapper.cpp new file mode 100644 index 000000000..a73a53349 --- /dev/null +++ b/src/Nazara/Graphics/ParticleMapper.cpp @@ -0,0 +1,15 @@ +// Copyright (C) 2014 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 + +NzParticleMapper::NzParticleMapper(void* buffer, const NzParticleDeclaration* declaration) : +m_declaration(declaration), +m_ptr(static_cast(buffer)) +{ +} + +NzParticleMapper::~NzParticleMapper() = default; diff --git a/src/Nazara/Graphics/ParticleRenderer.cpp b/src/Nazara/Graphics/ParticleRenderer.cpp new file mode 100644 index 000000000..77f9e64c9 --- /dev/null +++ b/src/Nazara/Graphics/ParticleRenderer.cpp @@ -0,0 +1,14 @@ +// Copyright (C) 2014 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 + +NzParticleRenderer::NzParticleRenderer(const NzParticleRenderer& renderer) : +NzResource() +{ + NazaraUnused(renderer); +} + +NzParticleRenderer::~NzParticleRenderer() = default; From 202f6753019694f54d6361b9b8fe9561feb44db4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 8 Aug 2014 20:59:49 +0200 Subject: [PATCH 027/233] Changed particle callbacks arguments (offset, count) => (startId, endId) Former-commit-id: 24550dad44e55aa9dfabaf916cbfb8e25df0451a --- .../Nazara/Graphics/ParticleController.hpp | 2 +- include/Nazara/Graphics/ParticleGenerator.hpp | 2 +- include/Nazara/Graphics/ParticleRenderer.hpp | 2 +- src/Nazara/Graphics/ParticleEmitter.cpp | 61 ++++++++++--------- 4 files changed, 36 insertions(+), 31 deletions(-) diff --git a/include/Nazara/Graphics/ParticleController.hpp b/include/Nazara/Graphics/ParticleController.hpp index 13d8f765f..4456bcc28 100644 --- a/include/Nazara/Graphics/ParticleController.hpp +++ b/include/Nazara/Graphics/ParticleController.hpp @@ -25,7 +25,7 @@ class NAZARA_API NzParticleController : public NzResource NzParticleController(const NzParticleController& controller); virtual ~NzParticleController(); - virtual void Apply(NzParticleEmitter& emitter, NzParticleMapper& mapper, unsigned int offset, unsigned int particleCount, float elapsedTime) = 0; + virtual void Apply(NzParticleEmitter& emitter, NzParticleMapper& mapper, unsigned int startId, unsigned int endId, float elapsedTime) = 0; }; #endif // NAZARA_PARTICLECONTROLLER_HPP diff --git a/include/Nazara/Graphics/ParticleGenerator.hpp b/include/Nazara/Graphics/ParticleGenerator.hpp index 0e8e8eb77..eefb9233b 100644 --- a/include/Nazara/Graphics/ParticleGenerator.hpp +++ b/include/Nazara/Graphics/ParticleGenerator.hpp @@ -25,7 +25,7 @@ class NAZARA_API NzParticleGenerator : public NzResource NzParticleGenerator(const NzParticleGenerator& generator); virtual ~NzParticleGenerator(); - virtual void Generate(NzParticleEmitter& emitter, NzParticleMapper& mapper, unsigned int offset, unsigned int particleCount) = 0; + virtual void Generate(NzParticleEmitter& emitter, NzParticleMapper& mapper, unsigned int startId, unsigned int endId) = 0; }; #endif // NAZARA_PARTICLEGENERATOR_HPP diff --git a/include/Nazara/Graphics/ParticleRenderer.hpp b/include/Nazara/Graphics/ParticleRenderer.hpp index ea85f3a87..81219c624 100644 --- a/include/Nazara/Graphics/ParticleRenderer.hpp +++ b/include/Nazara/Graphics/ParticleRenderer.hpp @@ -26,7 +26,7 @@ class NAZARA_API NzParticleRenderer : public NzResource NzParticleRenderer(const NzParticleRenderer& renderer); virtual ~NzParticleRenderer(); - virtual void Render(const NzParticleEmitter& emitter, const NzParticleMapper& mapper, unsigned int offset, unsigned int particleCount, NzAbstractRenderQueue* renderQueue) = 0; + virtual void Render(const NzParticleEmitter& emitter, const NzParticleMapper& mapper, unsigned int startId, unsigned int endId, NzAbstractRenderQueue* renderQueue) = 0; }; #endif // NAZARA_PARTICLERENDERER_HPP diff --git a/src/Nazara/Graphics/ParticleEmitter.cpp b/src/Nazara/Graphics/ParticleEmitter.cpp index 48162155b..b6dc13244 100644 --- a/src/Nazara/Graphics/ParticleEmitter.cpp +++ b/src/Nazara/Graphics/ParticleEmitter.cpp @@ -72,9 +72,11 @@ void NzParticleEmitter::AddGenerator(NzParticleGenerator* generator) void NzParticleEmitter::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const { ///FIXME: Vérifier le renderer - NzParticleMapper mapper(m_buffer.data(), m_declaration); - - m_renderer->Render(*this, mapper, 0, m_particleCount, renderQueue); + if (m_particleCount > 0) + { + NzParticleMapper mapper(m_buffer.data(), m_declaration); + m_renderer->Render(*this, mapper, 0, m_particleCount-1, renderQueue); + } } void* NzParticleEmitter::CreateParticle() @@ -106,7 +108,7 @@ void* NzParticleEmitter::GenerateParticles(unsigned int count) NzParticleMapper mapper(ptr, m_declaration); for (NzParticleGenerator* generator : m_generators) - generator->Generate(*this, mapper, 0, m_particleCount); + generator->Generate(*this, mapper, 0, m_particleCount-1); return ptr; } @@ -329,33 +331,36 @@ void NzParticleEmitter::Update() } } - NzParticleMapper mapper(m_buffer.data(), m_declaration); - - m_processing = true; - - // Pour éviter un verrouillage en cas d'exception - NzCallOnExit onExit([this]() + if (m_particleCount > 0) { + NzParticleMapper mapper(m_buffer.data(), m_declaration); + + m_processing = true; + + // Pour éviter un verrouillage en cas d'exception + NzCallOnExit onExit([this]() + { + m_processing = false; + }); + + for (NzParticleController* controller : m_controllers) + controller->Apply(*this, mapper, 0, m_particleCount-1, elapsedTime); + m_processing = false; - }); + onExit.Reset(); - for (NzParticleController* controller : m_controllers) - controller->Apply(*this, mapper, 0, m_particleCount, elapsedTime); + // On tue maintenant les particules mortes durant la mise à jour + if (m_dyingParticles.size() < m_particleCount) + { + // On tue les particules depuis la dernière vers la première (en terme de place), le std::set étant trié via std::greater + // La raison est simple, étant donné que la mort d'une particule signifie le déplacement de la dernière particule du buffer, + // sans cette solution certaines particules pourraient échapper à la mort + for (unsigned int index : m_dyingParticles) + KillParticle(index); + } + else + KillParticles(); // Toutes les particules sont mortes, ceci est beaucoup plus rapide - m_processing = false; - onExit.Reset(); - - // On tue maintenant les particules mortes durant la mise à jour - if (m_dyingParticles.size() < m_particleCount) - { - // On tue les particules depuis la dernière vers la première (en terme de place), le std::set étant trié via std::greater - // La raison est simple, étant donné que la mort d'une particule signifie le déplacement de la dernière particule du buffer, - // sans cette solution certaines particules pourraient échapper à la mort - for (unsigned int index : m_dyingParticles) - KillParticle(index); + m_dyingParticles.clear(); } - else - KillParticles(); // Toutes les particules sont mortes, ceci est beaucoup plus rapide - - m_dyingParticles.clear(); } From 0976607eb93b8154bfb3e93970e73bcb4bb8bab8 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 8 Aug 2014 21:21:04 +0200 Subject: [PATCH 028/233] Added fixed step update Switched back to defaulted operator=(ParticleEmitter&&) since it can't throw exception anyway Former-commit-id: 178b040a735ef01dcda21b45a317b6c534b5782e --- include/Nazara/Graphics/ParticleEmitter.hpp | 9 ++- src/Nazara/Graphics/ParticleEmitter.cpp | 68 +++++++++++++-------- 2 files changed, 49 insertions(+), 28 deletions(-) diff --git a/include/Nazara/Graphics/ParticleEmitter.hpp b/include/Nazara/Graphics/ParticleEmitter.hpp index 47d6a6b0b..f9d279fcc 100644 --- a/include/Nazara/Graphics/ParticleEmitter.hpp +++ b/include/Nazara/Graphics/ParticleEmitter.hpp @@ -35,6 +35,8 @@ class NAZARA_API NzParticleEmitter : public NzSceneNode, NzUpdatable void* CreateParticle(); void* CreateParticles(unsigned int count); + void EnableFixedStep(bool fixedStep); + void* GenerateParticle(); void* GenerateParticles(unsigned int count); @@ -49,6 +51,7 @@ class NAZARA_API NzParticleEmitter : public NzSceneNode, NzUpdatable nzSceneNodeType GetSceneNodeType() const override; bool IsDrawable() const; + bool IsFixedStepEnabled() const; void KillParticle(unsigned int index); void KillParticles(); @@ -58,10 +61,11 @@ class NAZARA_API NzParticleEmitter : public NzSceneNode, NzUpdatable void SetEmissionCount(unsigned int count); void SetEmissionRate(float rate); + void SetFixedStepSize(float step); void SetRenderer(NzParticleRenderer* renderer); NzParticleEmitter& operator=(const NzParticleEmitter& emitter); - NzParticleEmitter& operator=(NzParticleEmitter&& emitter); + NzParticleEmitter& operator=(NzParticleEmitter&& emitter) = default; private: void GenerateAABB() const; @@ -79,9 +83,12 @@ class NAZARA_API NzParticleEmitter : public NzSceneNode, NzUpdatable NzParticleDeclarationConstRef m_declaration; NzParticleRendererRef m_renderer; mutable bool m_boundingVolumeUpdated; + bool m_fixedStepEnabled; bool m_processing; float m_emissionAccumulator; float m_emissionRate; + float m_stepAccumulator; + float m_stepSize; unsigned int m_emissionCount; unsigned int m_maxParticleCount; unsigned int m_particleCount; diff --git a/src/Nazara/Graphics/ParticleEmitter.cpp b/src/Nazara/Graphics/ParticleEmitter.cpp index b6dc13244..7a54ef7f7 100644 --- a/src/Nazara/Graphics/ParticleEmitter.cpp +++ b/src/Nazara/Graphics/ParticleEmitter.cpp @@ -19,8 +19,12 @@ NzParticleEmitter(maxParticleCount, NzParticleDeclaration::Get(layout)) NzParticleEmitter::NzParticleEmitter(unsigned int maxParticleCount, NzParticleDeclaration* declaration) : m_declaration(declaration), m_boundingVolumeUpdated(false), +m_fixedStepEnabled(false), +m_processing(false), m_emissionAccumulator(0.f), m_emissionRate(0.f), +m_stepAccumulator(0.f), +m_stepSize(1.f/60.f), m_emissionCount(1), m_maxParticleCount(maxParticleCount), m_particleCount(0) @@ -41,9 +45,12 @@ m_boundingVolume(emitter.m_boundingVolume), m_declaration(emitter.m_declaration), m_renderer(emitter.m_renderer), m_boundingVolumeUpdated(emitter.m_boundingVolumeUpdated), +m_fixedStepEnabled(emitter.m_fixedStepEnabled), m_processing(false), m_emissionAccumulator(0.f), m_emissionRate(emitter.m_emissionRate), +m_stepAccumulator(0.f), +m_stepSize(emitter.m_stepSize), m_emissionCount(emitter.m_emissionCount), m_maxParticleCount(emitter.m_maxParticleCount), m_particleCount(emitter.m_particleCount), @@ -95,6 +102,16 @@ void* NzParticleEmitter::CreateParticles(unsigned int count) return &m_buffer[particlesIndex*m_particleSize]; } +void NzParticleEmitter::EnableFixedStep(bool fixedStep) +{ + // On teste pour empêcher que cette méthode ne remette systématiquement le step accumulator à zéro + if (m_fixedStepEnabled != fixedStep) + { + m_fixedStepEnabled = fixedStep; + m_stepAccumulator = 0.f; + } +} + void* NzParticleEmitter::GenerateParticle() { return GenerateParticles(1); @@ -156,6 +173,11 @@ bool NzParticleEmitter::IsDrawable() const return true; } +bool NzParticleEmitter::IsFixedStepEnabled() const +{ + return m_fixedStepEnabled; +} + void NzParticleEmitter::KillParticle(unsigned int index) { ///FIXME: Vérifier index @@ -218,16 +240,19 @@ NzParticleEmitter& NzParticleEmitter::operator=(const NzParticleEmitter& emitter m_declaration = emitter.m_declaration; m_emissionCount = emitter.m_emissionCount; m_emissionRate = emitter.m_emissionRate; + m_fixedStepEnabled = emitter.m_fixedStepEnabled; m_generators = emitter.m_generators; m_maxParticleCount = emitter.m_maxParticleCount; m_particleCount = emitter.m_particleCount; m_particleSize = emitter.m_particleSize; m_renderer = emitter.m_renderer; + m_stepSize = emitter.m_stepSize; // La copie ne peut pas (ou plutôt ne devrait pas) avoir lieu pendant une mise à jour, inutile de copier m_dyingParticles.clear(); m_emissionAccumulator = 0.f; m_processing = false; + m_stepAccumulator = 0.f; m_buffer.clear(); // Pour éviter une recopie lors du resize() qui ne servira pas à grand chose ResizeBuffer(); @@ -238,31 +263,6 @@ NzParticleEmitter& NzParticleEmitter::operator=(const NzParticleEmitter& emitter return *this; } -NzParticleEmitter& NzParticleEmitter::operator=(NzParticleEmitter&& emitter) -{ - NzErrorFlags flags(nzErrorFlag_ThrowException, true); - - NzSceneNode::operator=(emitter); - - m_boundingVolume = std::move(emitter.m_boundingVolume); - m_boundingVolumeUpdated = std::move(emitter.m_boundingVolumeUpdated); - m_buffer = std::move(emitter.m_buffer); - m_controllers = std::move(emitter.m_controllers); - m_declaration = std::move(emitter.m_declaration); - m_dyingParticles = std::move(emitter.m_dyingParticles); - m_emissionAccumulator = std::move(emitter.m_emissionAccumulator); - m_emissionCount = std::move(emitter.m_emissionCount); - m_emissionRate = std::move(emitter.m_emissionRate); - m_generators = std::move(emitter.m_generators); - m_maxParticleCount = std::move(emitter.m_maxParticleCount); - m_particleCount = std::move(emitter.m_particleCount); - m_particleSize = std::move(emitter.m_particleSize); - m_processing = std::move(emitter.m_processing); - m_renderer = std::move(emitter.m_renderer); - - return *this; -} - void NzParticleEmitter::GenerateAABB() const { m_boundingVolume.MakeInfinite(); @@ -343,8 +343,22 @@ void NzParticleEmitter::Update() m_processing = false; }); - for (NzParticleController* controller : m_controllers) - controller->Apply(*this, mapper, 0, m_particleCount-1, elapsedTime); + if (m_fixedStepEnabled) + { + m_stepAccumulator += elapsedTime; + while (m_stepAccumulator >= m_stepSize) + { + for (NzParticleController* controller : m_controllers) + controller->Apply(*this, mapper, 0, m_particleCount-1, m_stepAccumulator); + + m_stepAccumulator -= m_stepSize; + } + } + else + { + for (NzParticleController* controller : m_controllers) + controller->Apply(*this, mapper, 0, m_particleCount-1, elapsedTime); + } m_processing = false; onExit.Reset(); From f395cb7579c60c1ccd4f0df2c9bebc9907d20d9b Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 9 Aug 2014 00:30:24 +0200 Subject: [PATCH 029/233] Added ParticleEmitter::GetFixedStepSize() Fixed missing implementation of ParticleEmitter::SetFixedStepSize Former-commit-id: 255fcca4afe40cccf38a561f09f29a0a4ceccd71 --- include/Nazara/Graphics/ParticleEmitter.hpp | 3 ++- src/Nazara/Graphics/ParticleEmitter.cpp | 10 ++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Graphics/ParticleEmitter.hpp b/include/Nazara/Graphics/ParticleEmitter.hpp index f9d279fcc..ac85c9480 100644 --- a/include/Nazara/Graphics/ParticleEmitter.hpp +++ b/include/Nazara/Graphics/ParticleEmitter.hpp @@ -44,6 +44,7 @@ class NAZARA_API NzParticleEmitter : public NzSceneNode, NzUpdatable unsigned int GetEmissionCount() const; float GetEmissionRate() const; + float GetFixedStepSize() const; unsigned int GetMaxParticleCount() const; unsigned int GetParticleCount() const; unsigned int GetParticleSize() const; @@ -61,7 +62,7 @@ class NAZARA_API NzParticleEmitter : public NzSceneNode, NzUpdatable void SetEmissionCount(unsigned int count); void SetEmissionRate(float rate); - void SetFixedStepSize(float step); + void SetFixedStepSize(float stepSize); void SetRenderer(NzParticleRenderer* renderer); NzParticleEmitter& operator=(const NzParticleEmitter& emitter); diff --git a/src/Nazara/Graphics/ParticleEmitter.cpp b/src/Nazara/Graphics/ParticleEmitter.cpp index 7a54ef7f7..8671091bc 100644 --- a/src/Nazara/Graphics/ParticleEmitter.cpp +++ b/src/Nazara/Graphics/ParticleEmitter.cpp @@ -148,6 +148,11 @@ float NzParticleEmitter::GetEmissionRate() const return m_emissionRate; } +float NzParticleEmitter::GetFixedStepSize() const +{ + return m_stepSize; +} + unsigned int NzParticleEmitter::GetMaxParticleCount() const { return m_maxParticleCount; @@ -223,6 +228,11 @@ void NzParticleEmitter::SetEmissionRate(float rate) m_emissionRate = rate; } +void NzParticleEmitter::SetFixedStepSize(float stepSize) +{ + m_stepSize = stepSize; +} + void NzParticleEmitter::SetRenderer(NzParticleRenderer* renderer) { m_renderer = renderer; From a15e3abd0c3ba227c80c10ab089916eee153000d Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 9 Aug 2014 00:31:01 +0200 Subject: [PATCH 030/233] Added Mass particle component Former-commit-id: 491f488b7eab8aeb06a441701ca004f1738571e6 --- include/Nazara/Graphics/Enums.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/Nazara/Graphics/Enums.hpp b/include/Nazara/Graphics/Enums.hpp index 1f19f079e..6f9cc9814 100644 --- a/include/Nazara/Graphics/Enums.hpp +++ b/include/Nazara/Graphics/Enums.hpp @@ -49,6 +49,7 @@ enum nzParticleComponent nzParticleComponent_Color, nzParticleComponent_Life, + nzParticleComponent_Mass, nzParticleComponent_Normal, nzParticleComponent_Position, nzParticleComponent_Radius, From f936dac6ad07ad6ea0012f1221ba05caaa284081 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 18 Aug 2014 15:14:29 +0200 Subject: [PATCH 031/233] Fixed a terrible mistake in [Index|Vertex]Buffer::Reset Former-commit-id: 97daa00a60615e88fb8d015bd02281713c61807b --- src/Nazara/Utility/IndexBuffer.cpp | 4 ++-- src/Nazara/Utility/VertexBuffer.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Nazara/Utility/IndexBuffer.cpp b/src/Nazara/Utility/IndexBuffer.cpp index 2f13fad5f..d1b3bfc1c 100644 --- a/src/Nazara/Utility/IndexBuffer.cpp +++ b/src/Nazara/Utility/IndexBuffer.cpp @@ -177,9 +177,9 @@ void NzIndexBuffer::Reset(bool largeIndices, NzBuffer* buffer, unsigned int star return; } - if (endOffset > startOffset) + if (startOffset > endOffset) { - NazaraError("End offset cannot be over start offset"); + NazaraError("Start offset cannot be over end offset"); return; } diff --git a/src/Nazara/Utility/VertexBuffer.cpp b/src/Nazara/Utility/VertexBuffer.cpp index 5bde1935b..c5b9f300f 100644 --- a/src/Nazara/Utility/VertexBuffer.cpp +++ b/src/Nazara/Utility/VertexBuffer.cpp @@ -189,9 +189,9 @@ void NzVertexBuffer::Reset(const NzVertexDeclaration* vertexDeclaration, NzBuffe return; } - if (endOffset > startOffset) + if (startOffset > endOffset) { - NazaraError("End offset cannot be over start offset"); + NazaraError("Start offset cannot be over end offset"); return; } From df44d799c80a665378c359ef45adc9d03d84bb1e Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 18 Aug 2014 15:39:44 +0200 Subject: [PATCH 032/233] Added [Index|Vertex]Buffer easy constructor Former-commit-id: 4536af8c833c15b49876c773defd3475a561df4b --- include/Nazara/Utility/IndexBuffer.hpp | 2 ++ include/Nazara/Utility/VertexBuffer.hpp | 2 ++ src/Nazara/Utility/IndexBuffer.cpp | 10 ++++++++++ src/Nazara/Utility/VertexBuffer.cpp | 10 ++++++++++ 4 files changed, 24 insertions(+) diff --git a/include/Nazara/Utility/IndexBuffer.hpp b/include/Nazara/Utility/IndexBuffer.hpp index ea7745c42..3088a0fd1 100644 --- a/include/Nazara/Utility/IndexBuffer.hpp +++ b/include/Nazara/Utility/IndexBuffer.hpp @@ -21,6 +21,7 @@ class NAZARA_API NzIndexBuffer : public NzResource { public: NzIndexBuffer() = default; + NzIndexBuffer(bool largeIndices, NzBuffer* buffer); NzIndexBuffer(bool largeIndices, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset); NzIndexBuffer(bool largeIndices, unsigned int length, nzBufferStorage storage = nzBufferStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); NzIndexBuffer(const NzIndexBuffer& indexBuffer); @@ -51,6 +52,7 @@ class NAZARA_API NzIndexBuffer : public NzResource void Optimize(); void Reset(); + void Reset(bool largeIndices, NzBuffer* buffer); void Reset(bool largeIndices, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset); void Reset(bool largeIndices, unsigned int length, nzBufferStorage storage = nzBufferStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); void Reset(const NzIndexBuffer& indexBuffer); diff --git a/include/Nazara/Utility/VertexBuffer.hpp b/include/Nazara/Utility/VertexBuffer.hpp index 0bbb8b68a..6b009561d 100644 --- a/include/Nazara/Utility/VertexBuffer.hpp +++ b/include/Nazara/Utility/VertexBuffer.hpp @@ -22,6 +22,7 @@ class NAZARA_API NzVertexBuffer : public NzResource { public: NzVertexBuffer() = default; + NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer); NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset); NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzBufferStorage storage = nzBufferStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); NzVertexBuffer(const NzVertexBuffer& vertexBuffer); @@ -47,6 +48,7 @@ class NAZARA_API NzVertexBuffer : public NzResource void* MapRaw(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0) const; void Reset(); + void Reset(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer); void Reset(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset); void Reset(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzBufferStorage storage = nzBufferStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); void Reset(const NzVertexBuffer& vertexBuffer); diff --git a/src/Nazara/Utility/IndexBuffer.cpp b/src/Nazara/Utility/IndexBuffer.cpp index d1b3bfc1c..97744df60 100644 --- a/src/Nazara/Utility/IndexBuffer.cpp +++ b/src/Nazara/Utility/IndexBuffer.cpp @@ -11,6 +11,11 @@ #include #include +NzIndexBuffer::NzIndexBuffer(bool largeIndices, NzBuffer* buffer) +{ + Reset(largeIndices, buffer); +} + NzIndexBuffer::NzIndexBuffer(bool largeIndices, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset) { Reset(largeIndices, buffer, startOffset, endOffset); @@ -168,6 +173,11 @@ void NzIndexBuffer::Reset() m_buffer.Reset(); } +void NzIndexBuffer::Reset(bool largeIndices, NzBuffer* buffer) +{ + Reset(largeIndices, buffer, 0, buffer->GetSize()-1); +} + void NzIndexBuffer::Reset(bool largeIndices, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset) { #if NAZARA_UTILITY_SAFE diff --git a/src/Nazara/Utility/VertexBuffer.cpp b/src/Nazara/Utility/VertexBuffer.cpp index c5b9f300f..fd7a0883b 100644 --- a/src/Nazara/Utility/VertexBuffer.cpp +++ b/src/Nazara/Utility/VertexBuffer.cpp @@ -7,6 +7,11 @@ #include #include +NzVertexBuffer::NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer) +{ + Reset(vertexDeclaration, buffer); +} + NzVertexBuffer::NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset) { Reset(vertexDeclaration, buffer, startOffset, endOffset); @@ -180,6 +185,11 @@ void NzVertexBuffer::Reset() m_vertexDeclaration.Reset(); } +void NzVertexBuffer::Reset(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer) +{ + Reset(vertexDeclaration, buffer, 0, buffer->GetSize()-1); +} + void NzVertexBuffer::Reset(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset) { #if NAZARA_UTILITY_SAFE From 34af3c9bc979d72d79713209d01c989b42391f69 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 18 Aug 2014 15:40:54 +0200 Subject: [PATCH 033/233] [Index|Vertex]Buffer constructor now throw an exception on error As it should do anyway Former-commit-id: af4589424c0009dfc40ebf5ae57172fb5df77dc0 --- src/Nazara/Utility/IndexBuffer.cpp | 4 ++++ src/Nazara/Utility/VertexBuffer.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/Nazara/Utility/IndexBuffer.cpp b/src/Nazara/Utility/IndexBuffer.cpp index 97744df60..f96c220b8 100644 --- a/src/Nazara/Utility/IndexBuffer.cpp +++ b/src/Nazara/Utility/IndexBuffer.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -13,16 +14,19 @@ NzIndexBuffer::NzIndexBuffer(bool largeIndices, NzBuffer* buffer) { + NzErrorFlags(nzErrorFlag_ThrowException, true); Reset(largeIndices, buffer); } NzIndexBuffer::NzIndexBuffer(bool largeIndices, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset) { + NzErrorFlags(nzErrorFlag_ThrowException, true); Reset(largeIndices, buffer, startOffset, endOffset); } NzIndexBuffer::NzIndexBuffer(bool largeIndices, unsigned int length, nzBufferStorage storage, nzBufferUsage usage) { + NzErrorFlags(nzErrorFlag_ThrowException, true); Reset(largeIndices, length, storage, usage); } diff --git a/src/Nazara/Utility/VertexBuffer.cpp b/src/Nazara/Utility/VertexBuffer.cpp index fd7a0883b..45c572fea 100644 --- a/src/Nazara/Utility/VertexBuffer.cpp +++ b/src/Nazara/Utility/VertexBuffer.cpp @@ -4,21 +4,25 @@ #include #include +#include #include #include NzVertexBuffer::NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer) { + NzErrorFlags(nzErrorFlag_ThrowException, true); Reset(vertexDeclaration, buffer); } NzVertexBuffer::NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset) { + NzErrorFlags(nzErrorFlag_ThrowException, true); Reset(vertexDeclaration, buffer, startOffset, endOffset); } NzVertexBuffer::NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzBufferStorage storage, nzBufferUsage usage) { + NzErrorFlags(nzErrorFlag_ThrowException, true); Reset(vertexDeclaration, length, storage, usage); } From f154dbfb319c4e641a7e1b713f7fe1298afc193d Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 18 Aug 2014 15:41:42 +0200 Subject: [PATCH 034/233] Fixed rare bug when initializing debug drawer Former-commit-id: 287d10c05a481a139449068014780aa7119096bb --- src/Nazara/Renderer/DebugDrawer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Renderer/DebugDrawer.cpp b/src/Nazara/Renderer/DebugDrawer.cpp index 1a2e96ee7..066566bc1 100644 --- a/src/Nazara/Renderer/DebugDrawer.cpp +++ b/src/Nazara/Renderer/DebugDrawer.cpp @@ -661,7 +661,7 @@ bool NzDebugDrawer::Initialize() // s_vertexBuffer try { - NzErrorFlags flags(nzErrorFlag_ThrowException); + NzErrorFlags flags(nzErrorFlag_ThrowException, true); s_vertexBuffer.Reset(NzVertexDeclaration::Get(nzVertexLayout_XYZ), 65365, nzBufferStorage_Hardware, nzBufferUsage_Dynamic); } catch (const std::exception& e) From 0d69da09b9933aa8ae4159a021ac1ba8603b9010 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 18 Aug 2014 15:42:17 +0200 Subject: [PATCH 035/233] Fixed Renderer testing non-enabled vertex components Former-commit-id: d624d98b7b8a61fc3dc92d4c10441e759a50f310 --- src/Nazara/Renderer/Renderer.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index 0fc62e782..cead125a6 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -1786,15 +1786,15 @@ bool NzRenderer::EnsureStateUpdate() unsigned int offset; vertexDeclaration->GetComponent(static_cast(j), &enabled, &type, &offset); - if (!IsComponentTypeSupported(type)) - { - NazaraError("Invalid vertex declaration " + NzString::Pointer(vertexDeclaration) + ": Vertex component 0x" + NzString::Number(j, 16) + " (type: 0x" + NzString::Number(type, 16) + ") is not supported"); - updateFailed = true; - break; - } - if (enabled) { + if (!IsComponentTypeSupported(type)) + { + NazaraError("Invalid vertex declaration " + NzString::Pointer(vertexDeclaration) + ": Vertex component 0x" + NzString::Number(j, 16) + " (type: 0x" + NzString::Number(type, 16) + ") is not supported"); + updateFailed = true; + break; + } + glEnableVertexAttribArray(NzOpenGL::VertexComponentIndex[j]); switch (type) From f56e0504e63db2de88f919e7f8df1c0d0b5af878 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 18 Aug 2014 15:45:37 +0200 Subject: [PATCH 036/233] Buffer, [Render]Window now always throw on error Former-commit-id: a739cd4c7d96e7cf497338c525e9ab1b5d6a844a --- src/Nazara/Renderer/RenderWindow.cpp | 18 ++---------------- src/Nazara/Utility/Buffer.cpp | 10 ++-------- src/Nazara/Utility/Window.cpp | 18 ++---------------- 3 files changed, 6 insertions(+), 40 deletions(-) diff --git a/src/Nazara/Renderer/RenderWindow.cpp b/src/Nazara/Renderer/RenderWindow.cpp index 367399c09..736cadffb 100644 --- a/src/Nazara/Renderer/RenderWindow.cpp +++ b/src/Nazara/Renderer/RenderWindow.cpp @@ -14,28 +14,14 @@ NzRenderWindow::NzRenderWindow(NzVideoMode mode, const NzString& title, nzUInt32 style, const NzContextParameters& parameters) { + NzErrorFlags flags(nzErrorFlag_ThrowException, true); Create(mode, title, style, parameters); - - #ifdef NAZARA_DEBUG - if (!m_impl) - { - NazaraError("Failed to create render window"); - throw std::runtime_error("Constructor failed"); - } - #endif } NzRenderWindow::NzRenderWindow(NzWindowHandle handle, const NzContextParameters& parameters) { + NzErrorFlags flags(nzErrorFlag_ThrowException, true); Create(handle, parameters); - - #ifdef NAZARA_DEBUG - if (!m_impl) - { - NazaraError("Failed to create render window"); - throw std::runtime_error("Constructor failed"); - } - #endif } NzRenderWindow::~NzRenderWindow() diff --git a/src/Nazara/Utility/Buffer.cpp b/src/Nazara/Utility/Buffer.cpp index 6bf62d6d0..18d4e0583 100644 --- a/src/Nazara/Utility/Buffer.cpp +++ b/src/Nazara/Utility/Buffer.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -32,15 +33,8 @@ NzBuffer::NzBuffer(nzBufferType type, unsigned int size, nzBufferStorage storage m_type(type), m_impl(nullptr) { + NzErrorFlags flags(nzErrorFlag_ThrowException, true); Create(size, storage, usage); - - #ifdef NAZARA_DEBUG - if (!m_impl) - { - NazaraError("Failed to create buffer"); - throw std::runtime_error("Constructor failed"); - } - #endif } NzBuffer::~NzBuffer() diff --git a/src/Nazara/Utility/Window.cpp b/src/Nazara/Utility/Window.cpp index 00b01a0f5..d9780579e 100644 --- a/src/Nazara/Utility/Window.cpp +++ b/src/Nazara/Utility/Window.cpp @@ -45,15 +45,8 @@ m_waitForEvent(false) m_impl(nullptr) #endif { + NzErrorFlags flags(nzErrorFlag_ThrowException, true); Create(mode, title, style); - - #ifdef NAZARA_DEBUG - if (!m_impl) - { - NazaraError("Failed to create window"); - throw std::runtime_error("Constructor failed"); - } - #endif } NzWindow::NzWindow(NzWindowHandle handle) : @@ -65,15 +58,8 @@ m_waitForEvent(false) m_impl(nullptr) #endif { + NzErrorFlags flags(nzErrorFlag_ThrowException, true); Create(handle); - - #ifdef NAZARA_DEBUG - if (!m_impl) - { - NazaraError("Failed to create window"); - throw std::runtime_error("Constructor failed"); - } - #endif } NzWindow::~NzWindow() From e76b57e12002f163b8bdd4bd5169beccc77b157d Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 18 Aug 2014 17:19:09 +0200 Subject: [PATCH 037/233] Fixed Image level computation Array depth will no longer be taked in consideration when computing level count Former-commit-id: 93bf114127b5e252c3f8a8cbf938fcd09534a9ca --- include/Nazara/Utility/Image.hpp | 1 + src/Nazara/Utility/Image.cpp | 29 ++++++++++++++++++++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/include/Nazara/Utility/Image.hpp b/include/Nazara/Utility/Image.hpp index 2234b7c3e..0b83022bc 100644 --- a/include/Nazara/Utility/Image.hpp +++ b/include/Nazara/Utility/Image.hpp @@ -109,6 +109,7 @@ class NAZARA_API NzImage : public NzResource static void Copy(nzUInt8* destination, const nzUInt8* source, nzUInt8 bpp, unsigned int width, unsigned int height, unsigned int depth = 1, unsigned int dstWidth = 0, unsigned int dstHeight = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0); static nzUInt8 GetMaxLevel(unsigned int width, unsigned int height, unsigned int depth = 1); + static nzUInt8 GetMaxLevel(nzImageType type, unsigned int width, unsigned int height, unsigned int depth = 1); struct SharedImage { diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index a6ceaf41a..5eb826e6c 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -271,7 +271,7 @@ bool NzImage::Create(nzImageType type, nzPixelFormat format, unsigned int width, } #endif - levelCount = std::min(levelCount, GetMaxLevel(width, height, depth)); + levelCount = std::min(levelCount, GetMaxLevel(type, width, height, depth)); nzUInt8** levels = new nzUInt8*[levelCount]; @@ -673,7 +673,7 @@ nzUInt8 NzImage::GetLevelCount() const nzUInt8 NzImage::GetMaxLevel() const { - return GetMaxLevel(m_sharedImage->width, m_sharedImage->height, m_sharedImage->depth); + return GetMaxLevel(m_sharedImage->type, m_sharedImage->width, m_sharedImage->height, m_sharedImage->depth); } NzColor NzImage::GetPixelColor(unsigned int x, unsigned int y, unsigned int z) const @@ -1003,7 +1003,7 @@ void NzImage::SetLevelCount(nzUInt8 levelCount) } #endif - levelCount = std::min(levelCount, GetMaxLevel(m_sharedImage->width, m_sharedImage->height, m_sharedImage->depth)); + levelCount = std::min(levelCount, GetMaxLevel()); if (m_sharedImage->levelCount == levelCount) return; @@ -1287,6 +1287,29 @@ nzUInt8 NzImage::GetMaxLevel(unsigned int width, unsigned int height, unsigned i return std::max(std::max(std::max(widthLevel, heightLevel), depthLevel), 1U); } +nzUInt8 NzImage::GetMaxLevel(nzImageType type, unsigned int width, unsigned int height, unsigned int depth) +{ + // Pour éviter que la profondeur ne soit comptée dans le calcul des niveaux + switch (type) + { + case nzImageType_1D: + case nzImageType_1D_Array: + return GetMaxLevel(width, 1U, 1U); + + case nzImageType_2D: + case nzImageType_2D_Array: + case nzImageType_Cubemap: + return GetMaxLevel(width, height, 1U); + + case nzImageType_3D: + return GetMaxLevel(width, height, depth); + } + + NazaraError("Image type not handled (0x" + NzString::Number(type, 16) + ')'); + return 0; + +} + void NzImage::EnsureOwnership() { if (m_sharedImage == &emptyImage) From 726611183433e420878492fef98a08199d25982b Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 18 Aug 2014 17:20:14 +0200 Subject: [PATCH 038/233] Fixed missing include Former-commit-id: c63f03fa2233f3d5ac0cd24cb796c48693c0ff39 --- src/Nazara/Renderer/RenderWindow.cpp | 3 +++ src/Nazara/Utility/Window.cpp | 1 + 2 files changed, 4 insertions(+) diff --git a/src/Nazara/Renderer/RenderWindow.cpp b/src/Nazara/Renderer/RenderWindow.cpp index 736cadffb..44e0fdf89 100644 --- a/src/Nazara/Renderer/RenderWindow.cpp +++ b/src/Nazara/Renderer/RenderWindow.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -12,6 +13,8 @@ #include #include +///TODO: Améliorer les méthode CopyTo* + NzRenderWindow::NzRenderWindow(NzVideoMode mode, const NzString& title, nzUInt32 style, const NzContextParameters& parameters) { NzErrorFlags flags(nzErrorFlag_ThrowException, true); diff --git a/src/Nazara/Utility/Window.cpp b/src/Nazara/Utility/Window.cpp index d9780579e..aa84c3607 100644 --- a/src/Nazara/Utility/Window.cpp +++ b/src/Nazara/Utility/Window.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include From ad0fa61cdfcf5cf3ce4ee3625946adb0e7461dbc Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 18 Aug 2014 17:42:08 +0200 Subject: [PATCH 039/233] Added error check Also "fixed" some error messages Former-commit-id: 15be3887949e9bafab49c3f4e16ffc732f352c65 --- src/Nazara/Utility/Image.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index 5eb826e6c..d9ba58cb7 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -227,13 +227,13 @@ bool NzImage::Create(nzImageType type, nzPixelFormat format, unsigned int width, case nzImageType_1D: if (height > 1) { - NazaraError("1D textures must be 1 height"); + NazaraError("1D textures must be 1 tall"); return false; } if (depth > 1) { - NazaraError("1D textures must be 1 depth"); + NazaraError("1D textures must be 1 deep"); return false; } break; @@ -242,7 +242,7 @@ bool NzImage::Create(nzImageType type, nzPixelFormat format, unsigned int width, case nzImageType_2D: if (depth > 1) { - NazaraError("2D textures must be 1 depth"); + NazaraError("2D textures must be 1 deep"); return false; } break; @@ -254,7 +254,7 @@ bool NzImage::Create(nzImageType type, nzPixelFormat format, unsigned int width, case nzImageType_Cubemap: if (depth > 1) { - NazaraError("Cubemaps must be 1 depth"); + NazaraError("Cubemaps must be 1 deep"); return false; } @@ -883,6 +883,13 @@ bool NzImage::LoadCubemapFromImage(const NzImage& image, const NzCubemapParams& NazaraError("Image must be valid"); return false; } + + nzImageType type = image.GetType(); + if (type != nzImageType_2D) + { + NazaraError("Image type not handled (0x" + NzString::Number(type, 16) + ')'); + return false; + } #endif unsigned int width = image.GetWidth(); From 2a29dcf6e94fd37113f5e313a0661ff52d7e3d06 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 18 Aug 2014 17:59:06 +0200 Subject: [PATCH 040/233] Improved Texture class code Removed some code duplication Former-commit-id: affa0bf18ea317b3276a7e8d0a6351f28037dfba --- src/Nazara/Renderer/Texture.cpp | 106 +++++--------------------------- 1 file changed, 16 insertions(+), 90 deletions(-) diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index c534f5cdd..3bce66404 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -661,122 +661,50 @@ bool NzTexture::LoadFromStream(NzInputStream& stream, const NzImageParams& param bool NzTexture::LoadCubemapFromFile(const NzString& filePath, const NzImageParams& imageParams, bool generateMipmaps, const NzCubemapParams& cubemapParams) { - NzImage image; - if (!image.LoadFromFile(filePath, imageParams)) + NzImage cubemap; + if (!cubemap.LoadCubemapFromFile(filePath, imageParams, cubemapParams)) { - NazaraError("Failed to load image"); + NazaraError("Failed to load cubemap"); return false; } - return LoadCubemapFromImage(image, generateMipmaps, cubemapParams); + return LoadFromImage(cubemap, generateMipmaps); } bool NzTexture::LoadCubemapFromImage(const NzImage& image, bool generateMipmaps, const NzCubemapParams& params) { - // Implémentation presque identique à celle de Image::LoadCubemapFromImage - #if NAZARA_UTILITY_SAFE - if (!image.IsValid()) + NzImage cubemap; + if (!cubemap.LoadCubemapFromImage(image, params)) { - NazaraError("Image must be valid"); - return false; - } - #endif - - unsigned int width = image.GetWidth(); - unsigned int height = image.GetHeight(); - unsigned int faceSize = (params.faceSize == 0) ? std::max(width, height)/4 : params.faceSize; - - // Sans cette vérification, celles des rectangles pourrait réussir via un overflow - if (width < faceSize || height < faceSize) - { - NazaraError("Image is too small for this face size"); + NazaraError("Failed to load cubemap"); return false; } - // Calcul et vérification des surfaces - unsigned limitX = width - faceSize; - unsigned limitY = height - faceSize; - - NzVector2ui backPos = params.backPosition * faceSize; - if (backPos.x > limitX || backPos.y > limitY) - { - NazaraError("Back rectangle is out of image"); - return false; - } - - NzVector2ui downPos = params.downPosition * faceSize; - if (downPos.x > limitX || downPos.y > limitY) - { - NazaraError("Down rectangle is out of image"); - return false; - } - - NzVector2ui forwardPos = params.forwardPosition * faceSize; - if (forwardPos.x > limitX || forwardPos.y > limitY) - { - NazaraError("Forward rectangle is out of image"); - return false; - } - - NzVector2ui leftPos = params.leftPosition * faceSize; - if (leftPos.x > limitX || leftPos.y > limitY) - { - NazaraError("Left rectangle is out of image"); - return false; - } - - NzVector2ui rightPos = params.rightPosition * faceSize; - if (rightPos.x > limitX || rightPos.y > limitY) - { - NazaraError("Right rectangle is out of image"); - return false; - } - - NzVector2ui upPos = params.upPosition * faceSize; - if (upPos.x > limitX || upPos.y > limitY) - { - NazaraError("Up rectangle is out of image"); - return false; - } - - if (!Create(nzImageType_Cubemap, image.GetFormat(), faceSize, faceSize, 1, (generateMipmaps) ? 0xFF : 1)) - { - NazaraError("Failed to create texture"); - return false; - } - - UpdateFace(nzCubemapFace_NegativeX, image.GetConstPixels(leftPos.x, leftPos.y), width, height); - UpdateFace(nzCubemapFace_NegativeY, image.GetConstPixels(downPos.x, downPos.y), width, height); - UpdateFace(nzCubemapFace_NegativeZ, image.GetConstPixels(backPos.x, backPos.y), width, height); - UpdateFace(nzCubemapFace_PositiveX, image.GetConstPixels(rightPos.x, rightPos.y), width, height); - UpdateFace(nzCubemapFace_PositiveY, image.GetConstPixels(upPos.x, upPos.y), width, height); - UpdateFace(nzCubemapFace_PositiveZ, image.GetConstPixels(forwardPos.x, forwardPos.y), width, height); - - return true; + return LoadFromImage(cubemap, generateMipmaps); } bool NzTexture::LoadCubemapFromMemory(const void* data, std::size_t size, const NzImageParams& imageParams, bool generateMipmaps, const NzCubemapParams& cubemapParams) { - NzImage image; - if (!image.LoadFromMemory(data, size, imageParams)) + NzImage cubemap; + if (!cubemap.LoadCubemapFromMemory(data, size, imageParams, cubemapParams)) { - NazaraError("Failed to load image"); + NazaraError("Failed to load cubemap"); return false; } - return LoadCubemapFromImage(image, generateMipmaps, cubemapParams); + return LoadFromImage(cubemap, generateMipmaps); } bool NzTexture::LoadCubemapFromStream(NzInputStream& stream, const NzImageParams& imageParams, bool generateMipmaps, const NzCubemapParams& cubemapParams) { - NzImage image; - if (!image.LoadFromStream(stream, imageParams)) + NzImage cubemap; + if (!cubemap.LoadCubemapFromStream(stream, imageParams, cubemapParams)) { - NazaraError("Failed to load image"); + NazaraError("Failed to load cubemap"); return false; } - return LoadCubemapFromImage(image, generateMipmaps, cubemapParams); + return LoadFromImage(cubemap, generateMipmaps); } bool NzTexture::LoadFaceFromFile(nzCubemapFace face, const NzString& filePath, const NzImageParams& params) @@ -809,7 +737,6 @@ bool NzTexture::LoadFaceFromFile(nzCubemapFace face, const NzString& filePath, c } unsigned int faceSize = m_impl->width; - if (image.GetWidth() != faceSize || image.GetHeight() != faceSize) { NazaraError("Image size must match texture face size"); @@ -849,7 +776,6 @@ bool NzTexture::LoadFaceFromMemory(nzCubemapFace face, const void* data, std::si } unsigned int faceSize = m_impl->width; - if (image.GetWidth() != faceSize || image.GetHeight() != faceSize) { NazaraError("Image size must match texture face size"); From 8640f86f445725dee6558275bffe84b1e8d7b068 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 18 Aug 2014 18:02:36 +0200 Subject: [PATCH 041/233] Added TODO Former-commit-id: f655a6d2bb7788480536503b9370019454961e27 --- src/Nazara/Renderer/Texture.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index 3bce66404..5038ccab8 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -11,6 +11,8 @@ #include #include +///TODO: Virer les méthodes faisant référence aux faces et gérer ces dernières comme de simples niveaux de profondeurs (malgré OpenGL) + struct NzTextureImpl { GLuint id; From 0d692679922034080858d845f00cb47b3f86a9c3 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 18 Aug 2014 18:13:30 +0200 Subject: [PATCH 042/233] Added Image::LoadArrayFrom* (convert an atlas to an array) Also added Texture::LoadArrayFrom* shortcuts Former-commit-id: f3cde12d5b634c75de8745fa800c30749e0fe662 --- include/Nazara/Renderer/Texture.hpp | 6 ++ include/Nazara/Utility/Image.hpp | 6 ++ src/Nazara/Renderer/Texture.cpp | 48 ++++++++++++++ src/Nazara/Utility/Image.cpp | 97 +++++++++++++++++++++++++++++ 4 files changed, 157 insertions(+) diff --git a/include/Nazara/Renderer/Texture.hpp b/include/Nazara/Renderer/Texture.hpp index 53cb9e442..024216d70 100644 --- a/include/Nazara/Renderer/Texture.hpp +++ b/include/Nazara/Renderer/Texture.hpp @@ -62,6 +62,12 @@ class NAZARA_API NzTexture : public NzResource, NzNonCopyable bool LoadFromMemory(const void* data, std::size_t size, const NzImageParams& params = NzImageParams(), bool generateMipmaps = true); bool LoadFromStream(NzInputStream& stream, const NzImageParams& params = NzImageParams(), bool generateMipmaps = true); + // LoadArray + bool LoadArrayFromFile(const NzString& filePath, const NzImageParams& imageParams = NzImageParams(), bool generateMipmaps = true, const NzVector2ui& atlasSize = NzVector2ui(2, 2)); + bool LoadArrayFromImage(const NzImage& image, bool generateMipmaps = true, const NzVector2ui& atlasSize = NzVector2ui(2, 2)); + bool LoadArrayFromMemory(const void* data, std::size_t size, const NzImageParams& imageParams = NzImageParams(), bool generateMipmaps = true, const NzVector2ui& atlasSize = NzVector2ui(2, 2)); + bool LoadArrayFromStream(NzInputStream& stream, const NzImageParams& imageParams = NzImageParams(), bool generateMipmaps = true, const NzVector2ui& atlasSize = NzVector2ui(2, 2)); + // LoadCubemap bool LoadCubemapFromFile(const NzString& filePath, const NzImageParams& imageParams = NzImageParams(), bool generateMipmaps = true, const NzCubemapParams& cubemapParams = NzCubemapParams()); bool LoadCubemapFromImage(const NzImage& image, bool generateMipmaps = true, const NzCubemapParams& params = NzCubemapParams()); diff --git a/include/Nazara/Utility/Image.hpp b/include/Nazara/Utility/Image.hpp index 0b83022bc..21cefa6b3 100644 --- a/include/Nazara/Utility/Image.hpp +++ b/include/Nazara/Utility/Image.hpp @@ -91,6 +91,12 @@ class NAZARA_API NzImage : public NzResource bool LoadFromMemory(const void* data, std::size_t size, const NzImageParams& params = NzImageParams()); bool LoadFromStream(NzInputStream& stream, const NzImageParams& params = NzImageParams()); + // LoadArray + bool LoadArrayFromFile(const NzString& filePath, const NzImageParams& imageParams = NzImageParams(), const NzVector2ui& atlasSize = NzVector2ui(2, 2)); + bool LoadArrayFromImage(const NzImage& image, const NzVector2ui& atlasSize = NzVector2ui(2, 2)); + bool LoadArrayFromMemory(const void* data, std::size_t size, const NzImageParams& imageParams = NzImageParams(), const NzVector2ui& atlasSize = NzVector2ui(2, 2)); + bool LoadArrayFromStream(NzInputStream& stream, const NzImageParams& imageParams = NzImageParams(), const NzVector2ui& atlasSize = NzVector2ui(2, 2)); + // LoadCubemap bool LoadCubemapFromFile(const NzString& filePath, const NzImageParams& imageParams = NzImageParams(), const NzCubemapParams& cubemapParams = NzCubemapParams()); bool LoadCubemapFromImage(const NzImage& image, const NzCubemapParams& params = NzCubemapParams()); diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index 5038ccab8..4a5996e4e 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -661,6 +661,54 @@ bool NzTexture::LoadFromStream(NzInputStream& stream, const NzImageParams& param return LoadFromImage(image, generateMipmaps); } +bool NzTexture::LoadArrayFromFile(const NzString& filePath, const NzImageParams& imageParams, bool generateMipmaps, const NzVector2ui& atlasSize) +{ + NzImage cubemap; + if (!cubemap.LoadArrayFromFile(filePath, imageParams, atlasSize)) + { + NazaraError("Failed to load cubemap"); + return false; + } + + return LoadFromImage(cubemap, generateMipmaps); +} + +bool NzTexture::LoadArrayFromImage(const NzImage& image, bool generateMipmaps, const NzVector2ui& atlasSize) +{ + NzImage cubemap; + if (!cubemap.LoadArrayFromImage(image, atlasSize)) + { + NazaraError("Failed to load cubemap"); + return false; + } + + return LoadFromImage(cubemap, generateMipmaps); +} + +bool NzTexture::LoadArrayFromMemory(const void* data, std::size_t size, const NzImageParams& imageParams, bool generateMipmaps, const NzVector2ui& atlasSize) +{ + NzImage cubemap; + if (!cubemap.LoadArrayFromMemory(data, size, imageParams, atlasSize)) + { + NazaraError("Failed to load cubemap"); + return false; + } + + return LoadFromImage(cubemap, generateMipmaps); +} + +bool NzTexture::LoadArrayFromStream(NzInputStream& stream, const NzImageParams& imageParams, bool generateMipmaps, const NzVector2ui& atlasSize) +{ + NzImage cubemap; + if (!cubemap.LoadArrayFromStream(stream, imageParams, atlasSize)) + { + NazaraError("Failed to load cubemap"); + return false; + } + + return LoadFromImage(cubemap, generateMipmaps); +} + bool NzTexture::LoadCubemapFromFile(const NzString& filePath, const NzImageParams& imageParams, bool generateMipmaps, const NzCubemapParams& cubemapParams) { NzImage cubemap; diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index d9ba58cb7..7b963e30d 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -863,6 +863,103 @@ bool NzImage::LoadFromStream(NzInputStream& stream, const NzImageParams& params) return NzImageLoader::LoadFromStream(this, stream, params); } +// LoadArray +bool NzImage::LoadArrayFromFile(const NzString& filePath, const NzImageParams& imageParams, const NzVector2ui& atlasSize) +{ + NzImage image; + if (!image.LoadFromFile(filePath, imageParams)) + { + NazaraError("Failed to load image"); + return false; + } + + return LoadArrayFromImage(image, atlasSize); +} + +bool NzImage::LoadArrayFromImage(const NzImage& image, const NzVector2ui& atlasSize) +{ + #if NAZARA_UTILITY_SAFE + if (!image.IsValid()) + { + NazaraError("Image must be valid"); + return false; + } + + if (atlasSize.x == 0) + { + NazaraError("Atlas width must be over zero"); + return false; + } + + if (atlasSize.y == 0) + { + NazaraError("Atlas height must be over zero"); + return false; + } + #endif + + nzImageType type = image.GetType(); + + #if NAZARA_UTILITY_SAFE + if (type != nzImageType_1D && type != nzImageType_2D) + { + NazaraError("Image type not handled (0x" + NzString::Number(type, 16) + ')'); + return false; + } + #endif + + NzVector2ui imageSize(image.GetWidth(), image.GetHeight()); + + if (imageSize.x % atlasSize.x != 0) + { + NazaraWarning("Image width is not divisible by atlas width (" + NzString::Number(imageSize.x) + " mod " + NzString::Number(atlasSize.x) + " != 0)"); + } + + if (imageSize.y % atlasSize.y != 0) + { + NazaraWarning("Image height is not divisible by atlas height (" + NzString::Number(imageSize.y) + " mod " + NzString::Number(atlasSize.y) + " != 0)"); + } + + NzVector2ui faceSize = imageSize/atlasSize; + + // Selon le type de l'image de base, on va créer un array d'images 2D ou 1D + if (type == nzImageType_2D) + Create(nzImageType_2D_Array, image.GetFormat(), faceSize.x, faceSize.y); + else + Create(nzImageType_1D_Array, image.GetFormat(), faceSize.x, 1); + + unsigned int layer = 0; + for (unsigned int i = 0; i < atlasSize.x; ++i) + for (unsigned int j = 0; j < atlasSize.y; ++j) + Copy(image, NzRectui(i*faceSize.x, j*faceSize.y, faceSize.x, faceSize.y), NzVector3ui(0, 0, layer++)); + + return true; +} + +bool NzImage::LoadArrayFromMemory(const void* data, std::size_t size, const NzImageParams& imageParams, const NzVector2ui& atlasSize) +{ + NzImage image; + if (!image.LoadFromMemory(data, size, imageParams)) + { + NazaraError("Failed to load image"); + return false; + } + + return LoadArrayFromImage(image, atlasSize); +} + +bool NzImage::LoadArrayFromStream(NzInputStream& stream, const NzImageParams& imageParams, const NzVector2ui& atlasSize) +{ + NzImage image; + if (!image.LoadFromStream(stream, imageParams)) + { + NazaraError("Failed to load image"); + return false; + } + + return LoadArrayFromImage(image, atlasSize); +} + bool NzImage::LoadCubemapFromFile(const NzString& filePath, const NzImageParams& imageParams, const NzCubemapParams& cubemapParams) { NzImage image; From b3351037c7591851c7892cb1cacb5c67b0298e7a Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 18 Aug 2014 18:15:19 +0200 Subject: [PATCH 043/233] Changed some error messages Former-commit-id: e578d813dd7a8691506af080b79bc1ec99b65e3c --- src/Nazara/Graphics/Model.cpp | 2 +- src/Nazara/Renderer/Renderer.cpp | 4 ++-- src/Nazara/Utility/Animation.cpp | 2 +- src/Nazara/Utility/Skeleton.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Nazara/Graphics/Model.cpp b/src/Nazara/Graphics/Model.cpp index 8f9b85122..54e9b964f 100644 --- a/src/Nazara/Graphics/Model.cpp +++ b/src/Nazara/Graphics/Model.cpp @@ -396,7 +396,7 @@ void NzModel::SetSkinCount(unsigned int skinCount) #if NAZARA_GRAPHICS_SAFE if (skinCount == 0) { - NazaraError("Skin count must be over 0"); + NazaraError("Skin count must be over zero"); return; } #endif diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index cead125a6..c219f9c62 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -375,7 +375,7 @@ void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPr if (instanceCount == 0) { - NazaraError("Instance count must be over 0"); + NazaraError("Instance count must be over zero"); return; } @@ -470,7 +470,7 @@ void NzRenderer::DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitive if (instanceCount == 0) { - NazaraError("Instance count must be over 0"); + NazaraError("Instance count must be over zero"); return; } diff --git a/src/Nazara/Utility/Animation.cpp b/src/Nazara/Utility/Animation.cpp index e3fb1704e..61e325f76 100644 --- a/src/Nazara/Utility/Animation.cpp +++ b/src/Nazara/Utility/Animation.cpp @@ -48,7 +48,7 @@ bool NzAnimation::AddSequence(const NzSequence& sequence) if (sequence.frameCount == 0) { - NazaraError("Sequence frame count must be over 0"); + NazaraError("Sequence frame count must be over zero"); return false; } #endif diff --git a/src/Nazara/Utility/Skeleton.cpp b/src/Nazara/Utility/Skeleton.cpp index a58ba6a92..eeefc7d98 100644 --- a/src/Nazara/Utility/Skeleton.cpp +++ b/src/Nazara/Utility/Skeleton.cpp @@ -32,7 +32,7 @@ bool NzSkeleton::Create(unsigned int jointCount) #if NAZARA_UTILITY_SAFE if (jointCount == 0) { - NazaraError("Joint count must be over 0"); + NazaraError("Joint count must be over zero"); return false; } #endif From fd293f856495c32f0611c369db7973e209739565 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 23 Aug 2014 22:04:48 +0200 Subject: [PATCH 044/233] Fixed missing include Thanks to lepiaff Former-commit-id: 458060b52bbc74f632bfa8bef643d22e780a4a8f --- include/Nazara/Utility/Event.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/Nazara/Utility/Event.hpp b/include/Nazara/Utility/Event.hpp index 50062e7b5..723866011 100644 --- a/include/Nazara/Utility/Event.hpp +++ b/include/Nazara/Utility/Event.hpp @@ -9,6 +9,7 @@ #ifndef NAZARA_EVENT_HPP #define NAZARA_EVENT_HPP +#include #include #include From 71406eb6df7ff45069a7d3d12a60557bc23737fa Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 25 Aug 2014 20:20:02 +0200 Subject: [PATCH 045/233] Fixed array creation Former-commit-id: 21c8018a7eb82f96e14a11485adaecfbfe19d5e7 --- src/Nazara/Utility/Image.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index 7b963e30d..d59e3a4c6 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -922,15 +922,17 @@ bool NzImage::LoadArrayFromImage(const NzImage& image, const NzVector2ui& atlasS NzVector2ui faceSize = imageSize/atlasSize; + unsigned int layerCount = atlasSize.x*atlasSize.y; + // Selon le type de l'image de base, on va créer un array d'images 2D ou 1D if (type == nzImageType_2D) - Create(nzImageType_2D_Array, image.GetFormat(), faceSize.x, faceSize.y); + Create(nzImageType_2D_Array, image.GetFormat(), faceSize.x, faceSize.y, layerCount); else - Create(nzImageType_1D_Array, image.GetFormat(), faceSize.x, 1); + Create(nzImageType_1D_Array, image.GetFormat(), faceSize.x, layerCount); unsigned int layer = 0; - for (unsigned int i = 0; i < atlasSize.x; ++i) - for (unsigned int j = 0; j < atlasSize.y; ++j) + for (unsigned int j = 0; j < atlasSize.y; ++j) + for (unsigned int i = 0; i < atlasSize.x; ++i) Copy(image, NzRectui(i*faceSize.x, j*faceSize.y, faceSize.x, faceSize.y), NzVector3ui(0, 0, layer++)); return true; From 6e27acc492ba517f8f86a888be9ce82e6351be54 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 25 Aug 2014 20:22:10 +0200 Subject: [PATCH 046/233] Added Color vertex component Removed Userdata4 vertex component to keep the count to sixteen Former-commit-id: b048f11f44528d1cf6657d095768b188217421ba --- include/Nazara/Utility/Enums.hpp | 9 +++++---- src/Nazara/Renderer/OpenGL.cpp | 12 ++++++------ src/Nazara/Renderer/Shader.cpp | 2 +- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/include/Nazara/Utility/Enums.hpp b/include/Nazara/Utility/Enums.hpp index 52bc9cba6..25e09c10a 100644 --- a/include/Nazara/Utility/Enums.hpp +++ b/include/Nazara/Utility/Enums.hpp @@ -221,12 +221,14 @@ enum nzVertexComponent { nzVertexComponent_Unused = -1, + // Nous nous limitons à 16 composants de sommets car c'est le minimum supporté par le GPU nzVertexComponent_InstanceData0, nzVertexComponent_InstanceData1, nzVertexComponent_InstanceData2, nzVertexComponent_InstanceData3, nzVertexComponent_InstanceData4, nzVertexComponent_InstanceData5, + nzVertexComponent_Color, nzVertexComponent_Normal, nzVertexComponent_Position, nzVertexComponent_Tangent, @@ -236,14 +238,13 @@ enum nzVertexComponent nzVertexComponent_Userdata2, nzVertexComponent_Userdata3, nzVertexComponent_Userdata4, - nzVertexComponent_Userdata5, nzVertexComponent_FirstInstanceData = nzVertexComponent_InstanceData0, - nzVertexComponent_FirstVertexData = nzVertexComponent_Normal, + nzVertexComponent_FirstVertexData = nzVertexComponent_Color, nzVertexComponent_LastInstanceData = nzVertexComponent_InstanceData5, - nzVertexComponent_LastVertexData = nzVertexComponent_Userdata5, + nzVertexComponent_LastVertexData = nzVertexComponent_Userdata4, - nzVertexComponent_Max = nzVertexComponent_Userdata5 + nzVertexComponent_Max = nzVertexComponent_Userdata4 }; enum nzVertexLayout diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index a34dce25b..476800edf 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -2104,16 +2104,16 @@ nzUInt8 NzOpenGL::VertexComponentIndex[] = 13, // nzVertexComponent_InstanceData3 14, // nzVertexComponent_InstanceData4 15, // nzVertexComponent_InstanceData5 + 4, // nzVertexComponent_Color 2, // nzVertexComponent_Normal 0, // nzVertexComponent_Position 3, // nzVertexComponent_Tangent 1, // nzVertexComponent_TexCoord - 4, // nzVertexComponent_Userdata0 - 5, // nzVertexComponent_Userdata1 - 6, // nzVertexComponent_Userdata2 - 7, // nzVertexComponent_Userdata3 - 8, // nzVertexComponent_Userdata4 - 9 // nzVertexComponent_Userdata5 + 5, // nzVertexComponent_Userdata0 + 6, // nzVertexComponent_Userdata1 + 7, // nzVertexComponent_Userdata2 + 8, // nzVertexComponent_Userdata3 + 9 // nzVertexComponent_Userdata4 }; static_assert(nzVertexComponent_Max+1 == 16, "Attribute index array is incomplete"); diff --git a/src/Nazara/Renderer/Shader.cpp b/src/Nazara/Renderer/Shader.cpp index 699e36442..7729c1035 100644 --- a/src/Nazara/Renderer/Shader.cpp +++ b/src/Nazara/Renderer/Shader.cpp @@ -155,6 +155,7 @@ bool NzShader::Create() glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_InstanceData3], "InstanceData3"); glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_InstanceData4], "InstanceData4"); glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_InstanceData5], "InstanceData5"); + glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Color], "VertexColor"); glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Normal], "VertexNormal"); glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Position], "VertexPosition"); glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Tangent], "VertexTangent"); @@ -164,7 +165,6 @@ bool NzShader::Create() glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Userdata2], "VertexUserdata2"); glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Userdata3], "VertexUserdata3"); glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Userdata4], "VertexUserdata4"); - glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Userdata5], "VertexUserdata5"); if (NzRenderer::HasCapability(nzRendererCap_MultipleRenderTargets)) { From 9b1f63ce1130227c11d7a46006e9dcbc5151f58c Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 25 Aug 2014 20:23:00 +0200 Subject: [PATCH 047/233] Fixed possible bug Former-commit-id: 3ce9541e99d91140547ed8b60297d3d3785a0630 --- include/Nazara/Graphics/Material.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index c381beb3a..0f41e0f39 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -135,7 +135,7 @@ class NAZARA_API NzMaterial : public NzResource struct ShaderInstance { const NzShader* shader; - NzUberShaderInstance* uberInstance; + NzUberShaderInstance* uberInstance = nullptr; int uniforms[nzMaterialUniform_Max+1]; }; From 98aa804de525cec0f5be462b4d0056dea6f9ddf1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 25 Aug 2014 22:37:36 +0200 Subject: [PATCH 048/233] Flipped texture coordinates Nazara now use a top-left corner origin for UVs (DirectX-like) Former-commit-id: 550dd76cf15bc731d1e23060d1af15c3cd5cb4fd --- examples/FirstScene/main.cpp | 4 +++ include/Nazara/Utility/Mesh.hpp | 3 ++ src/Nazara/Graphics/Loaders/OBJ/Loader.cpp | 2 +- src/Nazara/Renderer/Texture.cpp | 36 ++++++------------- src/Nazara/Utility/Loaders/MD2/Loader.cpp | 5 ++- src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp | 7 ++-- 6 files changed, 24 insertions(+), 33 deletions(-) diff --git a/examples/FirstScene/main.cpp b/examples/FirstScene/main.cpp index 65f948375..62a4425c8 100644 --- a/examples/FirstScene/main.cpp +++ b/examples/FirstScene/main.cpp @@ -95,6 +95,10 @@ int main() // Ce paramètre sert à indiquer la mise à l'échelle désirée lors du chargement du modèle. params.mesh.scale.Set(0.01f); // Un centième de la taille originelle + // Les UVs de ce fichier sont retournées (repère OpenGL, origine coin bas-gauche) par rapport à ce que le moteur attend + // Nous devons dire au moteur de les retourner lors du chargement + params.mesh.flipUVs = true; + // On charge ensuite le modèle depuis son fichier // Le moteur va charger le fichier et essayer de retrouver les fichiers associés (comme les matériaux, textures, ...) if (!spaceship.LoadFromFile("resources/Spaceship/spaceship.obj", params)) diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp index 8c2036f05..116bbc3e7 100644 --- a/include/Nazara/Utility/Mesh.hpp +++ b/include/Nazara/Utility/Mesh.hpp @@ -36,6 +36,9 @@ struct NAZARA_API NzMeshParams // Faut-il centrer le mesh autour de l'origine ? bool center = false; + // Faut-il retourner les UV ? + bool flipUVs = false; + // Faut-il optimiser les index buffers ? (Rendu plus rapide, mais le chargement dure plus longtemps) bool optimizeIndexBuffers = true; diff --git a/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp b/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp index 449a82f2f..07c1742ec 100644 --- a/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp +++ b/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp @@ -142,7 +142,7 @@ namespace if (index >= 0) { const NzVector3f& uvw = texCoords[index]; - vertex.uv.Set(uvw.x, uvw.y); + vertex.uv.Set(uvw.x, (parameters.mesh.flipUVs) ? 1.f - uvw.y : uvw.y); // Inversion des UVs si demandé } else hasTexCoords = false; diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index 4a5996e4e..e19ef2bbf 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -1048,33 +1048,25 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int s return false; } - nzUInt8 bpp = NzPixelFormat::GetBytesPerPixel(m_impl->format); - - unsigned int size = box.width*box.height*box.depth*bpp; - std::unique_ptr flipped(new nzUInt8[size]); - NzImage::Copy(flipped.get(), pixels, bpp, box.width, box.height, box.depth, 0, 0, srcWidth, srcHeight); - - // Inversion de la texture pour le repère d'OpenGL - if (!NzPixelFormat::Flip(nzPixelFlipping_Horizontally, m_impl->format, box.width, box.height, box.depth, flipped.get(), flipped.get())) - NazaraWarning("Failed to flip image"); - - SetUnpackAlignement(bpp); + SetUnpackAlignement(NzPixelFormat::GetBytesPerPixel(m_impl->format)); + glPixelStorei(GL_UNPACK_ROW_LENGTH, srcWidth); + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, srcHeight); NzOpenGL::BindTexture(m_impl->type, m_impl->id); switch (m_impl->type) { case nzImageType_1D: - glTexSubImage1D(GL_TEXTURE_1D, level, box.x, box.width, format.dataFormat, format.dataType, flipped.get()); + glTexSubImage1D(GL_TEXTURE_1D, level, box.x, box.width, format.dataFormat, format.dataType, pixels); break; case nzImageType_1D_Array: case nzImageType_2D: - glTexSubImage2D(NzOpenGL::TextureTarget[m_impl->type], level, box.x, height-box.height-box.y, box.width, box.height, format.dataFormat, format.dataType, flipped.get()); + glTexSubImage2D(NzOpenGL::TextureTarget[m_impl->type], level, box.x, height-box.height-box.y, box.width, box.height, format.dataFormat, format.dataType, pixels); break; case nzImageType_2D_Array: case nzImageType_3D: - glTexSubImage3D(NzOpenGL::TextureTarget[m_impl->type], level, box.x, height-box.height-box.y, box.z, box.width, box.height, box.depth, format.dataFormat, format.dataType, flipped.get()); + glTexSubImage3D(NzOpenGL::TextureTarget[m_impl->type], level, box.x, height-box.height-box.y, box.z, box.width, box.height, box.depth, format.dataFormat, format.dataType, pixels); break; case nzImageType_Cubemap: @@ -1192,20 +1184,12 @@ bool NzTexture::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRe return false; } - nzUInt8 bpp = NzPixelFormat::GetBytesPerPixel(m_impl->format); - - // Inversion de la texture pour le repère d'OpenGL - unsigned int size = rect.width*rect.height*bpp; - std::unique_ptr flipped(new nzUInt8[size]); - NzImage::Copy(flipped.get(), pixels, bpp, rect.width, rect.height, 1, 0, 0, srcWidth, srcHeight); - - if (!NzPixelFormat::Flip(nzPixelFlipping_Horizontally, m_impl->format, rect.width, rect.height, 1, flipped.get(), flipped.get())) - NazaraWarning("Failed to flip image"); - - SetUnpackAlignement(bpp); + SetUnpackAlignement(NzPixelFormat::GetBytesPerPixel(m_impl->format)); + glPixelStorei(GL_UNPACK_ROW_LENGTH, srcWidth); + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, srcHeight); NzOpenGL::BindTexture(m_impl->type, m_impl->id); - glTexSubImage2D(NzOpenGL::CubemapFace[face], level, rect.x, height-rect.height-rect.y, rect.width, rect.height, format.dataFormat, format.dataType, flipped.get()); + glTexSubImage2D(NzOpenGL::CubemapFace[face], level, rect.x, height-rect.height-rect.y, rect.width, rect.height, format.dataFormat, format.dataType, pixels); return true; } diff --git a/src/Nazara/Utility/Loaders/MD2/Loader.cpp b/src/Nazara/Utility/Loaders/MD2/Loader.cpp index 693711f75..f57c53340 100644 --- a/src/Nazara/Utility/Loaders/MD2/Loader.cpp +++ b/src/Nazara/Utility/Loaders/MD2/Loader.cpp @@ -200,7 +200,10 @@ namespace { const unsigned int fixedIndex = indexFix[j]; const MD2_TexCoord& texC = texCoords[triangles[i].texCoords[fixedIndex]]; - vertex[triangles[i].vertices[fixedIndex]].uv.Set(static_cast(texC.u) / header.skinwidth, 1.f - static_cast(texC.v)/header.skinheight); + float u = static_cast(texC.u) / header.skinwidth; + float v = static_cast(texC.v) / header.skinheight; + + vertex[triangles[i].vertices[fixedIndex]].uv.Set(u, (parameters.flipUVs) ? 1.f - v : v); } } diff --git a/src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp b/src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp index 8b0a88802..b2b518dae 100644 --- a/src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp +++ b/src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp @@ -178,10 +178,7 @@ namespace } vertices->position = finalPos; - - // Le format MD5 spécifie ses UV avec l'origine en bas à gauche, contrairement au moteur - // dont l'origine est en haut à gauche, nous inversons donc la valeur en Y. - vertices->uv.Set(vertex.uv.x, 1.f - vertex.uv.y); + vertices->uv.Set(vertex.uv.x, (parameters.flipUVs) ? 1.f - vertex.uv.y : vertex.uv.y); // Inversion des UV si demandé vertices++; } @@ -271,7 +268,7 @@ namespace // On retourne le modèle dans le bon sens vertex->position = scale * (rotationQuat * finalPos); - vertex->uv.Set(md5Vertex.uv.x, 1.f - md5Vertex.uv.y); + vertex->uv.Set(md5Vertex.uv.x, (parameters.flipUVs) ? 1.f - md5Vertex.uv.y : md5Vertex.uv.y); // Inversion des UV si demandé vertex++; } From 18cf2351721fb94f3540d6fe620114e20180d4f6 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Wed, 27 Aug 2014 14:30:22 +0200 Subject: [PATCH 049/233] Update of two headers Former-commit-id: 813c36932bf842d6ad6c26aace9249894359c8de --- include/Nazara/Core.hpp | 1 + include/Nazara/Math.hpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Core.hpp b/include/Nazara/Core.hpp index bccbcaad6..71c845bfc 100644 --- a/include/Nazara/Core.hpp +++ b/include/Nazara/Core.hpp @@ -54,6 +54,7 @@ #include #include #include +#include #include #include #include diff --git a/include/Nazara/Math.hpp b/include/Nazara/Math.hpp index e70158c4a..b80211a25 100644 --- a/include/Nazara/Math.hpp +++ b/include/Nazara/Math.hpp @@ -30,7 +30,7 @@ #ifndef NAZARA_GLOBAL_MATH_HPP #define NAZARA_GLOBAL_MATH_HPP -#include +#include #include #include #include From fc4d84f206db74fa40725d66c7ec707669c50551 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Wed, 27 Aug 2014 14:34:35 +0200 Subject: [PATCH 050/233] Littles fixes -Light Manager: I prefer iterators -OpenGL: The UV problem is solved, but you forget to change the cubemaps -Texture: GetSize() could return a int instead a NzVector2ui -Algorithm: Simplification -Utility: Couldn't compile Former-commit-id: db890711b451d03427871fb997549a1b13c7d80a --- src/Nazara/Graphics/LightManager.cpp | 6 +++--- src/Nazara/Renderer/OpenGL.cpp | 4 ++-- src/Nazara/Renderer/Texture.cpp | 2 +- src/Nazara/Utility/Algorithm.cpp | 6 ++---- src/Nazara/Utility/Utility.cpp | 2 +- 5 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/Nazara/Graphics/LightManager.cpp b/src/Nazara/Graphics/LightManager.cpp index 107a170bc..8153e7d2a 100644 --- a/src/Nazara/Graphics/LightManager.cpp +++ b/src/Nazara/Graphics/LightManager.cpp @@ -37,10 +37,10 @@ unsigned int NzLightManager::ComputeClosestLights(const NzVector3f& position, fl light.score = std::numeric_limits::max(); // Nous jouons au Golf } - for (unsigned int i = 0; i < m_lights.size(); ++i) + for (auto it = m_lights.begin(); it != m_lights.end(); ++it) { - const NzLight** lights = m_lights[i].first; - unsigned int lightCount = m_lights[i].second; + const NzLight** lights = it->first; + unsigned int lightCount = it->second; for (unsigned int j = 0; j < lightCount; ++j) { diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index 476800edf..ef9e096d9 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -1941,8 +1941,8 @@ GLenum NzOpenGL::CubemapFace[] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X, // nzCubemapFace_PositiveX GL_TEXTURE_CUBE_MAP_NEGATIVE_X, // nzCubemapFace_NegativeX - GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, // nzCubemapFace_PositiveY (Inversion pour les standards OpenGL) - GL_TEXTURE_CUBE_MAP_POSITIVE_Y, // nzCubemapFace_NegativeY (Inversion pour les standards OpenGL) + GL_TEXTURE_CUBE_MAP_POSITIVE_Y, // nzCubemapFace_PositiveY + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, // nzCubemapFace_NegativeY GL_TEXTURE_CUBE_MAP_POSITIVE_Z, // nzCubemapFace_PositiveZ GL_TEXTURE_CUBE_MAP_NEGATIVE_Z // nzCubemapFace_NegativeZ }; diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index e19ef2bbf..cb5b4ff45 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -468,7 +468,7 @@ NzVector2ui NzTexture::GetSize() const if (!m_impl) { NazaraError("Texture must be valid"); - return 0; + return NzVector2ui(0, 0); } #endif diff --git a/src/Nazara/Utility/Algorithm.cpp b/src/Nazara/Utility/Algorithm.cpp index 628444000..e22f937fa 100644 --- a/src/Nazara/Utility/Algorithm.cpp +++ b/src/Nazara/Utility/Algorithm.cpp @@ -189,11 +189,9 @@ namespace void MoveTriangleToEnd(int tri) { auto it = std::find(tri_indices.begin(), tri_indices.end(), tri); - int t_ind = (it != tri_indices.end()) ? std::distance(tri_indices.begin(), it) : -1; + NazaraAssert(it != tri_indices.end(), "Triangle not found"); - NazaraAssert(t_ind >= 0, "Triangle not found"); - - tri_indices.erase(tri_indices.begin() + t_ind, tri_indices.begin() + t_ind + 1); + tri_indices.erase(it); tri_indices.push_back(tri); } }; diff --git a/src/Nazara/Utility/Utility.cpp b/src/Nazara/Utility/Utility.cpp index df38b312c..885e4a578 100644 --- a/src/Nazara/Utility/Utility.cpp +++ b/src/Nazara/Utility/Utility.cpp @@ -146,7 +146,7 @@ unsigned int NzUtility::ComponentCount[nzComponentType_Max+1] = static_assert(nzComponentType_Max+1 == 14, "Component count array is incomplete"); -unsigned int NzUtility::ComponentStride[nzComponentType_Max+1] = +std::size_t NzUtility::ComponentStride[nzComponentType_Max+1] = { 4*sizeof(nzUInt8), // nzComponentType_Color 1*sizeof(double), // nzComponentType_Double1 From 177ed1f3c7f4ad82c28fa8d4efc24fb3ac65899f Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Wed, 27 Aug 2014 14:40:19 +0200 Subject: [PATCH 051/233] Writing style file Add of a file for the standard writing in the project. I think it could be helpful. Former-commit-id: 3c61109ce5fd558e0675bf684d66262613acbe1e --- writing style.md | 84 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 writing style.md diff --git a/writing style.md b/writing style.md new file mode 100644 index 000000000..cc6da29f7 --- /dev/null +++ b/writing style.md @@ -0,0 +1,84 @@ +Examples writing-style: + +Alphabetical order for everything and try to regroup each methods beginning with the same letter in the header + +Class header: + +// Copyright (C) 2014 AUTHOR +// This file is part of the "Nazara Engine - MODULE module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_FILENAME_HPP +#define NAZARA_FILENAME_HPP + +#include +#include +#include + +struct NzPossibleImplementation; + +class NAZARA_API NzClassName +{ + friend NzClassFriend; + + public: + Constructors(); + Destructor(); + + FunctionInAClass(); + + protected: + + private: + NzClass m_variableName; + STL m_variableName; + dataType m_variableName; + + NzPossibleImplementation* m_impl; +}; + +#endif // NAZARA_FILENAME_HPP + +Class source: + +// Copyright (C) 2014 AUTHOR +// This file is part of the "Nazara Engine - MODULE module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include + +struct NzPossibleImplementation {}; + +NzClassName::Constructors() : +m_variableName(init) +{ + testsAndOtherInits; +} + +NzClassName::PublicFunctions() +NzClassName::ProtectedFunctions() +NzClassName::PrivateFunctions() + +Structure: + +/!\ enum in Enums.hpp + +enum nzEnum +{ + nzEnum_1, + nzEnum_2, + + nzEnum_Max = nzEnum_2 +}; + +Function: + +FunctionName() +{ + variableName = init; +} \ No newline at end of file From ea43edbaf346306483298f59ea0c72b9a788c2d9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 31 Aug 2014 14:09:43 +0200 Subject: [PATCH 052/233] Separated ParticleEmitter Renamed ParticleEmitter to ParticleSystem Added class ParticleEmitter (First implementation, this will probably change) Former-commit-id: a1f80db340983da5e85cedc974dd6b24a98e25b0 --- .../Nazara/Graphics/ParticleController.hpp | 4 +- include/Nazara/Graphics/ParticleEmitter.hpp | 80 +--- include/Nazara/Graphics/ParticleGenerator.hpp | 4 +- include/Nazara/Graphics/ParticleRenderer.hpp | 4 +- include/Nazara/Graphics/ParticleSystem.hpp | 95 +++++ src/Nazara/Graphics/ParticleEmitter.cpp | 379 ++---------------- src/Nazara/Graphics/ParticleSystem.cpp | 366 +++++++++++++++++ 7 files changed, 508 insertions(+), 424 deletions(-) create mode 100644 include/Nazara/Graphics/ParticleSystem.hpp create mode 100644 src/Nazara/Graphics/ParticleSystem.cpp diff --git a/include/Nazara/Graphics/ParticleController.hpp b/include/Nazara/Graphics/ParticleController.hpp index 4456bcc28..eddea25f7 100644 --- a/include/Nazara/Graphics/ParticleController.hpp +++ b/include/Nazara/Graphics/ParticleController.hpp @@ -12,8 +12,8 @@ #include class NzParticleController; -class NzParticleEmitter; class NzParticleMapper; +class NzParticleSystem; using NzParticleControllerConstRef = NzResourceRef; using NzParticleControllerRef = NzResourceRef; @@ -25,7 +25,7 @@ class NAZARA_API NzParticleController : public NzResource NzParticleController(const NzParticleController& controller); virtual ~NzParticleController(); - virtual void Apply(NzParticleEmitter& emitter, NzParticleMapper& mapper, unsigned int startId, unsigned int endId, float elapsedTime) = 0; + virtual void Apply(NzParticleSystem& system, NzParticleMapper& mapper, unsigned int startId, unsigned int endId, float elapsedTime) = 0; }; #endif // NAZARA_PARTICLECONTROLLER_HPP diff --git a/include/Nazara/Graphics/ParticleEmitter.hpp b/include/Nazara/Graphics/ParticleEmitter.hpp index ac85c9480..5e73426d5 100644 --- a/include/Nazara/Graphics/ParticleEmitter.hpp +++ b/include/Nazara/Graphics/ParticleEmitter.hpp @@ -8,92 +8,36 @@ #define NAZARA_PARTICLEEMITTER_HPP #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include -class NAZARA_API NzParticleEmitter : public NzSceneNode, NzUpdatable +class NzParticleMapper; +class NzParticleSystem; + +class NAZARA_API NzParticleEmitter : public NzNode { public: - NzParticleEmitter(unsigned int maxParticleCount, nzParticleLayout layout); - NzParticleEmitter(unsigned int maxParticleCount, NzParticleDeclaration* declaration); - NzParticleEmitter(const NzParticleEmitter& emitter); + NzParticleEmitter(); + NzParticleEmitter(const NzParticleEmitter& emitter) = default; NzParticleEmitter(NzParticleEmitter&& emitter) = default; - ~NzParticleEmitter(); + virtual ~NzParticleEmitter(); - void AddController(NzParticleController* controller); - void AddGenerator(NzParticleGenerator* generator); - void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const; - - void* CreateParticle(); - void* CreateParticles(unsigned int count); - - void EnableFixedStep(bool fixedStep); - - void* GenerateParticle(); - void* GenerateParticles(unsigned int count); - - const NzBoundingVolumef& GetBoundingVolume() const override; + virtual void Emit(NzParticleSystem& system, float elapsedTime) const; unsigned int GetEmissionCount() const; float GetEmissionRate() const; - float GetFixedStepSize() const; - unsigned int GetMaxParticleCount() const; - unsigned int GetParticleCount() const; - unsigned int GetParticleSize() const; - - nzSceneNodeType GetSceneNodeType() const override; - - bool IsDrawable() const; - bool IsFixedStepEnabled() const; - - void KillParticle(unsigned int index); - void KillParticles(); - - void RemoveController(NzParticleController* controller); - void RemoveGenerator(NzParticleGenerator* generator); void SetEmissionCount(unsigned int count); void SetEmissionRate(float rate); - void SetFixedStepSize(float stepSize); - void SetRenderer(NzParticleRenderer* renderer); - NzParticleEmitter& operator=(const NzParticleEmitter& emitter); + NzParticleEmitter& operator=(const NzParticleEmitter& emitter) = default; NzParticleEmitter& operator=(NzParticleEmitter&& emitter) = default; private: - void GenerateAABB() const; - void Register() override; - void ResizeBuffer(); - void Unregister() override; - void UpdateBoundingVolume() const; - void Update() override; + virtual void SetupParticles(NzParticleMapper& mapper, unsigned int count) const = 0; - std::set> m_dyingParticles; - mutable std::vector m_buffer; - std::vector m_controllers; - std::vector m_generators; - mutable NzBoundingVolumef m_boundingVolume; - NzParticleDeclarationConstRef m_declaration; - NzParticleRendererRef m_renderer; - mutable bool m_boundingVolumeUpdated; - bool m_fixedStepEnabled; - bool m_processing; - float m_emissionAccumulator; + mutable float m_emissionAccumulator; float m_emissionRate; - float m_stepAccumulator; - float m_stepSize; unsigned int m_emissionCount; - unsigned int m_maxParticleCount; - unsigned int m_particleCount; - unsigned int m_particleSize; }; #endif // NAZARA_PARTICLEEMITTER_HPP diff --git a/include/Nazara/Graphics/ParticleGenerator.hpp b/include/Nazara/Graphics/ParticleGenerator.hpp index eefb9233b..79a787c44 100644 --- a/include/Nazara/Graphics/ParticleGenerator.hpp +++ b/include/Nazara/Graphics/ParticleGenerator.hpp @@ -11,9 +11,9 @@ #include #include -class NzParticleEmitter; class NzParticleGenerator; class NzParticleMapper; +class NzParticleSystem; using NzParticleGeneratorConstRef = NzResourceRef; using NzParticleGeneratorRef = NzResourceRef; @@ -25,7 +25,7 @@ class NAZARA_API NzParticleGenerator : public NzResource NzParticleGenerator(const NzParticleGenerator& generator); virtual ~NzParticleGenerator(); - virtual void Generate(NzParticleEmitter& emitter, NzParticleMapper& mapper, unsigned int startId, unsigned int endId) = 0; + virtual void Generate(NzParticleSystem& system, NzParticleMapper& mapper, unsigned int startId, unsigned int endId) = 0; }; #endif // NAZARA_PARTICLEGENERATOR_HPP diff --git a/include/Nazara/Graphics/ParticleRenderer.hpp b/include/Nazara/Graphics/ParticleRenderer.hpp index 81219c624..4ad832310 100644 --- a/include/Nazara/Graphics/ParticleRenderer.hpp +++ b/include/Nazara/Graphics/ParticleRenderer.hpp @@ -12,9 +12,9 @@ #include class NzAbstractRenderQueue; -class NzParticleEmitter; class NzParticleMapper; class NzParticleRenderer; +class NzParticleSystem; using NzParticleRendererConstRef = NzResourceRef; using NzParticleRendererRef = NzResourceRef; @@ -26,7 +26,7 @@ class NAZARA_API NzParticleRenderer : public NzResource NzParticleRenderer(const NzParticleRenderer& renderer); virtual ~NzParticleRenderer(); - virtual void Render(const NzParticleEmitter& emitter, const NzParticleMapper& mapper, unsigned int startId, unsigned int endId, NzAbstractRenderQueue* renderQueue) = 0; + virtual void Render(const NzParticleSystem& system, const NzParticleMapper& mapper, unsigned int startId, unsigned int endId, NzAbstractRenderQueue* renderQueue) = 0; }; #endif // NAZARA_PARTICLERENDERER_HPP diff --git a/include/Nazara/Graphics/ParticleSystem.hpp b/include/Nazara/Graphics/ParticleSystem.hpp new file mode 100644 index 000000000..647d15ce0 --- /dev/null +++ b/include/Nazara/Graphics/ParticleSystem.hpp @@ -0,0 +1,95 @@ +// Copyright (C) 2014 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_PARTICLESYSTEM_HPP +#define NAZARA_PARTICLESYSTEM_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class NAZARA_API NzParticleSystem : public NzSceneNode, NzUpdatable +{ + public: + NzParticleSystem(unsigned int maxParticleCount, nzParticleLayout layout); + NzParticleSystem(unsigned int maxParticleCount, const NzParticleDeclaration* declaration); + NzParticleSystem(const NzParticleSystem& emitter); + NzParticleSystem(NzParticleSystem&& emitter) = default; + ~NzParticleSystem(); + + void AddController(NzParticleController* controller); + void AddEmitter(NzParticleEmitter* emitter); + void AddGenerator(NzParticleGenerator* generator); + void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const; + + void* CreateParticle(); + void* CreateParticles(unsigned int count); + + void EnableFixedStep(bool fixedStep); + + void* GenerateParticle(); + void* GenerateParticles(unsigned int count); + + const NzBoundingVolumef& GetBoundingVolume() const override; + const NzParticleDeclaration* GetDeclaration() const; + float GetFixedStepSize() const; + unsigned int GetMaxParticleCount() const; + unsigned int GetParticleCount() const; + unsigned int GetParticleSize() const; + nzSceneNodeType GetSceneNodeType() const override; + + bool IsDrawable() const; + bool IsFixedStepEnabled() const; + + void KillParticle(unsigned int index); + void KillParticles(); + + void RemoveController(NzParticleController* controller); + void RemoveEmitter(NzParticleEmitter* emitter); + void RemoveGenerator(NzParticleGenerator* generator); + + void SetFixedStepSize(float stepSize); + void SetRenderer(NzParticleRenderer* renderer); + + NzParticleSystem& operator=(const NzParticleSystem& emitter); + NzParticleSystem& operator=(NzParticleSystem&& emitter) = default; + + private: + void GenerateAABB() const; + void Register() override; + void ResizeBuffer(); + void Unregister() override; + void UpdateBoundingVolume() const; + void Update() override; + + std::set> m_dyingParticles; + mutable std::vector m_buffer; + std::vector m_controllers; + std::vector m_emitters; + std::vector m_generators; + mutable NzBoundingVolumef m_boundingVolume; + NzParticleDeclarationConstRef m_declaration; + NzParticleRendererRef m_renderer; + mutable bool m_boundingVolumeUpdated; + bool m_fixedStepEnabled; + bool m_processing; + float m_stepAccumulator; + float m_stepSize; + unsigned int m_maxParticleCount; + unsigned int m_particleCount; + unsigned int m_particleSize; +}; + +#endif // NAZARA_PARTICLESYSTEM_HPP diff --git a/src/Nazara/Graphics/ParticleEmitter.cpp b/src/Nazara/Graphics/ParticleEmitter.cpp index 8671091bc..46500f082 100644 --- a/src/Nazara/Graphics/ParticleEmitter.cpp +++ b/src/Nazara/Graphics/ParticleEmitter.cpp @@ -7,319 +7,22 @@ #include #include #include +#include #include #include #include -NzParticleEmitter::NzParticleEmitter(unsigned int maxParticleCount, nzParticleLayout layout) : -NzParticleEmitter(maxParticleCount, NzParticleDeclaration::Get(layout)) -{ -} - -NzParticleEmitter::NzParticleEmitter(unsigned int maxParticleCount, NzParticleDeclaration* declaration) : -m_declaration(declaration), -m_boundingVolumeUpdated(false), -m_fixedStepEnabled(false), -m_processing(false), +NzParticleEmitter::NzParticleEmitter() : m_emissionAccumulator(0.f), m_emissionRate(0.f), -m_stepAccumulator(0.f), -m_stepSize(1.f/60.f), -m_emissionCount(1), -m_maxParticleCount(maxParticleCount), -m_particleCount(0) +m_emissionCount(1) { - // En cas d'erreur, un constructeur ne peut que lancer une exception - NzErrorFlags flags(nzErrorFlag_ThrowException, true); - - m_particleSize = m_declaration->GetStride(); // La taille de chaque particule - - ResizeBuffer(); -} - -NzParticleEmitter::NzParticleEmitter(const NzParticleEmitter& emitter) : -NzSceneNode(emitter), -m_controllers(emitter.m_controllers), -m_generators(emitter.m_generators), -m_boundingVolume(emitter.m_boundingVolume), -m_declaration(emitter.m_declaration), -m_renderer(emitter.m_renderer), -m_boundingVolumeUpdated(emitter.m_boundingVolumeUpdated), -m_fixedStepEnabled(emitter.m_fixedStepEnabled), -m_processing(false), -m_emissionAccumulator(0.f), -m_emissionRate(emitter.m_emissionRate), -m_stepAccumulator(0.f), -m_stepSize(emitter.m_stepSize), -m_emissionCount(emitter.m_emissionCount), -m_maxParticleCount(emitter.m_maxParticleCount), -m_particleCount(emitter.m_particleCount), -m_particleSize(emitter.m_particleSize) -{ - NzErrorFlags flags(nzErrorFlag_ThrowException, true); - - ResizeBuffer(); - - // On ne copie que les particules vivantes - std::memcpy(m_buffer.data(), emitter.m_buffer.data(), emitter.m_particleCount*m_particleSize); } NzParticleEmitter::~NzParticleEmitter() = default; -void NzParticleEmitter::AddController(NzParticleController* controller) +void NzParticleEmitter::Emit(NzParticleSystem& system, float elapsedTime) const { - m_controllers.emplace_back(controller); -} - -void NzParticleEmitter::AddGenerator(NzParticleGenerator* generator) -{ - m_generators.emplace_back(generator); -} - -void NzParticleEmitter::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const -{ - ///FIXME: Vérifier le renderer - if (m_particleCount > 0) - { - NzParticleMapper mapper(m_buffer.data(), m_declaration); - m_renderer->Render(*this, mapper, 0, m_particleCount-1, renderQueue); - } -} - -void* NzParticleEmitter::CreateParticle() -{ - return CreateParticles(1); -} - -void* NzParticleEmitter::CreateParticles(unsigned int count) -{ - if (m_particleCount+count > m_maxParticleCount) - return nullptr; - - unsigned int particlesIndex = m_particleCount; - m_particleCount += count; - - return &m_buffer[particlesIndex*m_particleSize]; -} - -void NzParticleEmitter::EnableFixedStep(bool fixedStep) -{ - // On teste pour empêcher que cette méthode ne remette systématiquement le step accumulator à zéro - if (m_fixedStepEnabled != fixedStep) - { - m_fixedStepEnabled = fixedStep; - m_stepAccumulator = 0.f; - } -} - -void* NzParticleEmitter::GenerateParticle() -{ - return GenerateParticles(1); -} - -void* NzParticleEmitter::GenerateParticles(unsigned int count) -{ - void* ptr = CreateParticles(count); - if (!ptr) - return nullptr; - - NzParticleMapper mapper(ptr, m_declaration); - for (NzParticleGenerator* generator : m_generators) - generator->Generate(*this, mapper, 0, m_particleCount-1); - - return ptr; -} - -const NzBoundingVolumef& NzParticleEmitter::GetBoundingVolume() const -{ - if (!m_boundingVolumeUpdated) - UpdateBoundingVolume(); - - return m_boundingVolume; -} - -unsigned int NzParticleEmitter::GetEmissionCount() const -{ - return m_emissionCount; -} - -float NzParticleEmitter::GetEmissionRate() const -{ - return m_emissionRate; -} - -float NzParticleEmitter::GetFixedStepSize() const -{ - return m_stepSize; -} - -unsigned int NzParticleEmitter::GetMaxParticleCount() const -{ - return m_maxParticleCount; -} - -unsigned int NzParticleEmitter::GetParticleCount() const -{ - return m_particleCount; -} - -unsigned int NzParticleEmitter::GetParticleSize() const -{ - return m_particleSize; -} - -nzSceneNodeType NzParticleEmitter::GetSceneNodeType() const -{ - return nzSceneNodeType_ParticleEmitter; -} - -bool NzParticleEmitter::IsDrawable() const -{ - return true; -} - -bool NzParticleEmitter::IsFixedStepEnabled() const -{ - return m_fixedStepEnabled; -} - -void NzParticleEmitter::KillParticle(unsigned int index) -{ - ///FIXME: Vérifier index - - if (m_processing) - { - // Le buffer est en train d'être modifié, nous ne pouvons pas réduire sa taille, on place alors la particule dans une liste de secours - m_dyingParticles.insert(index); - return; - } - - // On déplace la dernière particule vivante à la place de celle-ci - if (--m_particleCount > 0) - std::memcpy(&m_buffer[index*m_particleSize], &m_buffer[m_particleCount*m_particleSize], m_particleSize); -} - -void NzParticleEmitter::KillParticles() -{ - m_particleCount = 0; -} - -void NzParticleEmitter::RemoveController(NzParticleController* controller) -{ - auto it = std::find(m_controllers.begin(), m_controllers.end(), controller); - if (it != m_controllers.end()) - m_controllers.erase(it); -} - -void NzParticleEmitter::RemoveGenerator(NzParticleGenerator* generator) -{ - auto it = std::find(m_generators.begin(), m_generators.end(), generator); - if (it != m_generators.end()) - m_generators.erase(it); -} - -void NzParticleEmitter::SetEmissionCount(unsigned int count) -{ - m_emissionCount = count; -} - -void NzParticleEmitter::SetEmissionRate(float rate) -{ - m_emissionRate = rate; -} - -void NzParticleEmitter::SetFixedStepSize(float stepSize) -{ - m_stepSize = stepSize; -} - -void NzParticleEmitter::SetRenderer(NzParticleRenderer* renderer) -{ - m_renderer = renderer; -} - -NzParticleEmitter& NzParticleEmitter::operator=(const NzParticleEmitter& emitter) -{ - NzErrorFlags flags(nzErrorFlag_ThrowException, true); - - NzSceneNode::operator=(emitter); - - m_boundingVolume = emitter.m_boundingVolume; - m_boundingVolumeUpdated = emitter.m_boundingVolumeUpdated; - m_controllers = emitter.m_controllers; - m_declaration = emitter.m_declaration; - m_emissionCount = emitter.m_emissionCount; - m_emissionRate = emitter.m_emissionRate; - m_fixedStepEnabled = emitter.m_fixedStepEnabled; - m_generators = emitter.m_generators; - m_maxParticleCount = emitter.m_maxParticleCount; - m_particleCount = emitter.m_particleCount; - m_particleSize = emitter.m_particleSize; - m_renderer = emitter.m_renderer; - m_stepSize = emitter.m_stepSize; - - // La copie ne peut pas (ou plutôt ne devrait pas) avoir lieu pendant une mise à jour, inutile de copier - m_dyingParticles.clear(); - m_emissionAccumulator = 0.f; - m_processing = false; - m_stepAccumulator = 0.f; - - m_buffer.clear(); // Pour éviter une recopie lors du resize() qui ne servira pas à grand chose - ResizeBuffer(); - - // On ne copie que les particules vivantes - std::memcpy(m_buffer.data(), emitter.m_buffer.data(), emitter.m_particleCount*m_particleSize); - - return *this; -} - -void NzParticleEmitter::GenerateAABB() const -{ - m_boundingVolume.MakeInfinite(); -} - -void NzParticleEmitter::Register() -{ - m_scene->RegisterForUpdate(this); -} - -void NzParticleEmitter::ResizeBuffer() -{ - // Histoire de décrire un peu mieux l'erreur en cas d'échec - try - { - m_buffer.resize(m_maxParticleCount*m_particleSize); - } - catch (const std::exception& e) - { - NzStringStream stream; - stream << "Failed to allocate particle buffer (" << e.what() << ") for " << m_maxParticleCount << " particles of size " << m_particleSize; - - NazaraError(stream.ToString()); - } -} - -void NzParticleEmitter::Unregister() -{ - m_scene->UnregisterForUpdate(this); -} - -void NzParticleEmitter::UpdateBoundingVolume() const -{ - if (m_boundingVolume.IsNull()) - GenerateAABB(); - - if (!m_transformMatrixUpdated) - UpdateTransformMatrix(); - - m_boundingVolume.Update(m_transformMatrix); - m_boundingVolumeUpdated = true; -} - -void NzParticleEmitter::Update() -{ - float elapsedTime = m_scene->GetUpdateTime(); - if (m_emissionRate > 0.f) { // On accumule la partie réelle (pour éviter qu'un taux d'update élevé empêche des particules de se former) @@ -334,57 +37,33 @@ void NzParticleEmitter::Update() unsigned int maxParticleCount = static_cast(emissionCount)*m_emissionCount; // On récupère le nombre de particules qu'il est possible de créer selon l'espace libre - unsigned int particleCount = std::min(maxParticleCount, m_maxParticleCount - m_particleCount); + unsigned int particleCount = std::min(maxParticleCount, system.GetMaxParticleCount() - system.GetParticleCount()); // Et on émet nos particules - GenerateParticles(particleCount); + void* particles = system.GenerateParticles(particleCount); + NzParticleMapper mapper(particles, system.GetDeclaration()); + + SetupParticles(mapper, particleCount); } } - - if (m_particleCount > 0) - { - NzParticleMapper mapper(m_buffer.data(), m_declaration); - - m_processing = true; - - // Pour éviter un verrouillage en cas d'exception - NzCallOnExit onExit([this]() - { - m_processing = false; - }); - - if (m_fixedStepEnabled) - { - m_stepAccumulator += elapsedTime; - while (m_stepAccumulator >= m_stepSize) - { - for (NzParticleController* controller : m_controllers) - controller->Apply(*this, mapper, 0, m_particleCount-1, m_stepAccumulator); - - m_stepAccumulator -= m_stepSize; - } - } - else - { - for (NzParticleController* controller : m_controllers) - controller->Apply(*this, mapper, 0, m_particleCount-1, elapsedTime); - } - - m_processing = false; - onExit.Reset(); - - // On tue maintenant les particules mortes durant la mise à jour - if (m_dyingParticles.size() < m_particleCount) - { - // On tue les particules depuis la dernière vers la première (en terme de place), le std::set étant trié via std::greater - // La raison est simple, étant donné que la mort d'une particule signifie le déplacement de la dernière particule du buffer, - // sans cette solution certaines particules pourraient échapper à la mort - for (unsigned int index : m_dyingParticles) - KillParticle(index); - } - else - KillParticles(); // Toutes les particules sont mortes, ceci est beaucoup plus rapide - - m_dyingParticles.clear(); - } +} + +unsigned int NzParticleEmitter::GetEmissionCount() const +{ + return m_emissionCount; +} + +float NzParticleEmitter::GetEmissionRate() const +{ + return m_emissionRate; +} + +void NzParticleEmitter::SetEmissionCount(unsigned int count) +{ + m_emissionCount = count; +} + +void NzParticleEmitter::SetEmissionRate(float rate) +{ + m_emissionRate = rate; } diff --git a/src/Nazara/Graphics/ParticleSystem.cpp b/src/Nazara/Graphics/ParticleSystem.cpp new file mode 100644 index 000000000..a9bbc565b --- /dev/null +++ b/src/Nazara/Graphics/ParticleSystem.cpp @@ -0,0 +1,366 @@ +// Copyright (C) 2014 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 + +NzParticleSystem::NzParticleSystem(unsigned int maxParticleCount, nzParticleLayout layout) : +NzParticleSystem(maxParticleCount, NzParticleDeclaration::Get(layout)) +{ +} + +NzParticleSystem::NzParticleSystem(unsigned int maxParticleCount, const NzParticleDeclaration* declaration) : +m_declaration(declaration), +m_boundingVolumeUpdated(false), +m_fixedStepEnabled(false), +m_processing(false), +m_stepAccumulator(0.f), +m_stepSize(1.f/60.f), +m_maxParticleCount(maxParticleCount), +m_particleCount(0) +{ + // En cas d'erreur, un constructeur ne peut que lancer une exception + NzErrorFlags flags(nzErrorFlag_ThrowException, true); + + m_particleSize = m_declaration->GetStride(); // La taille de chaque particule + + ResizeBuffer(); +} + +NzParticleSystem::NzParticleSystem(const NzParticleSystem& system) : +NzSceneNode(system), +m_controllers(system.m_controllers), +m_generators(system.m_generators), +m_boundingVolume(system.m_boundingVolume), +m_declaration(system.m_declaration), +m_renderer(system.m_renderer), +m_boundingVolumeUpdated(system.m_boundingVolumeUpdated), +m_fixedStepEnabled(system.m_fixedStepEnabled), +m_processing(false), +m_stepAccumulator(0.f), +m_stepSize(system.m_stepSize), +m_maxParticleCount(system.m_maxParticleCount), +m_particleCount(system.m_particleCount), +m_particleSize(system.m_particleSize) +{ + NzErrorFlags flags(nzErrorFlag_ThrowException, true); + + ResizeBuffer(); + + // On ne copie que les particules vivantes + std::memcpy(m_buffer.data(), system.m_buffer.data(), system.m_particleCount*m_particleSize); +} + +NzParticleSystem::~NzParticleSystem() = default; + +void NzParticleSystem::AddController(NzParticleController* controller) +{ + m_controllers.emplace_back(controller); +} + +void NzParticleSystem::AddEmitter(NzParticleEmitter* emitter) +{ + m_emitters.emplace_back(emitter); +} + +void NzParticleSystem::AddGenerator(NzParticleGenerator* generator) +{ + m_generators.emplace_back(generator); +} + +void NzParticleSystem::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const +{ + ///FIXME: Vérifier le renderer + if (m_particleCount > 0) + { + NzParticleMapper mapper(m_buffer.data(), m_declaration); + m_renderer->Render(*this, mapper, 0, m_particleCount-1, renderQueue); + } +} + +void* NzParticleSystem::CreateParticle() +{ + return CreateParticles(1); +} + +void* NzParticleSystem::CreateParticles(unsigned int count) +{ + if (count == 0) + return nullptr; + + if (m_particleCount+count > m_maxParticleCount) + return nullptr; + + unsigned int particlesIndex = m_particleCount; + m_particleCount += count; + + return &m_buffer[particlesIndex*m_particleSize]; +} + +void NzParticleSystem::EnableFixedStep(bool fixedStep) +{ + // On teste pour empêcher que cette méthode ne remette systématiquement le step accumulator à zéro + if (m_fixedStepEnabled != fixedStep) + { + m_fixedStepEnabled = fixedStep; + m_stepAccumulator = 0.f; + } +} + +void* NzParticleSystem::GenerateParticle() +{ + return GenerateParticles(1); +} + +void* NzParticleSystem::GenerateParticles(unsigned int count) +{ + void* ptr = CreateParticles(count); + if (!ptr) + return nullptr; + + NzParticleMapper mapper(ptr, m_declaration); + for (NzParticleGenerator* generator : m_generators) + generator->Generate(*this, mapper, 0, m_particleCount-1); + + return ptr; +} + +const NzBoundingVolumef& NzParticleSystem::GetBoundingVolume() const +{ + if (!m_boundingVolumeUpdated) + UpdateBoundingVolume(); + + return m_boundingVolume; +} + +const NzParticleDeclaration* NzParticleSystem::GetDeclaration() const +{ + return m_declaration; +} + +float NzParticleSystem::GetFixedStepSize() const +{ + return m_stepSize; +} + +unsigned int NzParticleSystem::GetMaxParticleCount() const +{ + return m_maxParticleCount; +} + +unsigned int NzParticleSystem::GetParticleCount() const +{ + return m_particleCount; +} + +unsigned int NzParticleSystem::GetParticleSize() const +{ + return m_particleSize; +} + +nzSceneNodeType NzParticleSystem::GetSceneNodeType() const +{ + return nzSceneNodeType_ParticleEmitter; +} + +bool NzParticleSystem::IsDrawable() const +{ + return true; +} + +bool NzParticleSystem::IsFixedStepEnabled() const +{ + return m_fixedStepEnabled; +} + +void NzParticleSystem::KillParticle(unsigned int index) +{ + ///FIXME: Vérifier index + + if (m_processing) + { + // Le buffer est en train d'être modifié, nous ne pouvons pas réduire sa taille, on place alors la particule dans une liste de secours + m_dyingParticles.insert(index); + return; + } + + // On déplace la dernière particule vivante à la place de celle-ci + if (--m_particleCount > 0) + std::memcpy(&m_buffer[index*m_particleSize], &m_buffer[m_particleCount*m_particleSize], m_particleSize); +} + +void NzParticleSystem::KillParticles() +{ + m_particleCount = 0; +} + +void NzParticleSystem::RemoveController(NzParticleController* controller) +{ + auto it = std::find(m_controllers.begin(), m_controllers.end(), controller); + if (it != m_controllers.end()) + m_controllers.erase(it); +} + +void NzParticleSystem::RemoveEmitter(NzParticleEmitter* emitter) +{ + auto it = std::find(m_emitters.begin(), m_emitters.end(), emitter); + if (it != m_emitters.end()) + m_emitters.erase(it); +} + +void NzParticleSystem::RemoveGenerator(NzParticleGenerator* generator) +{ + auto it = std::find(m_generators.begin(), m_generators.end(), generator); + if (it != m_generators.end()) + m_generators.erase(it); +} + +void NzParticleSystem::SetFixedStepSize(float stepSize) +{ + m_stepSize = stepSize; +} + +void NzParticleSystem::SetRenderer(NzParticleRenderer* renderer) +{ + m_renderer = renderer; +} + +NzParticleSystem& NzParticleSystem::operator=(const NzParticleSystem& system) +{ + NzErrorFlags flags(nzErrorFlag_ThrowException, true); + + NzSceneNode::operator=(system); + + m_boundingVolume = system.m_boundingVolume; + m_boundingVolumeUpdated = system.m_boundingVolumeUpdated; + m_controllers = system.m_controllers; + m_declaration = system.m_declaration; + m_fixedStepEnabled = system.m_fixedStepEnabled; + m_generators = system.m_generators; + m_maxParticleCount = system.m_maxParticleCount; + m_particleCount = system.m_particleCount; + m_particleSize = system.m_particleSize; + m_renderer = system.m_renderer; + m_stepSize = system.m_stepSize; + + // La copie ne peut pas (ou plutôt ne devrait pas) avoir lieu pendant une mise à jour, inutile de copier + m_dyingParticles.clear(); + m_processing = false; + m_stepAccumulator = 0.f; + + m_buffer.clear(); // Pour éviter une recopie lors du resize() qui ne servira pas à grand chose + ResizeBuffer(); + + // On ne copie que les particules vivantes + std::memcpy(m_buffer.data(), system.m_buffer.data(), system.m_particleCount*m_particleSize); + + return *this; +} + +void NzParticleSystem::GenerateAABB() const +{ + m_boundingVolume.MakeInfinite(); +} + +void NzParticleSystem::Register() +{ + m_scene->RegisterForUpdate(this); +} + +void NzParticleSystem::ResizeBuffer() +{ + // Histoire de décrire un peu mieux l'erreur en cas d'échec + try + { + m_buffer.resize(m_maxParticleCount*m_particleSize); + } + catch (const std::exception& e) + { + NzStringStream stream; + stream << "Failed to allocate particle buffer (" << e.what() << ") for " << m_maxParticleCount << " particles of size " << m_particleSize; + + NazaraError(stream.ToString()); + } +} + +void NzParticleSystem::Unregister() +{ + m_scene->UnregisterForUpdate(this); +} + +void NzParticleSystem::UpdateBoundingVolume() const +{ + if (m_boundingVolume.IsNull()) + GenerateAABB(); + + if (!m_transformMatrixUpdated) + UpdateTransformMatrix(); + + m_boundingVolume.Update(m_transformMatrix); + m_boundingVolumeUpdated = true; +} + +void NzParticleSystem::Update() +{ + float elapsedTime = m_scene->GetUpdateTime(); + + // Émission + for (NzParticleEmitter* emitter : m_emitters) + emitter->Emit(*this, elapsedTime); + + // Mise à jour + if (m_particleCount > 0) + { + NzParticleMapper mapper(m_buffer.data(), m_declaration); + + m_processing = true; + + // Pour éviter un verrouillage en cas d'exception + NzCallOnExit onExit([this]() + { + m_processing = false; + }); + + if (m_fixedStepEnabled) + { + m_stepAccumulator += elapsedTime; + while (m_stepAccumulator >= m_stepSize) + { + for (NzParticleController* controller : m_controllers) + controller->Apply(*this, mapper, 0, m_particleCount-1, m_stepAccumulator); + + m_stepAccumulator -= m_stepSize; + } + } + else + { + for (NzParticleController* controller : m_controllers) + controller->Apply(*this, mapper, 0, m_particleCount-1, elapsedTime); + } + + m_processing = false; + onExit.Reset(); + + // On tue maintenant les particules mortes durant la mise à jour + if (m_dyingParticles.size() < m_particleCount) + { + // On tue les particules depuis la dernière vers la première (en terme de place), le std::set étant trié via std::greater + // La raison est simple, étant donné que la mort d'une particule signifie le déplacement de la dernière particule du buffer, + // sans cette solution certaines particules pourraient échapper à la mort + for (unsigned int index : m_dyingParticles) + KillParticle(index); + } + else + KillParticles(); // Toutes les particules sont mortes, ceci est beaucoup plus rapide + + m_dyingParticles.clear(); + } +} + From 2753e3c4f16845afcbe1fbd6819ae9255ee1c79d Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 1 Sep 2014 14:10:48 +0200 Subject: [PATCH 053/233] Updated shaders Added support for billboards (rendertechniques support is coming) - Doesn't support lighting well for now Added support for vertex coloring Added AUTO_TEXCOORDS parameter support to PhongLighting UberShader Removed unused flag FLAG_FLIP_UVS More to come ... Former-commit-id: b408c80e8805a8bfebe9fcdf3a3f954116fbfe96 --- .../Shaders/Basic/compatibility.frag | 15 +++- .../Shaders/Basic/compatibility.frag.h | 2 +- .../Shaders/Basic/compatibility.vert | 87 ++++++++++++++---- .../Shaders/Basic/compatibility.vert.h | 2 +- .../Resources/Shaders/Basic/core.frag | 3 +- .../Resources/Shaders/Basic/core.frag.h | 2 +- .../Resources/Shaders/Basic/core.vert | 89 ++++++++++++++---- .../Resources/Shaders/Basic/core.vert.h | 2 +- .../Shaders/PhongLighting/compatibility.frag | 27 ++++-- .../PhongLighting/compatibility.frag.h | 2 +- .../Shaders/PhongLighting/compatibility.vert | 90 +++++++++++++++---- .../PhongLighting/compatibility.vert.h | 2 +- .../Resources/Shaders/PhongLighting/core.frag | 18 +++- .../Shaders/PhongLighting/core.frag.h | 2 +- .../Resources/Shaders/PhongLighting/core.vert | 90 +++++++++++++++---- .../Shaders/PhongLighting/core.vert.h | 2 +- 16 files changed, 345 insertions(+), 90 deletions(-) diff --git a/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.frag b/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.frag index ab1d445ca..bc3955b48 100644 --- a/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.frag +++ b/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.frag @@ -1,22 +1,31 @@ /********************Entrant********************/ varying vec2 vTexCoord; +varying vec4 vColor; /********************Uniformes********************/ uniform sampler2D MaterialAlphaMap; uniform float MaterialAlphaThreshold; uniform vec4 MaterialDiffuse; uniform sampler2D MaterialDiffuseMap; +uniform vec2 InvTargetSize; /********************Fonctions********************/ void main() { - vec4 fragmentColor = MaterialDiffuse; + vec4 fragmentColor = MaterialDiffuse; * vColor; + +#if AUTO_TEXCOORDS + vec2 texCoord = gl_FragCoord.xy * InvTargetSize; +#else + vec2 texCoord = vTexCoord; +#endif + #if DIFFUSE_MAPPING - fragmentColor *= texture2D(MaterialDiffuseMap, vTexCoord); + fragmentColor *= texture2D(MaterialDiffuseMap, texCoord); #endif #if ALPHA_MAPPING - fragmentColor.a *= texture2D(MaterialAlphaMap, vTexCoord).r; + fragmentColor.a *= texture2D(MaterialAlphaMap, texCoord).r; #endif #if ALPHA_TEST diff --git a/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.frag.h b/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.frag.h index 0ffb28cff..b1ae605a4 100644 --- a/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.frag.h +++ b/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.frag.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,118,97,114,121,105,110,103,32,118,101,99,50,32,118,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,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,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,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,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,9,118,101,99,52,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,59,13,10,35,105,102,32,68,73,70,70,85,83,69,95,77,65,80,80,73,78,71,13,10,9,102,114,97,103,109,101,110,116,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,50,68,40,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,44,32,118,84,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,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,102,114,97,103,109,101,110,116,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,50,68,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,118,84,101,120,67,111,111,114,100,41,46,114,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,105,102,32,40,102,114,97,103,109,101,110,116,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,35,101,110,100,105,102,13,10,13,10,9,103,108,95,70,114,97,103,67,111,108,111,114,32,61,32,102,114,97,103,109,101,110,116,67,111,108,111,114,59,13,10,125, \ 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,118,97,114,121,105,110,103,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,118,97,114,121,105,110,103,32,118,101,99,52,32,118,67,111,108,111,114,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,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,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,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,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,9,118,101,99,52,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,59,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,68,73,70,70,85,83,69,95,77,65,80,80,73,78,71,13,10,9,102,114,97,103,109,101,110,116,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,50,68,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,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,102,114,97,103,109,101,110,116,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,50,68,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,35,101,110,100,105,102,13,10,13,10,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,105,102,32,40,102,114,97,103,109,101,110,116,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,35,101,110,100,105,102,13,10,13,10,9,103,108,95,70,114,97,103,67,111,108,111,114,32,61,32,102,114,97,103,109,101,110,116,67,111,108,111,114,59,13,10,125, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.vert b/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.vert index 111db31db..47c2260d7 100644 --- a/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.vert +++ b/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.vert @@ -1,10 +1,19 @@ /********************Entrant********************/ +#if FLAG_BILLBOARD +varying vec3 InstanceData0; // center +varying vec4 InstanceData1; // size | sin cos +varying vec4 InstanceData2; // color +#else varying mat4 InstanceData0; +#endif + +varying vec4 VertexColor; varying vec3 VertexPosition; varying vec2 VertexTexCoord; /********************Sortant********************/ varying vec2 vTexCoord; +varying vec4 vColor; /********************Uniformes********************/ uniform float VertexDepth; @@ -14,29 +23,77 @@ uniform mat4 WorldViewProjMatrix; /********************Fonctions********************/ void main() { -#if FLAG_INSTANCING - #if TRANSFORM - gl_Position = ViewProjMatrix * InstanceData0 * vec4(VertexPosition, 1.0); +#if FLAG_VERTEXCOLOR + vec4 color = VertexColor; +#else + vec4 color = vec4(1.0); +#endif + vec2 texCoords; + +#if FLAG_BILLBOARD + #if FLAG_INSTANCING + vec3 billboardCenter = InstanceData0; + vec2 billboardSize = InstanceData1.xy; + vec2 billboardSinCos = InstanceData1.zw; + vec4 billboardColor = InstanceData2; + + vec2 rotatedPosition; + rotatedPosition.x = VertexPosition.x*billboardSinCos.y - VertexPosition.y*billboardSinCos.x; + rotatedPosition.y = VertexPosition.y*billboardSinCos.y + VertexPosition.x*billboardSinCos.x; + rotatedPosition *= billboardSize; + + vec3 cameraRight = vec3(ViewMatrix[0][0], ViewMatrix[1][0], ViewMatrix[2][0]); + vec3 cameraUp = vec3(ViewMatrix[0][1], ViewMatrix[1][1], ViewMatrix[2][1]); + vec3 vertexPos = billboardCenter + cameraRight*rotatedPosition.x + cameraUp*rotatedPosition.y; + + gl_Position = ViewProjMatrix * vec4(vertexPos, 1.0); + color = billboardColor; + texCoords = VertexPosition.xy + vec2(0.5, 0.5); #else - #if UNIFORM_VERTEX_DEPTH - gl_Position = InstanceData0 * vec4(VertexPosition.xy, VertexDepth, 1.0); - #else - gl_Position = InstanceData0 * vec4(VertexPosition, 1.0); - #endif + vec2 billboardCorner = VertexTexCoord - vec2(0.5, 0.5); + vec2 billboardSize = VertexUserdata0.xy; + vec2 billboardSinCos = VertexUserdata0.zw; + + vec2 rotatedPosition; + rotatedPosition.x = billboardCorner.x*billboardSinCos.y - billboardCorner.y*billboardSinCos.x; + rotatedPosition.y = billboardCorner.y*billboardSinCos.y + billboardCorner.x*billboardSinCos.x; + rotatedPosition *= billboardSize; + + vec3 cameraRight = vec3(ViewMatrix[0][0], ViewMatrix[1][0], ViewMatrix[2][0]); + vec3 cameraUp = vec3(ViewMatrix[0][1], ViewMatrix[1][1], ViewMatrix[2][1]); + vec3 vertexPos = VertexPosition + cameraRight*rotatedPosition.x + cameraUp*rotatedPosition.y; + + gl_Position = ViewProjMatrix * vec4(vertexPos, 1.0); + texCoords = VertexTexCoord; #endif #else - #if TRANSFORM - gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0); - #else - #if UNIFORM_VERTEX_DEPTH - gl_Position = vec4(VertexPosition.xy, VertexDepth, 1.0); + #if FLAG_INSTANCING + #if TRANSFORM + gl_Position = ViewProjMatrix * InstanceData0 * vec4(VertexPosition, 1.0); #else - gl_Position = vec4(VertexPosition, 1.0); + #if UNIFORM_VERTEX_DEPTH + gl_Position = InstanceData0 * vec4(VertexPosition.xy, VertexDepth, 1.0); + #else + gl_Position = InstanceData0 * vec4(VertexPosition, 1.0); + #endif + #endif + #else + #if TRANSFORM + gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0); + #else + #if UNIFORM_VERTEX_DEPTH + gl_Position = vec4(VertexPosition.xy, VertexDepth, 1.0); + #else + gl_Position = vec4(VertexPosition, 1.0); + #endif #endif #endif + + texCoords = VertexTexCoord; #endif + vColor = color; #if TEXTURE_MAPPING - vTexCoord = vec2(VertexTexCoord); + vTexCoord = vec2(texCoords); #endif } diff --git a/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.vert.h b/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.vert.h index 5182574de..556f0c733 100644 --- a/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.vert.h +++ b/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.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,118,97,114,121,105,110,103,32,109,97,116,52,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,13,10,118,97,114,121,105,110,103,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,118,97,114,121,105,110,103,32,118,101,99,50,32,118,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,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,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,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,73,78,83,84,65,78,67,73,78,71,13,10,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,35,101,108,115,101,13,10,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,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,35,101,108,115,101,13,10,9,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,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,13,10,35,101,108,115,101,13,10,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,35,101,108,115,101,13,10,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,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,35,101,108,115,101,13,10,9,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,35,101,110,100,105,102,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,118,101,99,50,40,86,101,114,116,101,120,84,101,120,67,111,111,114,100,41,59,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,118,97,114,121,105,110,103,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,118,97,114,121,105,110,103,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,118,97,114,121,105,110,103,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,118,97,114,121,105,110,103,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,118,97,114,121,105,110,103,32,118,101,99,52,32,86,101,114,116,101,120,67,111,108,111,114,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,13,10,118,97,114,121,105,110,103,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,118,97,114,121,105,110,103,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,118,97,114,121,105,110,103,32,118,101,99,52,32,118,67,111,108,111,114,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,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,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,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,118,101,99,50,40,48,46,53,44,32,48,46,53,41,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,118,101,99,50,40,48,46,53,44,32,48,46,53,41,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,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,118,101,99,50,40,116,101,120,67,111,111,114,100,115,41,59,13,10,35,101,110,100,105,102,13,10,125,13,10, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag b/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag index a789242b9..9c4c05df2 100644 --- a/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag +++ b/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag @@ -4,6 +4,7 @@ layout(early_fragment_tests) in; /********************Entrant********************/ in vec2 vTexCoord; +in vec4 vColor; /********************Sortant********************/ out vec4 RenderTarget0; @@ -18,7 +19,7 @@ uniform vec2 InvTargetSize; /********************Fonctions********************/ void main() { - vec4 fragmentColor = MaterialDiffuse; + vec4 fragmentColor = MaterialDiffuse * vColor; #if AUTO_TEXCOORDS vec2 texCoord = gl_FragCoord.xy * InvTargetSize; diff --git a/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag.h b/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag.h index 97c8ee9b1..8d13045fa 100644 --- a/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag.h +++ b/src/Nazara/Graphics/Resources/Shaders/Basic/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,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,50,32,118,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,82,101,110,100,101,114,84,97,114,103,101,116,48,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,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,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,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,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,9,118,101,99,52,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,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,68,73,70,70,85,83,69,95,77,65,80,80,73,78,71,13,10,9,102,114,97,103,109,101,110,116,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,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,102,114,97,103,109,101,110,116,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,35,101,110,100,105,102,13,10,13,10,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,105,102,32,40,102,114,97,103,109,101,110,116,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,35,101,110,100,105,102,13,10,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,125, \ 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,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,50,32,118,84,101,120,67,111,111,114,100,59,13,10,105,110,32,118,101,99,52,32,118,67,111,108,111,114,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,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,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,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,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,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,9,118,101,99,52,32,102,114,97,103,109,101,110,116,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,68,73,70,70,85,83,69,95,77,65,80,80,73,78,71,13,10,9,102,114,97,103,109,101,110,116,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,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,102,114,97,103,109,101,110,116,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,35,101,110,100,105,102,13,10,13,10,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,105,102,32,40,102,114,97,103,109,101,110,116,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,35,101,110,100,105,102,13,10,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,125, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/Shaders/Basic/core.vert b/src/Nazara/Graphics/Resources/Shaders/Basic/core.vert index 0516e8090..4945912b0 100644 --- a/src/Nazara/Graphics/Resources/Shaders/Basic/core.vert +++ b/src/Nazara/Graphics/Resources/Shaders/Basic/core.vert @@ -1,42 +1,101 @@ /********************Entrant********************/ +#if FLAG_BILLBOARD +in vec3 InstanceData0; // center +in vec4 InstanceData1; // size | sin cos +in vec4 InstanceData2; // color +#else in mat4 InstanceData0; +#endif + +in vec4 VertexColor; in vec3 VertexPosition; in vec2 VertexTexCoord; +in vec4 VertexUserdata0; /********************Sortant********************/ out vec2 vTexCoord; +out vec4 vColor; /********************Uniformes********************/ uniform float VertexDepth; +uniform mat4 ViewMatrix; uniform mat4 ViewProjMatrix; uniform mat4 WorldViewProjMatrix; /********************Fonctions********************/ void main() { -#if FLAG_INSTANCING - #if TRANSFORM - gl_Position = ViewProjMatrix * InstanceData0 * vec4(VertexPosition, 1.0); +#if FLAG_VERTEXCOLOR + vec4 color = VertexColor; +#else + vec4 color = vec4(1.0); +#endif + vec2 texCoords; + +#if FLAG_BILLBOARD + #if FLAG_INSTANCING + vec3 billboardCenter = InstanceData0; + vec2 billboardSize = InstanceData1.xy; + vec2 billboardSinCos = InstanceData1.zw; + vec4 billboardColor = InstanceData2; + + vec2 rotatedPosition; + rotatedPosition.x = VertexPosition.x*billboardSinCos.y - VertexPosition.y*billboardSinCos.x; + rotatedPosition.y = VertexPosition.y*billboardSinCos.y + VertexPosition.x*billboardSinCos.x; + rotatedPosition *= billboardSize; + + vec3 cameraRight = vec3(ViewMatrix[0][0], ViewMatrix[1][0], ViewMatrix[2][0]); + vec3 cameraUp = vec3(ViewMatrix[0][1], ViewMatrix[1][1], ViewMatrix[2][1]); + vec3 vertexPos = billboardCenter + cameraRight*rotatedPosition.x + cameraUp*rotatedPosition.y; + + gl_Position = ViewProjMatrix * vec4(vertexPos, 1.0); + color = billboardColor; + texCoords = VertexPosition.xy + 0.5; #else - #if UNIFORM_VERTEX_DEPTH - gl_Position = InstanceData0 * vec4(VertexPosition.xy, VertexDepth, 1.0); - #else - gl_Position = InstanceData0 * vec4(VertexPosition, 1.0); - #endif + vec2 billboardCorner = VertexTexCoord - 0.5; + vec2 billboardSize = VertexUserdata0.xy; + vec2 billboardSinCos = VertexUserdata0.zw; + + vec2 rotatedPosition; + rotatedPosition.x = billboardCorner.x*billboardSinCos.y - billboardCorner.y*billboardSinCos.x; + rotatedPosition.y = billboardCorner.y*billboardSinCos.y + billboardCorner.x*billboardSinCos.x; + rotatedPosition *= billboardSize; + + vec3 cameraRight = vec3(ViewMatrix[0][0], ViewMatrix[1][0], ViewMatrix[2][0]); + vec3 cameraUp = vec3(ViewMatrix[0][1], ViewMatrix[1][1], ViewMatrix[2][1]); + vec3 vertexPos = VertexPosition + cameraRight*rotatedPosition.x + cameraUp*rotatedPosition.y; + + gl_Position = ViewProjMatrix * vec4(vertexPos, 1.0); + texCoords = VertexTexCoord; #endif #else - #if TRANSFORM - gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0); - #else - #if UNIFORM_VERTEX_DEPTH - gl_Position = vec4(VertexPosition.xy, VertexDepth, 1.0); + #if FLAG_INSTANCING + #if TRANSFORM + gl_Position = ViewProjMatrix * InstanceData0 * vec4(VertexPosition, 1.0); #else - gl_Position = vec4(VertexPosition, 1.0); + #if UNIFORM_VERTEX_DEPTH + gl_Position = InstanceData0 * vec4(VertexPosition.xy, VertexDepth, 1.0); + #else + gl_Position = InstanceData0 * vec4(VertexPosition, 1.0); + #endif + #endif + #else + #if TRANSFORM + gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0); + #else + #if UNIFORM_VERTEX_DEPTH + gl_Position = vec4(VertexPosition.xy, VertexDepth, 1.0); + #else + gl_Position = vec4(VertexPosition, 1.0); + #endif #endif #endif + + texCoords = VertexTexCoord; #endif + vColor = color; #if TEXTURE_MAPPING - vTexCoord = vec2(VertexTexCoord); + vTexCoord = vec2(texCoords); #endif } diff --git a/src/Nazara/Graphics/Resources/Shaders/Basic/core.vert.h b/src/Nazara/Graphics/Resources/Shaders/Basic/core.vert.h index 681ed8a5a..52f419a93 100644 --- a/src/Nazara/Graphics/Resources/Shaders/Basic/core.vert.h +++ b/src/Nazara/Graphics/Resources/Shaders/Basic/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,105,110,32,109,97,116,52,32,73,110,115,116,97,110,99,101,68,97,116,97,48,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,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,50,32,118,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,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,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,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,73,78,83,84,65,78,67,73,78,71,13,10,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,35,101,108,115,101,13,10,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,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,35,101,108,115,101,13,10,9,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,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,13,10,35,101,108,115,101,13,10,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,35,101,108,115,101,13,10,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,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,35,101,108,115,101,13,10,9,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,35,101,110,100,105,102,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,118,101,99,50,40,86,101,114,116,101,120,84,101,120,67,111,111,114,100,41,59,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,50,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,105,110,32,118,101,99,52,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,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,50,32,118,84,101,120,67,111,111,114,100,59,13,10,111,117,116,32,118,101,99,52,32,118,67,111,108,111,114,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,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,77,97,116,114,105,120,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,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,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,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,118,101,99,50,40,116,101,120,67,111,111,114,100,115,41,59,13,10,35,101,110,100,105,102,13,10,125,13,10, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.frag b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.frag index d122528d4..f78f73ed6 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.frag +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.frag @@ -1,5 +1,5 @@ #if FLAG_DEFERRED - #error Deferred Shading needs core profile + #error Deferred Shading is not supported by compatibility shaders #endif #define LIGHT_DIRECTIONAL 0 @@ -11,6 +11,7 @@ varying mat3 vLightToWorld; varying vec3 vNormal; varying vec2 vTexCoord; varying vec3 vWorldPos; +varying vec4 vColor; /********************Uniformes********************/ struct Light @@ -24,9 +25,10 @@ struct Light vec2 parameters3; }; -uniform vec3 EyePosition; +// Lumières uniform Light Lights[3]; +// Matériau uniform sampler2D MaterialAlphaMap; uniform float MaterialAlphaThreshold; uniform vec4 MaterialAmbient; @@ -38,18 +40,27 @@ uniform float MaterialShininess; uniform vec4 MaterialSpecular; uniform sampler2D MaterialSpecularMap; +// Autres +uniform vec3 EyePosition; uniform vec4 SceneAmbient; /********************Fonctions********************/ void main() { - vec4 diffuseColor = MaterialDiffuse; + vec4 diffuseColor = MaterialDiffuse * vColor; + +#if AUTO_TEXCOORDS + vec2 texCoord = gl_FragCoord.xy * InvTargetSize; +#else + vec2 texCoord = vTexCoord; +#endif + #if DIFFUSE_MAPPING - diffuseColor *= texture(MaterialDiffuseMap, vTexCoord); + diffuseColor *= texture(MaterialDiffuseMap, texCoord); #endif #if ALPHA_MAPPING - diffuseColor.a *= texture(MaterialAlphaMap, vTexCoord).r; + diffuseColor.a *= texture(MaterialAlphaMap, texCoord).r; #endif #if ALPHA_TEST @@ -63,7 +74,7 @@ void main() vec3 lightSpecular = vec3(0.0); #if NORMAL_MAPPING - vec3 normal = normalize(vLightToWorld * (2.0 * vec3(texture(MaterialNormalMap, vTexCoord)) - 1.0)); + vec3 normal = normalize(vLightToWorld * (2.0 * vec3(texture(MaterialNormalMap, texCoord)) - 1.0)); #else vec3 normal = normalize(vNormal); #endif @@ -206,7 +217,7 @@ void main() lightSpecular *= MaterialSpecular.rgb; #if SPECULAR_MAPPING - lightSpecular *= texture(MaterialSpecularMap, vTexCoord).rgb; // Utiliser l'alpha de MaterialSpecular n'aurait aucun sens + lightSpecular *= texture(MaterialSpecularMap, texCoord).rgb; // Utiliser l'alpha de MaterialSpecular n'aurait aucun sens #endif vec3 lightColor = (lightAmbient + lightDiffuse + lightSpecular); @@ -215,7 +226,7 @@ void main() #if EMISSIVE_MAPPING float lightIntensity = dot(lightColor, vec3(0.3, 0.59, 0.11)); - vec3 emissionColor = MaterialDiffuse.rgb * texture(MaterialEmissiveMap, vTexCoord).rgb; + vec3 emissionColor = MaterialDiffuse.rgb * texture(MaterialEmissiveMap, texCoord).rgb; RenderTarget0 = vec4(mix(fragmentColor.rgb, emissionColor, clamp(1.0 - 3.0*lightIntensity, 0.0, 1.0)), fragmentColor.a); #else RenderTarget0 = fragmentColor; diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.frag.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.frag.h index 97855b8e5..3358d4e82 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.frag.h +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.frag.h @@ -1 +1 @@ -35,105,102,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,9,35,101,114,114,111,114,32,68,101,102,101,114,114,101,100,32,83,104,97,100,105,110,103,32,110,101,101,100,115,32,99,111,114,101,32,112,114,111,102,105,108,101,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,118,97,114,121,105,110,103,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,118,78,111,114,109,97,108,59,13,10,118,97,114,121,105,110,103,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,118,97,114,121,105,110,103,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,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,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,76,105,103,104,116,32,76,105,103,104,116,115,91,51,93,59,13,10,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,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,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,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,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,59,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,118,84,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,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,118,84,101,120,67,111,111,114,100,41,46,114,59,13,10,35,101,110,100,105,102,13,10,13,10,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,35,101,110,100,105,102,13,10,13,10,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,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,118,84,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,13,10,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,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,105,102,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,32,61,61,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,41,13,10,9,9,9,123,13,10,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,47,47,32,65,109,98,105,101,110,116,13,10,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,47,47,32,68,105,102,102,117,115,101,13,10,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,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,47,47,32,83,112,101,99,117,108,97,114,13,10,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,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,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,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,125,13,10,9,9,9,101,108,115,101,32,105,102,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,32,61,61,32,76,73,71,72,84,95,80,79,73,78,84,41,13,10,9,9,9,123,13,10,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,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,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,13,10,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,47,47,32,65,109,98,105,101,110,116,13,10,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,47,47,32,68,105,102,102,117,115,101,13,10,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,13,10,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,47,47,32,83,112,101,99,117,108,97,114,13,10,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,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,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,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,125,13,10,9,9,9,101,108,115,101,32,105,102,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,32,61,61,32,76,73,71,72,84,95,83,80,79,84,41,13,10,9,9,9,123,13,10,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,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,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,13,10,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,47,47,32,65,109,98,105,101,110,116,13,10,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,47,47,32,68,105,102,102,117,115,101,13,10,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,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,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,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,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,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,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,47,47,32,83,112,101,99,117,108,97,114,13,10,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,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,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,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,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,105,102,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,32,61,61,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,41,13,10,9,9,9,123,13,10,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,47,47,32,65,109,98,105,101,110,116,13,10,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,47,47,32,68,105,102,102,117,115,101,13,10,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,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,125,13,10,9,9,9,101,108,115,101,32,105,102,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,32,61,61,32,76,73,71,72,84,95,80,79,73,78,84,41,13,10,9,9,9,123,13,10,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,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,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,13,10,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,47,47,32,65,109,98,105,101,110,116,13,10,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,47,47,32,68,105,102,102,117,115,101,13,10,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,13,10,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,125,13,10,9,9,9,101,108,115,101,32,105,102,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,32,61,61,32,76,73,71,72,84,95,83,80,79,84,41,13,10,9,9,9,123,13,10,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,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,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,13,10,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,47,47,32,65,109,98,105,101,110,116,13,10,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,47,47,32,68,105,102,102,117,115,101,13,10,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,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,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,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,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,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,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,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,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,118,84,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,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,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,118,84,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,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,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,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,35,101,110,100,105,102,32,47,47,32,76,73,71,72,84,73,78,71,13,10,125,13,10, \ No newline at end of file +35,105,102,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,9,35,101,114,114,111,114,32,68,101,102,101,114,114,101,100,32,83,104,97,100,105,110,103,32,105,115,32,110,111,116,32,115,117,112,112,111,114,116,101,100,32,98,121,32,99,111,109,112,97,116,105,98,105,108,105,116,121,32,115,104,97,100,101,114,115,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,118,97,114,121,105,110,103,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,118,78,111,114,109,97,108,59,13,10,118,97,114,121,105,110,103,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,118,87,111,114,108,100,80,111,115,59,13,10,118,97,114,121,105,110,103,32,118,101,99,52,32,118,67,111,108,111,114,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,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,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,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,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,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,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,35,101,110,100,105,102,13,10,13,10,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,35,101,110,100,105,102,13,10,13,10,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,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,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,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,105,102,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,32,61,61,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,41,13,10,9,9,9,123,13,10,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,47,47,32,65,109,98,105,101,110,116,13,10,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,47,47,32,68,105,102,102,117,115,101,13,10,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,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,47,47,32,83,112,101,99,117,108,97,114,13,10,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,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,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,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,125,13,10,9,9,9,101,108,115,101,32,105,102,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,32,61,61,32,76,73,71,72,84,95,80,79,73,78,84,41,13,10,9,9,9,123,13,10,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,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,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,13,10,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,47,47,32,65,109,98,105,101,110,116,13,10,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,47,47,32,68,105,102,102,117,115,101,13,10,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,13,10,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,47,47,32,83,112,101,99,117,108,97,114,13,10,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,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,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,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,125,13,10,9,9,9,101,108,115,101,32,105,102,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,32,61,61,32,76,73,71,72,84,95,83,80,79,84,41,13,10,9,9,9,123,13,10,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,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,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,13,10,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,47,47,32,65,109,98,105,101,110,116,13,10,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,47,47,32,68,105,102,102,117,115,101,13,10,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,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,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,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,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,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,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,47,47,32,83,112,101,99,117,108,97,114,13,10,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,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,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,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,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,105,102,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,32,61,61,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,41,13,10,9,9,9,123,13,10,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,47,47,32,65,109,98,105,101,110,116,13,10,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,47,47,32,68,105,102,102,117,115,101,13,10,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,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,125,13,10,9,9,9,101,108,115,101,32,105,102,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,32,61,61,32,76,73,71,72,84,95,80,79,73,78,84,41,13,10,9,9,9,123,13,10,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,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,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,13,10,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,47,47,32,65,109,98,105,101,110,116,13,10,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,47,47,32,68,105,102,102,117,115,101,13,10,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,13,10,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,125,13,10,9,9,9,101,108,115,101,32,105,102,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,32,61,61,32,76,73,71,72,84,95,83,80,79,84,41,13,10,9,9,9,123,13,10,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,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,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,13,10,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,47,47,32,65,109,98,105,101,110,116,13,10,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,47,47,32,68,105,102,102,117,115,101,13,10,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,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,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,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,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,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,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,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,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,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,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,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,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,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,35,101,110,100,105,102,32,47,47,32,76,73,71,72,84,73,78,71,13,10,125,13,10, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.vert b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.vert index 8ef9700b3..e42e972f7 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.vert +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.vert @@ -1,5 +1,12 @@ /********************Entrant********************/ +#if FLAG_BILLBOARD +varying vec3 InstanceData0; // center +varying vec4 InstanceData1; // size | sin cos +varying vec4 InstanceData2; // color +#else varying mat4 InstanceData0; +#endif + varying vec3 VertexPosition; varying vec3 VertexNormal; varying vec3 VertexTangent; @@ -10,6 +17,7 @@ varying mat3 vLightToWorld; varying vec3 vNormal; varying vec2 vTexCoord; varying vec3 vWorldPos; +varying vec4 vColor; /********************Uniformes********************/ uniform float VertexDepth; @@ -20,28 +28,76 @@ uniform mat4 WorldViewProjMatrix; /********************Fonctions********************/ void main() { -#if FLAG_INSTANCING - #if TRANSFORM - gl_Position = ViewProjMatrix * InstanceData0 * vec4(VertexPosition, 1.0); +#if FLAG_VERTEXCOLOR + vec4 color = VertexColor; +#else + vec4 color = vec4(1.0); +#endif + vec2 texCoords; + +#if FLAG_BILLBOARD + #if FLAG_INSTANCING + vec3 billboardCenter = InstanceData0; + vec2 billboardSize = InstanceData1.xy; + vec2 billboardSinCos = InstanceData1.zw; + vec4 billboardColor = InstanceData2; + + vec2 rotatedPosition; + rotatedPosition.x = VertexPosition.x*billboardSinCos.y - VertexPosition.y*billboardSinCos.x; + rotatedPosition.y = VertexPosition.y*billboardSinCos.y + VertexPosition.x*billboardSinCos.x; + rotatedPosition *= billboardSize; + + vec3 cameraRight = vec3(ViewMatrix[0][0], ViewMatrix[1][0], ViewMatrix[2][0]); + vec3 cameraUp = vec3(ViewMatrix[0][1], ViewMatrix[1][1], ViewMatrix[2][1]); + vec3 vertexPos = billboardCenter + cameraRight*rotatedPosition.x + cameraUp*rotatedPosition.y; + + gl_Position = ViewProjMatrix * vec4(vertexPos, 1.0); + color = billboardColor; + texCoords = VertexPosition.xy + vec2(0.5, 0.5); #else - #if UNIFORM_VERTEX_DEPTH - gl_Position = InstanceData0 * vec4(VertexPosition.xy, VertexDepth, 1.0); - #else - gl_Position = InstanceData0 * vec4(VertexPosition, 1.0); - #endif + vec2 billboardCorner = VertexTexCoord - vec2(0.5, 0.5); + vec2 billboardSize = VertexUserdata0.xy; + vec2 billboardSinCos = VertexUserdata0.zw; + + vec2 rotatedPosition; + rotatedPosition.x = billboardCorner.x*billboardSinCos.y - billboardCorner.y*billboardSinCos.x; + rotatedPosition.y = billboardCorner.y*billboardSinCos.y + billboardCorner.x*billboardSinCos.x; + rotatedPosition *= billboardSize; + + vec3 cameraRight = vec3(ViewMatrix[0][0], ViewMatrix[1][0], ViewMatrix[2][0]); + vec3 cameraUp = vec3(ViewMatrix[0][1], ViewMatrix[1][1], ViewMatrix[2][1]); + vec3 vertexPos = VertexPosition + cameraRight*rotatedPosition.x + cameraUp*rotatedPosition.y; + + gl_Position = ViewProjMatrix * vec4(vertexPos, 1.0); + texCoords = VertexTexCoord; #endif #else - #if TRANSFORM - gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0); - #else - #if UNIFORM_VERTEX_DEPTH - gl_Position = vec4(VertexPosition.xy, VertexDepth, 1.0); + #if FLAG_INSTANCING + #if TRANSFORM + gl_Position = ViewProjMatrix * InstanceData0 * vec4(VertexPosition, 1.0); #else - gl_Position = vec4(VertexPosition, 1.0); + #if UNIFORM_VERTEX_DEPTH + gl_Position = InstanceData0 * vec4(VertexPosition.xy, VertexDepth, 1.0); + #else + gl_Position = InstanceData0 * vec4(VertexPosition, 1.0); + #endif + #endif + #else + #if TRANSFORM + gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0); + #else + #if UNIFORM_VERTEX_DEPTH + gl_Position = vec4(VertexPosition.xy, VertexDepth, 1.0); + #else + gl_Position = vec4(VertexPosition, 1.0); + #endif #endif #endif + + texCoords = VertexTexCoord; #endif + vColor = color; #if LIGHTING #if FLAG_INSTANCING @@ -61,11 +117,7 @@ void main() #endif #if TEXTURE_MAPPING - #if FLAG_FLIP_UVS - vTexCoord = vec2(VertexTexCoord.x, 1.0 - VertexTexCoord.y); - #else - vTexCoord = VertexTexCoord; - #endif + vTexCoord = vec2(texCoords); #endif #if LIGHTING && PARALLAX_MAPPING diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.vert.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.vert.h index 48cbdb6e4..29df285c8 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.vert.h +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.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,118,97,114,121,105,110,103,32,109,97,116,52,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,86,101,114,116,101,120,78,111,114,109,97,108,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,86,101,114,116,101,120,84,97,110,103,101,110,116,59,13,10,118,97,114,121,105,110,103,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,118,97,114,121,105,110,103,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,118,78,111,114,109,97,108,59,13,10,118,97,114,121,105,110,103,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,118,97,114,121,105,110,103,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,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,73,78,83,84,65,78,67,73,78,71,13,10,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,35,101,108,115,101,13,10,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,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,35,101,108,115,101,13,10,9,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,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,13,10,35,101,108,115,101,13,10,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,35,101,108,115,101,13,10,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,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,35,101,108,115,101,13,10,9,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,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,13,10,35,101,110,100,105,102,13,10,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,91,48,93,46,120,121,122,44,32,73,110,115,116,97,110,99,101,68,97,116,97,48,91,49,93,46,120,121,122,44,32,73,110,115,116,97,110,99,101,68,97,116,97,48,91,50,93,46,120,121,122,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,91,48,93,46,120,121,122,44,32,87,111,114,108,100,77,97,116,114,105,120,91,49,93,46,120,121,122,44,32,87,111,114,108,100,77,97,116,114,105,120,91,50,93,46,120,121,122,41,59,13,10,9,35,101,110,100,105,102,13,10,9,13,10,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,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,35,105,102,32,70,76,65,71,95,70,76,73,80,95,85,86,83,13,10,9,118,84,101,120,67,111,111,114,100,32,61,32,118,101,99,50,40,86,101,114,116,101,120,84,101,120,67,111,111,114,100,46,120,44,32,49,46,48,32,45,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,46,121,41,59,13,10,9,35,101,108,115,101,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,9,35,101,110,100,105,102,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,118,97,114,121,105,110,103,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,118,97,114,121,105,110,103,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,118,97,114,121,105,110,103,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,118,97,114,121,105,110,103,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,118,97,114,121,105,110,103,32,118,101,99,51,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,86,101,114,116,101,120,78,111,114,109,97,108,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,86,101,114,116,101,120,84,97,110,103,101,110,116,59,13,10,118,97,114,121,105,110,103,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,118,97,114,121,105,110,103,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,118,78,111,114,109,97,108,59,13,10,118,97,114,121,105,110,103,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,118,87,111,114,108,100,80,111,115,59,13,10,118,97,114,121,105,110,103,32,118,101,99,52,32,118,67,111,108,111,114,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,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,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,118,101,99,50,40,48,46,53,44,32,48,46,53,41,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,118,101,99,50,40,48,46,53,44,32,48,46,53,41,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,9,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,91,48,93,46,120,121,122,44,32,73,110,115,116,97,110,99,101,68,97,116,97,48,91,49,93,46,120,121,122,44,32,73,110,115,116,97,110,99,101,68,97,116,97,48,91,50,93,46,120,121,122,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,91,48,93,46,120,121,122,44,32,87,111,114,108,100,77,97,116,114,105,120,91,49,93,46,120,121,122,44,32,87,111,114,108,100,77,97,116,114,105,120,91,50,93,46,120,121,122,41,59,13,10,9,35,101,110,100,105,102,13,10,9,13,10,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,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,118,101,99,50,40,116,101,120,67,111,111,114,100,115,41,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 diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag index 055b5472e..54e86e5e1 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag @@ -12,6 +12,7 @@ in vec3 vNormal; in vec2 vTexCoord; in vec3 vViewDir; in vec3 vWorldPos; +in vec4 vColor; /********************Sortant********************/ out vec4 RenderTarget0; @@ -30,9 +31,10 @@ struct Light vec2 parameters3; }; -uniform vec3 EyePosition; +// Lumières uniform Light Lights[3]; +// Matériau uniform sampler2D MaterialAlphaMap; uniform float MaterialAlphaThreshold; uniform vec4 MaterialAmbient; @@ -45,8 +47,11 @@ uniform float MaterialShininess; uniform vec4 MaterialSpecular; uniform sampler2D MaterialSpecularMap; +// Autres uniform float ParallaxBias = -0.03; uniform float ParallaxScale = 0.02; +uniform vec2 InvTargetSize; +uniform vec3 EyePosition; uniform vec4 SceneAmbient; /********************Fonctions********************/ @@ -76,8 +81,14 @@ vec4 EncodeNormal(in vec3 normal) void main() { - vec4 diffuseColor = MaterialDiffuse; + vec4 diffuseColor = MaterialDiffuse * vColor; + +#if AUTO_TEXCOORDS + vec2 texCoord = gl_FragCoord.xy * InvTargetSize; +#else vec2 texCoord = vTexCoord; +#endif + #if LIGHTING && PARALLAX_MAPPING float height = texture(MaterialHeightMap, texCoord).r; float v = height*ParallaxScale + ParallaxBias; @@ -92,7 +103,8 @@ void main() #if FLAG_DEFERRED #if ALPHA_TEST - #if ALPHA_MAPPING // Inutile de faire de l'alpha-mapping sans alpha-test en Deferred (l'alpha n'est pas sauvegardé) + // Inutile de faire de l'alpha-mapping sans alpha-test en Deferred (l'alpha n'est pas sauvegardé dans le G-Buffer) + #if ALPHA_MAPPING diffuseColor.a *= texture(MaterialAlphaMap, texCoord).r; #endif diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h index 54e4bb415..18b03d1dc 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,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,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,76,105,103,104,116,32,76,105,103,104,116,115,91,51,93,59,13,10,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,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,52,32,83,99,101,110,101,65,109,98,105,101,110,116,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,59,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,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,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,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,32,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,41,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,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,105,110,32,118,101,99,52,32,118,67,111,108,111,114,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,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,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 diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert index 09430bb06..d19345f14 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert @@ -1,5 +1,13 @@ /********************Entrant********************/ +#if FLAG_BILLBOARD +in vec3 InstanceData0; // center +in vec4 InstanceData1; // size | sin cos +in vec4 InstanceData2; // color +#else in mat4 InstanceData0; +#endif + +in vec4 VertexColor; in vec3 VertexPosition; in vec3 VertexNormal; in vec3 VertexTangent; @@ -11,6 +19,7 @@ out vec3 vNormal; out vec2 vTexCoord; out vec3 vViewDir; out vec3 vWorldPos; +out vec4 vColor; /********************Uniformes********************/ uniform vec3 EyePosition; @@ -22,28 +31,77 @@ uniform mat4 WorldViewProjMatrix; /********************Fonctions********************/ void main() { -#if FLAG_INSTANCING - #if TRANSFORM - gl_Position = ViewProjMatrix * InstanceData0 * vec4(VertexPosition, 1.0); +#if FLAG_VERTEXCOLOR + vec4 color = VertexColor; +#else + vec4 color = vec4(1.0); +#endif + vec2 texCoords; + +#if FLAG_BILLBOARD + #if FLAG_INSTANCING + vec3 billboardCenter = InstanceData0; + vec2 billboardSize = InstanceData1.xy; + vec2 billboardSinCos = InstanceData1.zw; + vec4 billboardColor = InstanceData2; + + vec2 rotatedPosition; + rotatedPosition.x = VertexPosition.x*billboardSinCos.y - VertexPosition.y*billboardSinCos.x; + rotatedPosition.y = VertexPosition.y*billboardSinCos.y + VertexPosition.x*billboardSinCos.x; + rotatedPosition *= billboardSize; + + vec3 cameraRight = vec3(ViewMatrix[0][0], ViewMatrix[1][0], ViewMatrix[2][0]); + vec3 cameraUp = vec3(ViewMatrix[0][1], ViewMatrix[1][1], ViewMatrix[2][1]); + vec3 vertexPos = billboardCenter + cameraRight*rotatedPosition.x + cameraUp*rotatedPosition.y; + + gl_Position = ViewProjMatrix * vec4(vertexPos, 1.0); + color = billboardColor; + texCoords = VertexPosition.xy + 0.5; #else - #if UNIFORM_VERTEX_DEPTH - gl_Position = InstanceData0 * vec4(VertexPosition.xy, VertexDepth, 1.0); - #else - gl_Position = InstanceData0 * vec4(VertexPosition, 1.0); - #endif + vec2 billboardCorner = VertexTexCoord - 0.5; + vec2 billboardSize = VertexUserdata0.xy; + vec2 billboardSinCos = VertexUserdata0.zw; + + vec2 rotatedPosition; + rotatedPosition.x = billboardCorner.x*billboardSinCos.y - billboardCorner.y*billboardSinCos.x; + rotatedPosition.y = billboardCorner.y*billboardSinCos.y + billboardCorner.x*billboardSinCos.x; + rotatedPosition *= billboardSize; + + vec3 cameraRight = vec3(ViewMatrix[0][0], ViewMatrix[1][0], ViewMatrix[2][0]); + vec3 cameraUp = vec3(ViewMatrix[0][1], ViewMatrix[1][1], ViewMatrix[2][1]); + vec3 vertexPos = VertexPosition + cameraRight*rotatedPosition.x + cameraUp*rotatedPosition.y; + + gl_Position = ViewProjMatrix * vec4(vertexPos, 1.0); + texCoords = VertexTexCoord; #endif #else - #if TRANSFORM - gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0); - #else - #if UNIFORM_VERTEX_DEPTH - gl_Position = vec4(VertexPosition.xy, VertexDepth, 1.0); + #if FLAG_INSTANCING + #if TRANSFORM + gl_Position = ViewProjMatrix * InstanceData0 * vec4(VertexPosition, 1.0); #else - gl_Position = vec4(VertexPosition, 1.0); + #if UNIFORM_VERTEX_DEPTH + gl_Position = InstanceData0 * vec4(VertexPosition.xy, VertexDepth, 1.0); + #else + gl_Position = InstanceData0 * vec4(VertexPosition, 1.0); + #endif + #endif + #else + #if TRANSFORM + gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0); + #else + #if UNIFORM_VERTEX_DEPTH + gl_Position = vec4(VertexPosition.xy, VertexDepth, 1.0); + #else + gl_Position = vec4(VertexPosition, 1.0); + #endif #endif #endif + + texCoords = VertexTexCoord; #endif + vColor = color; + #if LIGHTING #if FLAG_INSTANCING mat3 rotationMatrix = mat3(InstanceData0); @@ -62,11 +120,7 @@ void main() #endif #if TEXTURE_MAPPING - #if FLAG_FLIP_UVS - vTexCoord = vec2(VertexTexCoord.x, 1.0 - VertexTexCoord.y); - #else vTexCoord = VertexTexCoord; - #endif #endif #if LIGHTING && PARALLAX_MAPPING diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert.h index c920136a2..4e99b165e 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,105,110,32,109,97,116,52,32,73,110,115,116,97,110,99,101,68,97,116,97,48,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,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,73,78,83,84,65,78,67,73,78,71,13,10,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,35,101,108,115,101,13,10,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,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,35,101,108,115,101,13,10,9,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,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,13,10,35,101,108,115,101,13,10,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,35,101,108,115,101,13,10,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,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,35,101,108,115,101,13,10,9,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,35,101,110,100,105,102,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,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,35,105,102,32,70,76,65,71,95,70,76,73,80,95,85,86,83,13,10,9,118,84,101,120,67,111,111,114,100,32,61,32,118,101,99,50,40,86,101,114,116,101,120,84,101,120,67,111,111,114,100,46,120,44,32,49,46,48,32,45,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,46,121,41,59,13,10,9,35,101,108,115,101,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,9,35,101,110,100,105,102,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,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,111,117,116,32,118,101,99,52,32,118,67,111,108,111,114,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,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 From 67ecefd38008fc13015b69f09f4e8151e5e5fef7 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 1 Sep 2014 15:42:51 +0200 Subject: [PATCH 054/233] Added sprite color attribute Former-commit-id: 1db061b862315495cb40ff308348a0ac8d41e304 --- include/Nazara/Graphics/Sprite.hpp | 3 +++ src/Nazara/Graphics/Sprite.cpp | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Graphics/Sprite.hpp b/include/Nazara/Graphics/Sprite.hpp index 54ebb71a1..3316ecfa7 100644 --- a/include/Nazara/Graphics/Sprite.hpp +++ b/include/Nazara/Graphics/Sprite.hpp @@ -23,6 +23,7 @@ class NAZARA_API NzSprite : public NzSceneNode void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; const NzBoundingVolumef& GetBoundingVolume() const override; + const NzColor& GetColor() const; NzMaterial* GetMaterial() const; nzSceneNodeType GetSceneNodeType() const override; const NzVector2f& GetSize() const; @@ -30,6 +31,7 @@ class NAZARA_API NzSprite : public NzSceneNode bool IsDrawable() const; + void SetColor(const NzColor& color); void SetMaterial(NzMaterial* material, bool resizeSprite = true); void SetSize(const NzVector2f& size); void SetTexture(NzTexture* texture, bool resizeSprite = true); @@ -43,6 +45,7 @@ class NAZARA_API NzSprite : public NzSceneNode void UpdateBoundingVolume() const; mutable NzBoundingVolumef m_boundingVolume; + NzColor m_color; NzMaterialRef m_material; NzRectf m_textureCoords; NzVector2f m_size; diff --git a/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index 7d14a1a8e..6bc082a6d 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -8,6 +8,7 @@ NzSprite::NzSprite() : m_boundingVolume(NzBoundingVolumef::Null()), +m_color(NzColor::White), m_textureCoords(0.f, 0.f, 1.f, 1.f), m_size(64.f, 64.f), m_boundingVolumeUpdated(true) @@ -16,6 +17,7 @@ m_boundingVolumeUpdated(true) NzSprite::NzSprite(NzTexture* texture) : m_boundingVolume(NzBoundingVolumef::Null()), +m_color(NzColor::White), m_textureCoords(0.f, 0.f, 1.f, 1.f) { if (texture) @@ -41,6 +43,7 @@ m_textureCoords(0.f, 0.f, 1.f, 1.f) NzSprite::NzSprite(const NzSprite& sprite) : NzSceneNode(sprite), m_boundingVolume(sprite.m_boundingVolume), +m_color(sprite.m_color), m_material(sprite.m_material), m_textureCoords(sprite.m_textureCoords), m_size(sprite.m_size), @@ -52,6 +55,7 @@ m_boundingVolumeUpdated(sprite.m_boundingVolumeUpdated) NzSprite::NzSprite(NzSprite&& sprite) : NzSceneNode(sprite), m_boundingVolume(sprite.m_boundingVolume), +m_color(std::move(sprite.m_color)), m_material(std::move(sprite.m_material)), m_textureCoords(sprite.m_textureCoords), m_size(sprite.m_size), @@ -72,6 +76,11 @@ const NzBoundingVolumef& NzSprite::GetBoundingVolume() const return infinity; } +const NzColor& NzSprite::GetColor() const +{ + return m_color; +} + NzMaterial* NzSprite::GetMaterial() const { return m_material; @@ -97,6 +106,11 @@ bool NzSprite::IsDrawable() const return m_material != nullptr; } +void NzSprite::SetColor(const NzColor& color) +{ + m_color = color; +} + void NzSprite::SetMaterial(NzMaterial* material, bool resizeSprite) { m_material = material; @@ -173,7 +187,7 @@ void NzSprite::Unregister() void NzSprite::UpdateBoundingVolume() const { if (m_boundingVolume.IsNull()) - m_boundingVolume.Set(-m_size.x*0.5f, -m_size.y*0.5f, 0.f, m_size.x, m_size.y, 0.f); + m_boundingVolume.Set(0.f, 0.f, 0.f, m_size.x, m_size.y, 0.f); if (!m_transformMatrixUpdated) UpdateTransformMatrix(); From aeec8ee0f426af55cf259b5ac7f5030546b258a1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 1 Sep 2014 16:00:54 +0200 Subject: [PATCH 055/233] Enabled new shader flags Former-commit-id: df06f4faf4c7275c702338eee1ed14a2445662a1 --- include/Nazara/Graphics/Enums.hpp | 8 +++++--- src/Nazara/Graphics/Material.cpp | 13 ++++++++----- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/include/Nazara/Graphics/Enums.hpp b/include/Nazara/Graphics/Enums.hpp index 6f9cc9814..4865f586b 100644 --- a/include/Nazara/Graphics/Enums.hpp +++ b/include/Nazara/Graphics/Enums.hpp @@ -121,10 +121,12 @@ enum nzShaderFlags { nzShaderFlags_None = 0, - nzShaderFlags_Deferred = 0x1, - nzShaderFlags_Instancing = 0x2, + nzShaderFlags_Billboard = 0x1, + nzShaderFlags_Deferred = 0x2, + nzShaderFlags_Instancing = 0x4, + nzShaderFlags_VertexColor = 0x8, - nzShaderFlags_Max = nzShaderFlags_Instancing*2-1 + nzShaderFlags_Max = nzShaderFlags_VertexColor*2-1 }; #endif // NAZARA_ENUMS_GRAPHICS_HPP diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 123db7ffc..024a0efcf 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -248,10 +248,11 @@ const NzUberShader* NzMaterial::GetShader() const const NzUberShaderInstance* NzMaterial::GetShaderInstance(nzUInt32 flags) const { - if (!m_shaders[flags].uberInstance) + const ShaderInstance& instance = m_shaders[flags]; + if (!instance.uberInstance) GenerateShader(flags); - return m_shaders[flags].uberInstance; + return instance.uberInstance; } float NzMaterial::GetShininess() const @@ -690,8 +691,10 @@ void NzMaterial::GenerateShader(nzUInt32 flags) const m_normalMap.IsValid() || m_heightMap.IsValid() || m_specularMap.IsValid()); list.SetParameter("TRANSFORM", m_transformEnabled); + list.SetParameter("FLAG_BILLBOARD", static_cast(flags & nzShaderFlags_Billboard)); list.SetParameter("FLAG_DEFERRED", static_cast(flags & nzShaderFlags_Deferred)); list.SetParameter("FLAG_INSTANCING", static_cast(flags & nzShaderFlags_Instancing)); + list.SetParameter("FLAG_VERTEXCOLOR", static_cast(flags & nzShaderFlags_VertexColor)); ShaderInstance& instance = m_shaders[flags]; instance.uberInstance = m_uberShader->Get(list); @@ -759,7 +762,7 @@ bool NzMaterial::Initialize() } uberShader->SetShader(nzShaderStage_Fragment, fragmentShader, "ALPHA_MAPPING ALPHA_TEST AUTO_TEXCOORDS DIFFUSE_MAPPING"); - uberShader->SetShader(nzShaderStage_Vertex, vertexShader, "FLAG_INSTANCING TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); + uberShader->SetShader(nzShaderStage_Vertex, vertexShader, "FLAG_BILLBOARD FLAG_INSTANCING FLAG_VERTEXCOLOR TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); NzUberShaderLibrary::Register("Basic", uberShader.get()); uberShader.release(); @@ -799,8 +802,8 @@ bool NzMaterial::Initialize() vertexShader.Set(reinterpret_cast(compatibilityVertexShader), sizeof(compatibilityVertexShader)); } - uberShader->SetShader(nzShaderStage_Fragment, fragmentShader, "FLAG_DEFERRED ALPHA_MAPPING ALPHA_TEST DIFFUSE_MAPPING EMISSIVE_MAPPING LIGHTING NORMAL_MAPPING PARALLAX_MAPPING SPECULAR_MAPPING"); - uberShader->SetShader(nzShaderStage_Vertex, vertexShader, "FLAG_DEFERRED FLAG_INSTANCING COMPUTE_TBNMATRIX LIGHTING PARALLAX_MAPPING TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); + uberShader->SetShader(nzShaderStage_Fragment, fragmentShader, "FLAG_DEFERRED 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"); NzUberShaderLibrary::Register("PhongLighting", uberShader.get()); uberShader.release(); From 659eb317572e291e2f516019db483798ec83d13a Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 3 Sep 2014 13:16:56 +0200 Subject: [PATCH 056/233] Added support for billboads Improved ForwardRenderTechnique code Former-commit-id: 2386de85c26839565f087885ffcb098ef263bdfa --- .../Nazara/Graphics/AbstractRenderQueue.hpp | 4 + .../Nazara/Graphics/DeferredRenderQueue.hpp | 2 + .../Nazara/Graphics/ForwardRenderQueue.hpp | 12 + .../Graphics/ForwardRenderTechnique.hpp | 15 +- src/Nazara/Graphics/DeferredRenderQueue.cpp | 15 + src/Nazara/Graphics/ForwardRenderQueue.cpp | 59 +++- .../Graphics/ForwardRenderTechnique.cpp | 306 +++++++++++++++--- src/Nazara/Graphics/Graphics.cpp | 15 +- 8 files changed, 375 insertions(+), 53 deletions(-) diff --git a/include/Nazara/Graphics/AbstractRenderQueue.hpp b/include/Nazara/Graphics/AbstractRenderQueue.hpp index c3a9de2e4..77e7942e5 100644 --- a/include/Nazara/Graphics/AbstractRenderQueue.hpp +++ b/include/Nazara/Graphics/AbstractRenderQueue.hpp @@ -8,7 +8,9 @@ #define NAZARA_ABSTRACTRENDERQUEUE_HPP #include +#include #include +#include #include #include #include @@ -25,6 +27,8 @@ class NAZARA_API NzAbstractRenderQueue : NzNonCopyable NzAbstractRenderQueue() = default; virtual ~NzAbstractRenderQueue(); + virtual void AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos = NzVector2f(0.f, 1.f), const NzColor& color = NzColor::White) = 0; + virtual void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr = nullptr, NzSparsePtr colorPtr = nullptr) = 0; virtual void AddDrawable(const NzDrawable* drawable) = 0; virtual void AddLight(const NzLight* light) = 0; virtual void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) = 0; diff --git a/include/Nazara/Graphics/DeferredRenderQueue.hpp b/include/Nazara/Graphics/DeferredRenderQueue.hpp index 8cec0ecea..3e610b758 100644 --- a/include/Nazara/Graphics/DeferredRenderQueue.hpp +++ b/include/Nazara/Graphics/DeferredRenderQueue.hpp @@ -28,6 +28,8 @@ class NAZARA_API NzDeferredRenderQueue : public NzAbstractRenderQueue, NzResourc NzDeferredRenderQueue(NzForwardRenderQueue* forwardQueue); ~NzDeferredRenderQueue(); + 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 AddDrawable(const NzDrawable* drawable) override; void AddLight(const NzLight* light) override; void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) override; diff --git a/include/Nazara/Graphics/ForwardRenderQueue.hpp b/include/Nazara/Graphics/ForwardRenderQueue.hpp index 85710cd0d..2533e22a5 100644 --- a/include/Nazara/Graphics/ForwardRenderQueue.hpp +++ b/include/Nazara/Graphics/ForwardRenderQueue.hpp @@ -30,6 +30,8 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResource NzForwardRenderQueue() = default; ~NzForwardRenderQueue(); + 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 AddDrawable(const NzDrawable* drawable) override; void AddLight(const NzLight* light) override; void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) override; @@ -43,6 +45,14 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResource bool OnResourceDestroy(const NzResource* resource, int index) override; void OnResourceReleased(const NzResource* resource, int index) override; + struct BillboardData + { + NzColor color; + NzVector3f center; + NzVector2f size; + NzVector2f sinCos; + }; + struct TransparentModelData { NzMatrix4f transformMatrix; @@ -68,11 +78,13 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResource typedef std::map>, MeshDataComparator> MeshInstanceContainer; typedef std::map, BatchedModelMaterialComparator> ModelBatches; + typedef std::map> BatchedBillboardContainer; typedef std::map> BatchedSpriteContainer; typedef std::vector LightContainer; typedef std::vector TransparentModelContainer; ModelBatches opaqueModels; + BatchedBillboardContainer billboards; BatchedSpriteContainer sprites; TransparentModelContainer transparentModels; std::vector transparentModelData; diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.hpp b/include/Nazara/Graphics/ForwardRenderTechnique.hpp index 9050cda20..a1133b497 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.hpp +++ b/include/Nazara/Graphics/ForwardRenderTechnique.hpp @@ -20,7 +20,7 @@ class NAZARA_API NzForwardRenderTechnique : public NzAbstractRenderTechnique, Nz { public: NzForwardRenderTechnique(); - ~NzForwardRenderTechnique(); + ~NzForwardRenderTechnique() = default; void Clear(const NzScene* scene) const; bool Draw(const NzScene* scene) const; @@ -31,9 +31,13 @@ class NAZARA_API NzForwardRenderTechnique : public NzAbstractRenderTechnique, Nz void SetMaxLightPassPerObject(unsigned int passCount); + static bool Initialize(); + static void Uninitialize(); + private: struct LightUniforms; + void DrawBillboards(const NzScene* scene) const; void DrawOpaqueModels(const NzScene* scene) const; void DrawSprites(const NzScene* scene) const; void DrawTransparentModels(const NzScene* scene) const; @@ -49,12 +53,19 @@ class NAZARA_API NzForwardRenderTechnique : public NzAbstractRenderTechnique, Nz }; mutable std::unordered_map m_lightUniforms; + NzBuffer m_vertexBuffer; mutable NzForwardRenderQueue m_renderQueue; - NzIndexBufferRef m_indexBuffer; mutable NzLightManager m_directionalLights; mutable NzLightManager m_lights; + NzVertexBuffer m_billboardPointBuffer; NzVertexBuffer m_spriteBuffer; unsigned int m_maxLightPassPerObject; + + static NzIndexBuffer s_quadIndexBuffer; + static NzVertexBuffer s_quadVertexBuffer; + static NzVertexDeclaration s_billboardInstanceDeclaration; + static NzVertexDeclaration s_billboardVertexDeclaration; + static NzVertexDeclaration s_spriteDeclaration; }; #endif // NAZARA_FORWARDRENDERTECHNIQUE_HPP diff --git a/src/Nazara/Graphics/DeferredRenderQueue.cpp b/src/Nazara/Graphics/DeferredRenderQueue.cpp index c4e393ec1..db6ce13fd 100644 --- a/src/Nazara/Graphics/DeferredRenderQueue.cpp +++ b/src/Nazara/Graphics/DeferredRenderQueue.cpp @@ -31,6 +31,18 @@ NzDeferredRenderQueue::~NzDeferredRenderQueue() Clear(true); } +void NzDeferredRenderQueue::AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos, const NzColor& color) +{ + ///TODO: Rendre les billboards via Deferred Shading si possible + m_forwardQueue->AddBillboard(material, position, size, sinCos, color); +} + +void NzDeferredRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr colorPtr) +{ + ///TODO: Rendre les billboards via Deferred Shading si possible + m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); +} + void NzDeferredRenderQueue::AddDrawable(const NzDrawable* drawable) { m_forwardQueue->AddDrawable(drawable); @@ -81,8 +93,10 @@ void NzDeferredRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData bool& enableInstancing = std::get<1>(it->second); MeshInstanceContainer& meshMap = std::get<2>(it->second); + // On indique la présence de modèles dans cette partie de la map used = true; + // Si nous insérons ce mesh pour la première fois, nous ajoutons des listeners sur ses buffers MeshInstanceContainer::iterator it2 = meshMap.find(meshData); if (it2 == meshMap.end()) { @@ -94,6 +108,7 @@ void NzDeferredRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData meshData.vertexBuffer->AddResourceListener(this, ResourceType_VertexBuffer); } + // On ajoute la matrice à la liste des instances de cet objet std::vector& instances = it2->second; instances.push_back(transformMatrix); diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index 90770660d..fd867e45c 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -27,6 +27,37 @@ NzForwardRenderQueue::~NzForwardRenderQueue() Clear(true); } +void NzForwardRenderQueue::AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos, const NzColor& color) +{ + billboards[material].push_back(BillboardData{color, position, size, sinCos}); +} + +void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr colorPtr) +{ + ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seont 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) + 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 + + std::vector& billboardVec = billboards[material]; + unsigned int prevSize = billboardVec.size(); + billboardVec.resize(prevSize + count); + + BillboardData* billboardData = &billboardVec[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + billboardData->center = *positionPtr++; + billboardData->color = *colorPtr++; + billboardData->sinCos = *sinCosPtr++; + billboardData->size = *sizePtr++; + billboardData++; + } +} + void NzForwardRenderQueue::AddDrawable(const NzDrawable* drawable) { #if NAZARA_GRAPHICS_SAFE @@ -72,6 +103,7 @@ void NzForwardRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& { if (material->IsEnabled(nzRendererParameter_Blend)) { + // Le matériau est transparent, nous devons rendre ce mesh d'une autre façon (après le rendu des objets opaques et en les triant) unsigned int index = transparentModelData.size(); transparentModelData.resize(index+1); @@ -88,6 +120,7 @@ void NzForwardRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& ModelBatches::iterator it = opaqueModels.find(material); if (it == opaqueModels.end()) { + // Première utilisation du matériau, ajoutons-nous comme listener it = opaqueModels.insert(std::make_pair(material, ModelBatches::mapped_type())).first; material->AddResourceListener(this, ResourceType_Material); } @@ -166,6 +199,8 @@ void NzForwardRenderQueue::Clear(bool fully) renderData.vertexBuffer->RemoveResourceListener(this); } } + + billboards.clear(); opaqueModels.clear(); sprites.clear(); } @@ -174,6 +209,7 @@ void NzForwardRenderQueue::Clear(bool fully) void NzForwardRenderQueue::Sort(const NzAbstractViewer* viewer) { NzPlanef nearPlane = viewer->GetFrustum().GetPlane(nzFrustumPlane_Near); + NzVector3f viewerPos = viewer->GetEyePosition(); NzVector3f viewerNormal = viewer->GetForward(); std::sort(transparentModels.begin(), transparentModels.end(), [this, &nearPlane, &viewerNormal](unsigned int index1, unsigned int index2) @@ -186,6 +222,20 @@ void NzForwardRenderQueue::Sort(const NzAbstractViewer* viewer) return nearPlane.Distance(position1) > nearPlane.Distance(position2); }); + + for (auto& pair : billboards) + { + const NzMaterial* mat = pair.first; + auto& container = pair.second; + + if (mat->IsEnabled(nzRendererParameter_Blend)) + { + std::sort(container.begin(), container.end(), [&viewerPos](const BillboardData& data1, const BillboardData& data2) + { + return viewerPos.SquaredDistance(data1.center) > viewerPos.SquaredDistance(data2.center); + }); + } + } } bool NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int index) @@ -210,8 +260,13 @@ bool NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int ind } case ResourceType_Material: - opaqueModels.erase(static_cast(resource)); + { + const NzMaterial* material = static_cast(resource); + + billboards.erase(material); + opaqueModels.erase(material); break; + } case ResourceType_VertexBuffer: { @@ -299,7 +354,6 @@ bool NzForwardRenderQueue::BatchedModelMaterialComparator::operator()(const NzMa const NzShader* shader1 = mat1->GetShaderInstance()->GetShader(); const NzShader* shader2 = mat2->GetShaderInstance()->GetShader(); - if (shader1 != shader2) return shader1 < shader2; @@ -320,7 +374,6 @@ bool NzForwardRenderQueue::BatchedSpriteMaterialComparator::operator()(const NzM const NzShader* shader1 = mat1->GetShaderInstance()->GetShader(); const NzShader* shader2 = mat2->GetShaderInstance()->GetShader(); - if (shader1 != shader2) return shader1 < shader2; diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 68726c809..44cd9d172 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -3,6 +3,8 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include +#include #include #include #include @@ -22,46 +24,36 @@ namespace { - static NzIndexBuffer* s_indexBuffer = nullptr; - unsigned int s_maxSprites = 8192; - - NzIndexBuffer* BuildIndexBuffer() + struct BillboardPoint { - std::unique_ptr indexBuffer(new NzIndexBuffer(false, s_maxSprites*6, nzBufferStorage_Hardware, nzBufferUsage_Static)); - indexBuffer->SetPersistent(false); + NzColor color; + NzVector3f position; + NzVector2f size; + NzVector2f sinCos; // doit suivre size + NzVector2f uv; + }; - NzBufferMapper mapper(indexBuffer.get(), nzBufferAccess_WriteOnly); - nzUInt16* indices = static_cast(mapper.GetPointer()); + struct SpriteVertex + { + NzColor color; + NzVector3f position; + NzVector2f uv; + }; - for (unsigned int i = 0; i < s_maxSprites; ++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; - } - - return indexBuffer.release(); - } + unsigned int s_maxBillboardSprites = std::numeric_limits::max()/6; + unsigned int s_vertexBufferSize = 1024*1024; // 1 MB } NzForwardRenderTechnique::NzForwardRenderTechnique() : -m_spriteBuffer(NzVertexDeclaration::Get(nzVertexLayout_XYZ_UV), s_maxSprites*4, nzBufferStorage_Hardware, nzBufferUsage_Dynamic), +m_vertexBuffer(nzBufferType_Vertex), m_maxLightPassPerObject(3) { - if (!s_indexBuffer) - s_indexBuffer = BuildIndexBuffer(); + NzErrorFlags flags(nzErrorFlag_ThrowException, true); - m_indexBuffer = s_indexBuffer; -} + m_vertexBuffer.Create(s_vertexBufferSize, nzBufferStorage_Hardware, nzBufferUsage_Dynamic); -NzForwardRenderTechnique::~NzForwardRenderTechnique() -{ - if (m_indexBuffer.Reset()) - s_indexBuffer = nullptr; + m_billboardPointBuffer.Reset(&s_billboardVertexDeclaration, &m_vertexBuffer); + m_spriteBuffer.Reset(&s_spriteDeclaration, &m_vertexBuffer); } void NzForwardRenderTechnique::Clear(const NzScene* scene) const @@ -87,6 +79,9 @@ bool NzForwardRenderTechnique::Draw(const NzScene* scene) const if (!m_renderQueue.transparentModels.empty()) DrawTransparentModels(scene); + if (!m_renderQueue.billboards.empty()) + DrawBillboards(scene); + if (!m_renderQueue.sprites.empty()) DrawSprites(scene); @@ -162,6 +157,208 @@ void NzForwardRenderTechnique::SetMaxLightPassPerObject(unsigned int passCount) m_maxLightPassPerObject = passCount; } +bool NzForwardRenderTechnique::Initialize() +{ + try + { + NzErrorFlags flags(nzErrorFlag_ThrowException, true); + + s_quadIndexBuffer.Reset(false, s_maxBillboardSprites*6, nzBufferStorage_Hardware, nzBufferUsage_Static); + + NzBufferMapper mapper(s_quadIndexBuffer, nzBufferAccess_WriteOnly); + nzUInt16* indices = static_cast(mapper.GetPointer()); + + for (unsigned int i = 0; i < s_maxBillboardSprites; ++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, nzBufferStorage_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)); + + s_spriteDeclaration.EnableComponent(nzVertexComponent_Color, nzComponentType_Color, NzOffsetOf(SpriteVertex, color)); + s_spriteDeclaration.EnableComponent(nzVertexComponent_Position, nzComponentType_Float3, NzOffsetOf(SpriteVertex, position)); + s_spriteDeclaration.EnableComponent(nzVertexComponent_TexCoord, nzComponentType_Float2, NzOffsetOf(SpriteVertex, uv)); + + } + catch (const std::exception& e) + { + NazaraError("Failed to initialise: " + NzString(e.what())); + return false; + } + + return true; +} + +void NzForwardRenderTechnique::Uninitialize() +{ + s_quadIndexBuffer.Reset(); +} + +void NzForwardRenderTechnique::DrawBillboards(const NzScene* scene) const +{ + NzAbstractViewer* viewer = scene->GetViewer(); + const NzShader* lastShader = nullptr; + + 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& billboardVector = matIt.second; + + unsigned int billboardCount = billboardVector.size(); + if (billboardCount > 0) + { + // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + const NzShader* shader = material->Apply(nzShaderFlags_Billboard | nzShaderFlags_Instancing | nzShaderFlags_VertexColor); + + // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas + if (shader != lastShader) + { + // Couleur ambiante de la scène + shader->SendColor(shader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); + // Position de la caméra + shader->SendVector(shader->GetUniformLocation(nzShaderUniform_EyePosition), viewer->GetEyePosition()); + + lastShader = shader; + } + + 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 + { + NzRenderer::SetIndexBuffer(&s_quadIndexBuffer); + NzRenderer::SetVertexBuffer(&m_billboardPointBuffer); + + for (auto& matIt : m_renderQueue.billboards) + { + const NzMaterial* material = matIt.first; + auto& billboardVector = matIt.second; + + unsigned int billboardCount = billboardVector.size(); + if (billboardCount > 0) + { + // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + const NzShader* shader = material->Apply(nzShaderFlags_Billboard | nzShaderFlags_VertexColor); + + // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas + if (shader != lastShader) + { + // Couleur ambiante de la scène + shader->SendColor(shader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); + // Position de la caméra + shader->SendVector(shader->GetUniformLocation(nzShaderUniform_EyePosition), viewer->GetEyePosition()); + + lastShader = shader; + } + + const NzForwardRenderQueue::BillboardData* data = &billboardVector[0]; + unsigned int maxBillboardPerDraw = std::min(s_maxBillboardSprites, 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 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++; + } + + vertexMapper.Unmap(); + + NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, renderedBillboardCount*6); + } + while (billboardCount > 0); + + billboardVector.clear(); + } + } + } +} + void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const { NzAbstractViewer* viewer = scene->GetViewer(); @@ -378,7 +575,7 @@ void NzForwardRenderTechnique::DrawSprites(const NzScene* scene) const NzAbstractViewer* viewer = scene->GetViewer(); const NzShader* lastShader = nullptr; - NzRenderer::SetIndexBuffer(m_indexBuffer); + NzRenderer::SetIndexBuffer(&s_quadIndexBuffer); NzRenderer::SetMatrix(nzMatrixType_World, NzMatrix4f::Identity()); NzRenderer::SetVertexBuffer(&m_spriteBuffer); @@ -391,7 +588,7 @@ void NzForwardRenderTechnique::DrawSprites(const NzScene* scene) const if (spriteCount > 0) { // On commence par appliquer du matériau (et récupérer le shader ainsi activé) - const NzShader* shader = material->Apply(); + const NzShader* shader = material->Apply(nzShaderFlags_VertexColor); // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas if (shader != lastShader) @@ -405,36 +602,47 @@ void NzForwardRenderTechnique::DrawSprites(const NzScene* scene) const } const NzSprite** spritePtr = &spriteVector[0]; + unsigned int maxSpritePerDraw = std::min(s_maxBillboardSprites, m_spriteBuffer.GetVertexCount()/4); do { - unsigned int renderedSpriteCount = std::min(spriteCount, 64U); + unsigned int renderedSpriteCount = std::min(spriteCount, maxSpritePerDraw); spriteCount -= renderedSpriteCount; NzBufferMapper vertexMapper(m_spriteBuffer, nzBufferAccess_DiscardAndWrite, 0, renderedSpriteCount*4); - NzVertexStruct_XYZ_UV* vertices = reinterpret_cast(vertexMapper.GetPointer()); + SpriteVertex* vertices = reinterpret_cast(vertexMapper.GetPointer()); for (unsigned int i = 0; i < renderedSpriteCount; ++i) { const NzSprite* sprite = *spritePtr++; + + const NzColor& color = sprite->GetColor(); const NzRectf& textureCoords = sprite->GetTextureCoords(); - const NzVector2f& halfSize = sprite->GetSize()*0.5f; - NzVector3f center = sprite->GetPosition(); + NzVector2f size = sprite->GetSize(); + NzVector3f origin = sprite->GetPosition(); + NzVector3f scale = sprite->GetScale(); NzQuaternionf rotation = sprite->GetRotation(); - vertices->position = center + rotation * NzVector3f(-halfSize.x, -halfSize.y, 0.f); - vertices->uv.Set(textureCoords.x, textureCoords.y + textureCoords.height); - vertices++; + size.x *= scale.x; + size.y *= scale.y; - vertices->position = center + rotation * NzVector3f(halfSize.x, -halfSize.y, 0.f); - vertices->uv.Set(textureCoords.width, textureCoords.y + textureCoords.height); - vertices++; - - vertices->position = center + rotation * NzVector3f(-halfSize.x, halfSize.y, 0.f); + vertices->color = color; + vertices->position = origin; vertices->uv.Set(textureCoords.x, textureCoords.y); vertices++; - vertices->position = center + rotation * NzVector3f(halfSize.x, halfSize.y, 0.f); - vertices->uv.Set(textureCoords.width, textureCoords.y); + vertices->color = color; + vertices->position = origin + rotation * NzVector3f(size.x, 0.f, 0.f); + vertices->uv.Set(textureCoords.x + textureCoords.width, textureCoords.y); + vertices++; + + vertices->color = color; + vertices->position = origin + rotation * NzVector3f(0.f, size.y, 0.f); + vertices->uv.Set(textureCoords.x, textureCoords.y + textureCoords.height); + vertices++; + + vertices->color = color; + vertices->position = origin + rotation * NzVector3f(size.x, size.y, 0.f); + vertices->uv.Set(textureCoords.x + textureCoords.width, textureCoords.y + textureCoords.height); vertices++; } @@ -557,3 +765,9 @@ const NzForwardRenderTechnique::LightUniforms* NzForwardRenderTechnique::GetLigh return &(pair.first->second); } } + +NzIndexBuffer NzForwardRenderTechnique::s_quadIndexBuffer; +NzVertexBuffer NzForwardRenderTechnique::s_quadVertexBuffer; +NzVertexDeclaration NzForwardRenderTechnique::s_billboardInstanceDeclaration; +NzVertexDeclaration NzForwardRenderTechnique::s_billboardVertexDeclaration; +NzVertexDeclaration NzForwardRenderTechnique::s_spriteDeclaration; diff --git a/src/Nazara/Graphics/Graphics.cpp b/src/Nazara/Graphics/Graphics.cpp index 1058e484b..f1e8e33dc 100644 --- a/src/Nazara/Graphics/Graphics.cpp +++ b/src/Nazara/Graphics/Graphics.cpp @@ -65,12 +65,22 @@ bool NzGraphics::Initialize() NzLoaders_Texture_Register(); // RenderTechniques + if (!NzForwardRenderTechnique::Initialize()) + { + NazaraError("Failed to initialize Forward Rendering"); + return false; + } + NzRenderTechniques::Register(NzRenderTechniques::ToString(nzRenderTechniqueType_BasicForward), 0, []() -> NzAbstractRenderTechnique* { return new NzForwardRenderTechnique; }); if (NzDeferredRenderTechnique::IsSupported()) { - NzDeferredRenderTechnique::Initialize(); - NzRenderTechniques::Register(NzRenderTechniques::ToString(nzRenderTechniqueType_DeferredShading), 20, []() -> NzAbstractRenderTechnique* { return new NzDeferredRenderTechnique; }); + if (NzDeferredRenderTechnique::Initialize()) + NzRenderTechniques::Register(NzRenderTechniques::ToString(nzRenderTechniqueType_DeferredShading), 20, []() -> NzAbstractRenderTechnique* { return new NzDeferredRenderTechnique; }); + else + { + NazaraWarning("Failed to initialize Deferred Rendering"); + } } onExit.Reset(); @@ -104,6 +114,7 @@ void NzGraphics::Uninitialize() NzLoaders_Texture_Unregister(); NzDeferredRenderTechnique::Uninitialize(); + NzForwardRenderTechnique::Uninitialize(); NzMaterial::Uninitialize(); NzParticleDeclaration::Uninitialize(); NzSkinningManager::Uninitialize(); From bf2d39541c75af4d1b6c7c9965ce6774198908a4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 3 Sep 2014 13:29:40 +0200 Subject: [PATCH 057/233] Fixed cubemaps rendering (Skyboxes) Former-commit-id: a8d065cbdf8bdbde55547739e53b4daa6ce2969d --- src/Nazara/Graphics/SkyboxBackground.cpp | 4 ++-- src/Nazara/Renderer/OpenGL.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Nazara/Graphics/SkyboxBackground.cpp b/src/Nazara/Graphics/SkyboxBackground.cpp index d4347d25f..d1d7b8ca3 100644 --- a/src/Nazara/Graphics/SkyboxBackground.cpp +++ b/src/Nazara/Graphics/SkyboxBackground.cpp @@ -87,7 +87,7 @@ namespace "void main()\n" "{\n" " gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0);\n" - " vTexCoord = vec3(VertexPosition.x, -VertexPosition.y, -VertexPosition.z);\n" + " vTexCoord = vec3(VertexPosition.x, VertexPosition.y, -VertexPosition.z);\n" "}\n"; const char* vertexSource140 = @@ -102,7 +102,7 @@ namespace "void main()\n" "{\n" " gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0);\n" - " vTexCoord = vec3(VertexPosition.x, -VertexPosition.y, -VertexPosition.z);\n" + " vTexCoord = vec3(VertexPosition.x, VertexPosition.y, -VertexPosition.z);\n" "}\n"; ///TODO: Remplacer ça par des ShaderNode diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index 476800edf..ef9e096d9 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -1941,8 +1941,8 @@ GLenum NzOpenGL::CubemapFace[] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X, // nzCubemapFace_PositiveX GL_TEXTURE_CUBE_MAP_NEGATIVE_X, // nzCubemapFace_NegativeX - GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, // nzCubemapFace_PositiveY (Inversion pour les standards OpenGL) - GL_TEXTURE_CUBE_MAP_POSITIVE_Y, // nzCubemapFace_NegativeY (Inversion pour les standards OpenGL) + GL_TEXTURE_CUBE_MAP_POSITIVE_Y, // nzCubemapFace_PositiveY + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, // nzCubemapFace_NegativeY GL_TEXTURE_CUBE_MAP_POSITIVE_Z, // nzCubemapFace_PositiveZ GL_TEXTURE_CUBE_MAP_NEGATIVE_Z // nzCubemapFace_NegativeZ }; From 00a35cd565e5df54e72282ef7569ccf523282eb7 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 3 Sep 2014 13:29:54 +0200 Subject: [PATCH 058/233] Removed useless enum Former-commit-id: b342be41eda3271320954a0279cf0a2afdfcd8e2 --- include/Nazara/Renderer/Enums.hpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/include/Nazara/Renderer/Enums.hpp b/include/Nazara/Renderer/Enums.hpp index 229800e9b..fa9fc9a3d 100644 --- a/include/Nazara/Renderer/Enums.hpp +++ b/include/Nazara/Renderer/Enums.hpp @@ -185,16 +185,6 @@ enum nzSamplerWrap nzSamplerWrap_Max = nzSamplerWrap_Repeat }; -enum nzShaderTarget -{ - nzShaderTarget_FullscreenQuad, - nzShaderTarget_Model, - nzShaderTarget_None, - nzShaderTarget_Sprite, - - nzShaderTarget_Max = nzShaderTarget_Sprite -}; - enum nzShaderUniform { nzShaderUniform_EyePosition, From 1b949777222112da1a046bd4e421baca94867ac4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 3 Sep 2014 13:30:12 +0200 Subject: [PATCH 059/233] Added Quaternion::Normalize static method Former-commit-id: a4530be00673dec5b9731b75fb4edbac7ccd69d5 --- include/Nazara/Math/Quaternion.hpp | 1 + include/Nazara/Math/Quaternion.inl | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/include/Nazara/Math/Quaternion.hpp b/include/Nazara/Math/Quaternion.hpp index 4521ea909..35e6a7b65 100644 --- a/include/Nazara/Math/Quaternion.hpp +++ b/include/Nazara/Math/Quaternion.hpp @@ -76,6 +76,7 @@ template class NzQuaternion static NzQuaternion Identity(); static NzQuaternion Lerp(const NzQuaternion& from, const NzQuaternion& to, T interpolation); + static NzQuaternion Normalize(const NzQuaternion& quat, T* length = nullptr); static NzQuaternion RotationBetween(const NzVector3& from, const NzVector3& to); static NzQuaternion Slerp(const NzQuaternion& from, const NzQuaternion& to, T interpolation); static NzQuaternion Zero(); diff --git a/include/Nazara/Math/Quaternion.inl b/include/Nazara/Math/Quaternion.inl index 76290c0c7..8348a5e2f 100644 --- a/include/Nazara/Math/Quaternion.inl +++ b/include/Nazara/Math/Quaternion.inl @@ -408,6 +408,12 @@ NzQuaternion NzQuaternion::Lerp(const NzQuaternion& from, const NzQuaterni return interpolated; } +template +NzQuaternion NzQuaternion::Normalize(const NzQuaternion& quat, T* length) +{ + return quat.GetNormal(length); +} + template NzQuaternion NzQuaternion::RotationBetween(const NzVector3& from, const NzVector3& to) { From e32c0c626e869c80cad7aa0707d587f18d364173 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 3 Sep 2014 13:30:21 +0200 Subject: [PATCH 060/233] Fixed global math include Former-commit-id: 0f1871a2ecf1e8b94d63612c7357d6fc0ab0287b --- include/Nazara/Math.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Math.hpp b/include/Nazara/Math.hpp index e70158c4a..b80211a25 100644 --- a/include/Nazara/Math.hpp +++ b/include/Nazara/Math.hpp @@ -30,7 +30,7 @@ #ifndef NAZARA_GLOBAL_MATH_HPP #define NAZARA_GLOBAL_MATH_HPP -#include +#include #include #include #include From 522ceb1e308db346f3c76b4d8698a3adc41a4fdd Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 3 Sep 2014 13:32:37 +0200 Subject: [PATCH 061/233] Improved SparsePtr class Added implicit conversion from a normal pointer to a sparse pointer Added implicit conversion to boolean Added implicit conversion to normal pointer Added support for const pointers Renamed Get/Set to GetPtr/SetPtr Former-commit-id: 32d5d2ec6a7b296c5b89b722de9ca142d5c64aae --- include/Nazara/Core/SparsePtr.hpp | 21 +++++++++-- include/Nazara/Core/SparsePtr.inl | 62 ++++++++++++++++++++++++++----- 2 files changed, 70 insertions(+), 13 deletions(-) diff --git a/include/Nazara/Core/SparsePtr.hpp b/include/Nazara/Core/SparsePtr.hpp index eec23149c..aff3460ac 100644 --- a/include/Nazara/Core/SparsePtr.hpp +++ b/include/Nazara/Core/SparsePtr.hpp @@ -10,21 +10,34 @@ ///FIXME: Est-ce que SparsePtr est vraiment le meilleur nom pour cette classe ? #include +#include template class NzSparsePtr { public: + using BytePtr = typename std::conditional::value, const nzUInt8*, nzUInt8*>::type; + using VoidPtr = typename std::conditional::value, const void*, void*>::type; + NzSparsePtr(); - NzSparsePtr(void* ptr, unsigned int stride); + NzSparsePtr(T* ptr); + NzSparsePtr(VoidPtr ptr, unsigned int stride); NzSparsePtr(const NzSparsePtr& ptr) = default; ~NzSparsePtr() = default; - void* Get() const; + VoidPtr GetPtr() const; unsigned int GetStride() const; - void Set(void* ptr); + + void Reset(); + void Reset(T* ptr); + void Reset(VoidPtr ptr, unsigned int stride); + void Reset(const NzSparsePtr& ptr); + + void SetPtr(VoidPtr ptr); void SetStride(unsigned int stride); + operator bool() const; + operator T*() const; T& operator*() const; T& operator->() const; T& operator[](unsigned int index) const; @@ -51,7 +64,7 @@ class NzSparsePtr NzSparsePtr& operator=(const NzSparsePtr& ptr) = default; private: - nzUInt8* m_ptr; + BytePtr m_ptr; unsigned int m_stride; }; diff --git a/include/Nazara/Core/SparsePtr.inl b/include/Nazara/Core/SparsePtr.inl index f769e577e..b98599bfd 100644 --- a/include/Nazara/Core/SparsePtr.inl +++ b/include/Nazara/Core/SparsePtr.inl @@ -5,21 +5,25 @@ #include template -NzSparsePtr::NzSparsePtr() : -m_ptr(nullptr), -m_stride(0) +NzSparsePtr::NzSparsePtr() { + Reset(); } template -NzSparsePtr::NzSparsePtr(void* ptr, unsigned int stride) +NzSparsePtr::NzSparsePtr(T* ptr) { - Set(ptr); - SetStride(stride); + Reset(ptr); } template -void* NzSparsePtr::Get() const +NzSparsePtr::NzSparsePtr(VoidPtr ptr, unsigned int stride) +{ + Reset(ptr, stride); +} + +template +typename NzSparsePtr::VoidPtr NzSparsePtr::GetPtr() const { return m_ptr; } @@ -31,9 +35,37 @@ unsigned int NzSparsePtr::GetStride() const } template -void NzSparsePtr::Set(void* ptr) +void NzSparsePtr::Reset() { - m_ptr = reinterpret_cast(ptr); + SetPtr(nullptr); + SetStride(0); +} + +template +void NzSparsePtr::Reset(T* ptr) +{ + SetPtr(ptr); + SetStride(sizeof(T)); +} + +template +void NzSparsePtr::Reset(VoidPtr ptr, unsigned int stride) +{ + SetPtr(ptr); + SetStride(stride); +} + +template +void NzSparsePtr::Reset(const NzSparsePtr& ptr) +{ + SetPtr(ptr.GetPtr()); + SetStride(ptr.GetStride()); +} + +template +void NzSparsePtr::SetPtr(VoidPtr ptr) +{ + m_ptr = reinterpret_cast(ptr); } template @@ -42,6 +74,18 @@ void NzSparsePtr::SetStride(unsigned int stride) m_stride = stride; } +template +NzSparsePtr::operator bool() const +{ + return m_ptr != nullptr; +} + +template +NzSparsePtr::operator T*() const +{ + return reinterpret_cast(m_ptr); +} + template T& NzSparsePtr::operator*() const { From ce2aa91b327a2de9db24ab71626dd9833c04ce94 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 3 Sep 2014 13:35:10 +0200 Subject: [PATCH 063/233] Fixed PCX loader crash Former-commit-id: 3c0734a67d271a68f79a56e986ebd96552ae6d4b --- src/Nazara/Utility/Loaders/PCX/Loader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nazara/Utility/Loaders/PCX/Loader.cpp b/src/Nazara/Utility/Loaders/PCX/Loader.cpp index 6f3558f95..d0b75dff2 100644 --- a/src/Nazara/Utility/Loaders/PCX/Loader.cpp +++ b/src/Nazara/Utility/Loaders/PCX/Loader.cpp @@ -287,7 +287,7 @@ namespace /* for each color plane */ for (int c = 0; c < 3; ++c) { - nzUInt8* ptr = &pixels[y * width * 4]; + nzUInt8* ptr = &pixels[y * width * 3]; int bytes = header.bytesPerScanLine; /* decode line number y */ @@ -324,7 +324,7 @@ namespace } default: - NazaraError("Failed to load " + NzString::Number(bitCount) + " bitcount pcx files"); + NazaraError("Unsupported " + NzString::Number(bitCount) + " bitcount for pcx files"); return false; } From 68bd3304c6f2927beb7ba3d26faf4fddc918a1b4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 6 Sep 2014 11:52:37 +0200 Subject: [PATCH 064/233] Renamed Degrees|Radians functions to From[Degrees|Radians] Also added To[Degrees|Radians] functions Former-commit-id: b7445a42e5ee88319009db9d664d8d9f8fe88c18 --- include/Nazara/Math/Algorithm.hpp | 6 ++-- include/Nazara/Math/Algorithm.inl | 48 +++++++++++++++++++++--------- include/Nazara/Math/Quaternion.inl | 10 +++---- include/Nazara/Math/Vector2.inl | 2 +- include/Nazara/Math/Vector3.inl | 2 +- 5 files changed, 45 insertions(+), 23 deletions(-) diff --git a/include/Nazara/Math/Algorithm.hpp b/include/Nazara/Math/Algorithm.hpp index 46d11645f..c4420f621 100644 --- a/include/Nazara/Math/Algorithm.hpp +++ b/include/Nazara/Math/Algorithm.hpp @@ -22,7 +22,8 @@ template T NzApproach(T value, T objective, T increment); template constexpr T NzClamp(T value, T min, T max); -template constexpr T NzDegrees(T degrees); +template constexpr T NzFromDegrees(T degrees); +template constexpr T NzFromRadians(T radians); template constexpr T NzDegreeToRadian(T degrees); unsigned int NzGetNearestPowerOfTwo(unsigned int number); unsigned int NzGetNumberLength(signed char number); @@ -40,9 +41,10 @@ template T NzMultiplyAdd(T x, T y, T z); template T NzNormalizeAngle(T angle); template bool NzNumberEquals(T a, T b, T maxDifference = std::numeric_limits::epsilon()); NzString NzNumberToString(long long number, nzUInt8 radix = 10); -template T NzRadians(T radians); template T NzRadianToDegree(T radians); long long NzStringToNumber(NzString str, nzUInt8 radix = 10, bool* ok = nullptr); +template constexpr T NzToDegrees(T angle); +template constexpr T NzToRadians(T angle); #include diff --git a/include/Nazara/Math/Algorithm.inl b/include/Nazara/Math/Algorithm.inl index 7f6884da8..49b54be32 100644 --- a/include/Nazara/Math/Algorithm.inl +++ b/include/Nazara/Math/Algorithm.inl @@ -31,7 +31,13 @@ constexpr T NzClamp(T value, T min, T max) } template -constexpr T NzDegrees(T degrees) +constexpr T NzDegreeToRadian(T degrees) +{ + return degrees * F(M_PI/180.0); +} + +template +constexpr T NzFromDegrees(T degrees) { #if NAZARA_MATH_ANGLE_RADIAN return NzDegreeToRadian(degrees); @@ -41,9 +47,13 @@ constexpr T NzDegrees(T degrees) } template -constexpr T NzDegreeToRadian(T degrees) +constexpr T NzFromRadians(T radians) { - return degrees * F(M_PI/180.0); + #if NAZARA_MATH_ANGLE_RADIAN + return radians; + #else + return NzRadianToDegree(radians); + #endif } inline unsigned int NzGetNearestPowerOfTwo(unsigned int number) @@ -51,7 +61,7 @@ inline unsigned int NzGetNearestPowerOfTwo(unsigned int number) ///TODO: Marquer comme constexpr en C++14 unsigned int x = 1; // Tant que x est plus petit que n, on décale ses bits vers la gauche, ce qui revient à multiplier par deux - while(x <= number) + while (x <= number) x <<= 1; return x; @@ -268,16 +278,6 @@ inline NzString NzNumberToString(long long number, nzUInt8 radix) return str.Reversed(); } -template -T NzRadians(T radians) -{ - #if NAZARA_MATH_ANGLE_RADIAN - return radians; - #else - return NzRadianToDegree(radians); - #endif -} - template T NzRadianToDegree(T radians) { @@ -333,6 +333,26 @@ inline long long NzStringToNumber(NzString str, nzUInt8 radix, bool* ok) return (negative) ? -static_cast(total) : total; } +template +constexpr T NzToDegrees(T angle) +{ + #if NAZARA_MATH_ANGLE_RADIAN + return NzRadianToDegree(angle); + #else + return angle; + #endif +} + +template +constexpr T NzToRadians(T angle) +{ + #if NAZARA_MATH_ANGLE_RADIAN + return angle; + #else + return NzDegreeToRadian(angle); + #endif +} + #undef F2 #undef F diff --git a/include/Nazara/Math/Quaternion.inl b/include/Nazara/Math/Quaternion.inl index 8348a5e2f..e62ed166f 100644 --- a/include/Nazara/Math/Quaternion.inl +++ b/include/Nazara/Math/Quaternion.inl @@ -265,14 +265,14 @@ NzEulerAngles NzQuaternion::ToEulerAngles() const T test = x*y + z*w; if (test > F(0.499)) // singularity at north pole - return NzEulerAngles(NzDegrees(F(90.0)), NzRadians(F(2.0) * std::atan2(x, w)), F(0.0)); + return NzEulerAngles(NzFromDegrees(F(90.0)), NzFromRadians(F(2.0) * std::atan2(x, w)), F(0.0)); if (test < F(-0.499)) - return NzEulerAngles(NzDegrees(F(-90.0)), NzRadians(F(-2.0) * std::atan2(x, w)), F(0.0)); + return NzEulerAngles(NzFromDegrees(F(-90.0)), NzFromRadians(F(-2.0) * std::atan2(x, w)), F(0.0)); - return NzEulerAngles(NzRadians(std::atan2(F(2.0)*x*w - F(2.0)*y*z, F(1.0) - F(2.0)*x* - F(2.0)*z*z)), - NzRadians(std::atan2(F(2.0)*y*w - F(2.0)*x*z, F(1.0) - F(2.0)*y*y - F(2.0)*z*z)), - NzRadians(std::asin(F(2.0)*test))); + return NzEulerAngles(NzFromRadians(std::atan2(F(2.0)*x*w - F(2.0)*y*z, F(1.0) - F(2.0)*x* - F(2.0)*z*z)), + NzFromRadians(std::atan2(F(2.0)*y*w - F(2.0)*x*z, F(1.0) - F(2.0)*y*y - F(2.0)*z*z)), + NzFromRadians(std::asin(F(2.0)*test))); } template diff --git a/include/Nazara/Math/Vector2.inl b/include/Nazara/Math/Vector2.inl index 227d95425..01d93a6fb 100644 --- a/include/Nazara/Math/Vector2.inl +++ b/include/Nazara/Math/Vector2.inl @@ -57,7 +57,7 @@ inline unsigned int NzVector2::AbsDotProduct(const NzVector2 T NzVector2::AngleBetween(const NzVector2& vec) const { - return NzRadians(std::atan2(vec.y, vec.x) - std::atan2(y, x)); + return NzFromRadians(std::atan2(vec.y, vec.x) - std::atan2(y, x)); } template diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index f300330b8..79b886728 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -77,7 +77,7 @@ T NzVector3::AngleBetween(const NzVector3& vec) const #endif T alpha = DotProduct(vec)/divisor; - return NzRadians(std::acos(NzClamp(alpha, F(-1.0), F(1.0)))); + return NzFromRadians(std::acos(NzClamp(alpha, F(-1.0), F(1.0)))); } template From 04be41082c638147398e074c62f85c721087aed5 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 6 Sep 2014 11:59:57 +0200 Subject: [PATCH 065/233] Added A LOT of oveloads to AbstractRenderQueue::AddBillboards Former-commit-id: 51b73a110e61cee7ad8fca42b10afd59363de809 --- .../Nazara/Graphics/AbstractRenderQueue.hpp | 9 + .../Nazara/Graphics/DeferredRenderQueue.hpp | 7 + .../Nazara/Graphics/ForwardRenderQueue.hpp | 7 + src/Nazara/Graphics/DeferredRenderQueue.cpp | 39 +++- src/Nazara/Graphics/ForwardRenderQueue.cpp | 206 ++++++++++++++++++ 5 files changed, 266 insertions(+), 2 deletions(-) diff --git a/include/Nazara/Graphics/AbstractRenderQueue.hpp b/include/Nazara/Graphics/AbstractRenderQueue.hpp index 77e7942e5..f3a209dff 100644 --- a/include/Nazara/Graphics/AbstractRenderQueue.hpp +++ b/include/Nazara/Graphics/AbstractRenderQueue.hpp @@ -27,8 +27,17 @@ class NAZARA_API NzAbstractRenderQueue : NzNonCopyable NzAbstractRenderQueue() = default; virtual ~NzAbstractRenderQueue(); + // Je ne suis vraiment pas fan du nombre de surcharges pour AddBillboards, + // mais je n'ai pas d'autre solution tout aussi performante pour le moment... virtual void AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos = NzVector2f(0.f, 1.f), const NzColor& color = NzColor::White) = 0; virtual void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr = nullptr, NzSparsePtr colorPtr = nullptr) = 0; + virtual void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) = 0; + virtual void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr = nullptr) = 0; + virtual void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) = 0; + virtual void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr = nullptr, NzSparsePtr colorPtr = nullptr) = 0; + virtual void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) = 0; + virtual void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr = nullptr) = 0; + virtual void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) = 0; virtual void AddDrawable(const NzDrawable* drawable) = 0; virtual void AddLight(const NzLight* light) = 0; virtual void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) = 0; diff --git a/include/Nazara/Graphics/DeferredRenderQueue.hpp b/include/Nazara/Graphics/DeferredRenderQueue.hpp index 3e610b758..ec022e5cb 100644 --- a/include/Nazara/Graphics/DeferredRenderQueue.hpp +++ b/include/Nazara/Graphics/DeferredRenderQueue.hpp @@ -30,6 +30,13 @@ class NAZARA_API NzDeferredRenderQueue : public NzAbstractRenderQueue, NzResourc 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 AddLight(const NzLight* light) override; void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) override; diff --git a/include/Nazara/Graphics/ForwardRenderQueue.hpp b/include/Nazara/Graphics/ForwardRenderQueue.hpp index 2533e22a5..a0386f532 100644 --- a/include/Nazara/Graphics/ForwardRenderQueue.hpp +++ b/include/Nazara/Graphics/ForwardRenderQueue.hpp @@ -32,6 +32,13 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResource 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 AddLight(const NzLight* light) override; void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) override; diff --git a/src/Nazara/Graphics/DeferredRenderQueue.cpp b/src/Nazara/Graphics/DeferredRenderQueue.cpp index db6ce13fd..985a0e96e 100644 --- a/src/Nazara/Graphics/DeferredRenderQueue.cpp +++ b/src/Nazara/Graphics/DeferredRenderQueue.cpp @@ -11,6 +11,8 @@ #include #include +///TODO: Rendre les billboards via Deferred Shading si possible + namespace { enum ResourceType @@ -33,16 +35,49 @@ NzDeferredRenderQueue::~NzDeferredRenderQueue() void NzDeferredRenderQueue::AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos, const NzColor& color) { - ///TODO: Rendre les billboards via Deferred Shading si possible m_forwardQueue->AddBillboard(material, position, size, sinCos, color); } void NzDeferredRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr colorPtr) { - ///TODO: Rendre les billboards via Deferred Shading si possible m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); } +void NzDeferredRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) +{ + m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); +} + +void NzDeferredRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr) +{ + m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, anglePtr, colorPtr); +} + +void NzDeferredRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) +{ + m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, anglePtr, alphaPtr); +} + +void NzDeferredRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr colorPtr) +{ + m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); +} + +void NzDeferredRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) +{ + m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); +} + +void NzDeferredRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr) +{ + m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, anglePtr, colorPtr); +} + +void NzDeferredRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) +{ + m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, anglePtr, alphaPtr); +} + void NzDeferredRenderQueue::AddDrawable(const NzDrawable* drawable) { m_forwardQueue->AddDrawable(drawable); diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index fd867e45c..cc0a4d0e1 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -58,6 +58,212 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in } } +void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) +{ + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seont 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) + 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 + + std::vector& billboardVec = billboards[material]; + unsigned int prevSize = billboardVec.size(); + billboardVec.resize(prevSize + count); + + BillboardData* billboardData = &billboardVec[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 NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr) +{ + ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seont 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 + + std::vector& billboardVec = billboards[material]; + unsigned int prevSize = billboardVec.size(); + billboardVec.resize(prevSize + count); + + BillboardData* billboardData = &billboardVec[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 NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) +{ + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seont 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 + + float defaultAlpha = 1.f; + + if (!alphaPtr) + alphaPtr.Reset(&defaultAlpha, 0); // Pareil + + std::vector& billboardVec = billboards[material]; + unsigned int prevSize = billboardVec.size(); + billboardVec.resize(prevSize + count); + + BillboardData* billboardData = &billboardVec[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 NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr colorPtr) +{ + ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seont 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) + 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 + + std::vector& billboardVec = billboards[material]; + unsigned int prevSize = billboardVec.size(); + billboardVec.resize(prevSize + count); + + BillboardData* billboardData = &billboardVec[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + billboardData->center = *positionPtr++; + billboardData->color = *colorPtr++; + billboardData->sinCos = *sinCosPtr++; + billboardData->size.Set(*sizePtr++); + billboardData++; + } +} + +void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) +{ + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seont 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) + 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 + + std::vector& billboardVec = billboards[material]; + unsigned int prevSize = billboardVec.size(); + billboardVec.resize(prevSize + count); + + BillboardData* billboardData = &billboardVec[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 NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr) +{ + ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seont 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 + + std::vector& billboardVec = billboards[material]; + unsigned int prevSize = billboardVec.size(); + billboardVec.resize(prevSize + count); + + BillboardData* billboardData = &billboardVec[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 NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) +{ + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seont 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 + + float defaultAlpha = 1.f; + + if (!alphaPtr) + alphaPtr.Reset(&defaultAlpha, 0); // Pareil + + std::vector& billboardVec = billboards[material]; + unsigned int prevSize = billboardVec.size(); + billboardVec.resize(prevSize + count); + + BillboardData* billboardData = &billboardVec[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 NzForwardRenderQueue::AddDrawable(const NzDrawable* drawable) { #if NAZARA_GRAPHICS_SAFE From a008439cde4f93ee469fb9bcdd23c1e57d890fb9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 11 Sep 2014 00:10:24 +0200 Subject: [PATCH 066/233] Added depth sorting attribute to Material class Only works for billboards for now Former-commit-id: 50a46d3266a2e7fc6d75629103ad8b7193b13bf3 --- include/Nazara/Graphics/Material.hpp | 3 +++ src/Nazara/Graphics/ForwardRenderQueue.cpp | 2 +- src/Nazara/Graphics/Material.cpp | 11 +++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index 0f41e0f39..19767f690 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -53,6 +53,7 @@ class NAZARA_API NzMaterial : public NzResource void Enable(nzRendererParameter renderParameter, bool enable); void EnableAlphaTest(bool alphaTest); + void EnableDepthSorting(bool depthSorting); void EnableLighting(bool lighting); void EnableTransform(bool transform); @@ -88,6 +89,7 @@ class NAZARA_API NzMaterial : public NzResource bool HasSpecularMap() const; bool IsAlphaTestEnabled() const; + bool IsDepthSortingEnabled() const; bool IsEnabled(nzRendererParameter renderParameter) const; bool IsLightingEnabled() const; bool IsTransformEnabled() const; @@ -161,6 +163,7 @@ class NAZARA_API NzMaterial : public NzResource NzUberShaderConstRef m_uberShader; mutable ShaderInstance m_shaders[nzShaderFlags_Max+1]; bool m_alphaTestEnabled; + bool m_depthSortingEnabled; bool m_lightingEnabled; bool m_transformEnabled; float m_alphaThreshold; diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index cc0a4d0e1..1ecb307ea 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -434,7 +434,7 @@ void NzForwardRenderQueue::Sort(const NzAbstractViewer* viewer) const NzMaterial* mat = pair.first; auto& container = pair.second; - if (mat->IsEnabled(nzRendererParameter_Blend)) + if (mat->IsDepthSortingEnabled()) { std::sort(container.begin(), container.end(), [&viewerPos](const BillboardData& data1, const BillboardData& data2) { diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 024a0efcf..3e6e600e9 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -152,6 +152,11 @@ void NzMaterial::EnableAlphaTest(bool alphaTest) InvalidateShaders(); } +void NzMaterial::EnableDepthSorting(bool depthSorting) +{ + m_depthSortingEnabled = depthSorting; +} + void NzMaterial::EnableLighting(bool lighting) { m_lightingEnabled = lighting; @@ -320,6 +325,11 @@ bool NzMaterial::IsAlphaTestEnabled() const return m_alphaTestEnabled; } +bool NzMaterial::IsDepthSortingEnabled() const +{ + return m_depthSortingEnabled; +} + bool NzMaterial::IsEnabled(nzRendererParameter parameter) const { #ifdef NAZARA_DEBUG @@ -376,6 +386,7 @@ void NzMaterial::Reset() m_alphaThreshold = 0.2f; m_alphaTestEnabled = false; m_ambientColor = NzColor(128, 128, 128); + m_depthSortingEnabled = false; m_diffuseColor = NzColor::White; m_diffuseSampler = NzTextureSampler(); m_lightingEnabled = true; From b79a4c503c39d296c3af979064fc58addc0e496c Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 14 Sep 2014 19:35:12 +0200 Subject: [PATCH 067/233] Fixed VBO being freed after OpenGL exit Former-commit-id: ddd5fb16baa4371ceb917415bc138590cdc16e26 --- src/Nazara/Graphics/ForwardRenderTechnique.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 44cd9d172..0fd97e4eb 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -223,6 +223,7 @@ bool NzForwardRenderTechnique::Initialize() void NzForwardRenderTechnique::Uninitialize() { s_quadIndexBuffer.Reset(); + s_quadVertexBuffer.Reset(); } void NzForwardRenderTechnique::DrawBillboards(const NzScene* scene) const From 91471e048f95b0dd553ac28ef4bc6b892f0239f6 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 14 Sep 2014 19:50:46 +0200 Subject: [PATCH 068/233] Moved comment Former-commit-id: 63d8ff7494668696550efdf258c372a8e3f3bce4 --- src/Nazara/Renderer/Win32/ContextImpl.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Nazara/Renderer/Win32/ContextImpl.cpp b/src/Nazara/Renderer/Win32/ContextImpl.cpp index 1ae61bd3e..65f9ef98e 100644 --- a/src/Nazara/Renderer/Win32/ContextImpl.cpp +++ b/src/Nazara/Renderer/Win32/ContextImpl.cpp @@ -160,15 +160,15 @@ bool NzContextImpl::Create(NzContextParameters& parameters) { *attrib++ = WGL_CONTEXT_PROFILE_MASK_ARB; *attrib++ = (parameters.compatibilityProfile) ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB : WGL_CONTEXT_CORE_PROFILE_BIT_ARB; + + // Les contextes forward-compatible ne sont plus utilisés pour cette raison : + // http://www.opengl.org/discussion_boards/showthread.php/175052-Forward-compatible-vs-Core-profile } if (parameters.debugMode) { *attrib++ = WGL_CONTEXT_FLAGS_ARB; *attrib++ = WGL_CONTEXT_DEBUG_BIT_ARB; - - // Les contextes forward-compatible ne sont plus utilisés pour cette raison : - // http://www.opengl.org/discussion_boards/showthread.php/175052-Forward-compatible-vs-Core-profile } *attrib++ = 0; From 62dc2dbdf330ca67d4c67923ea7a05d8a58e08e6 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 14 Sep 2014 19:50:57 +0200 Subject: [PATCH 069/233] Added comments Former-commit-id: 4f315d869ae4041a9ae245ef6b181dc6058f6503 --- src/Nazara/Utility/Image.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index d59e3a4c6..5fb12ff6f 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -1247,6 +1247,7 @@ void NzImage::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int src } // Nous n'autorisons pas de modifier plus d'une face du cubemap à la fois (Nous prenons donc la profondeur de base) + ///FIXME: Ce code n'autorise même pas la modification d'une autre face du cubemap Oo if (box.x+box.width > width || box.y+box.height > height || box.z+box.depth > GetLevelSize(m_sharedImage->depth, level)) { NazaraError("Box dimensions are out of bounds"); @@ -1267,6 +1268,7 @@ void NzImage::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int src void NzImage::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z, unsigned int srcWidth, unsigned int srcHeight, nzUInt8 level) { + ///FIXME: Cette surcharge possède-t-elle la moindre utilité ? (Update(pixels, NzBoxui(rect.x, rect.y, z, rect.width, rect.height, 1), srcWidth, ..) devrait donner le même résultat #if NAZARA_UTILITY_SAFE if (m_sharedImage == &emptyImage) { From 4b2e3370d95b70f70b87cf1786f7c03ffb79356f Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 26 Nov 2014 02:35:59 +0100 Subject: [PATCH 070/233] Added GuillotineBinPack algorithm Former-commit-id: 9f2fb342e7bd9e1b33937a4fd462c993ae5cec3e --- include/Nazara/Core/GuillotineBinPack.hpp | 73 ++++ src/Nazara/Core/GuillotineBinPack.cpp | 387 ++++++++++++++++++++++ 2 files changed, 460 insertions(+) create mode 100644 include/Nazara/Core/GuillotineBinPack.hpp create mode 100644 src/Nazara/Core/GuillotineBinPack.cpp diff --git a/include/Nazara/Core/GuillotineBinPack.hpp b/include/Nazara/Core/GuillotineBinPack.hpp new file mode 100644 index 000000000..f0464a3f7 --- /dev/null +++ b/include/Nazara/Core/GuillotineBinPack.hpp @@ -0,0 +1,73 @@ +// Copyright (C) 2014 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 + +// Implémentation originale de Jukka Jylänki (Merci de sa contribution au domaine public) +// http://clb.demon.fi/projects/even-more-rectangle-bin-packing + +#pragma once + +#ifndef NAZARA_GUILLOTINEBINPACK_HPP +#define NAZARA_GUILLOTINEBINPACK_HPP + +#include +#include +#include +#include + +class NAZARA_API NzGuillotineBinPack +{ + public: + enum FreeRectChoiceHeuristic + { + RectBestAreaFit, + RectBestLongSideFit, + RectBestShortSideFit, + RectWorstAreaFit, + RectWorstLongSideFit, + RectWorstShortSideFit + }; + + enum GuillotineSplitHeuristic + { + SplitLongerAxis, + SplitLongerLeftoverAxis, + SplitMaximizeArea, + SplitMinimizeArea, + SplitShorterAxis, + SplitShorterLeftoverAxis + }; + + NzGuillotineBinPack(); + NzGuillotineBinPack(unsigned int width, unsigned int height); + ~NzGuillotineBinPack() = default; + + void Clear(); + + void FreeRectangle(const NzRectui& rect); + + unsigned int GetHeight() const; + float GetOccupancy() const; + NzVector2ui GetSize() const; + unsigned int GetWidth() const; + + bool Insert(NzRectui* rects, bool* flipped, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod); + + bool MergeFreeRectangles(); + + void Reset(); + void Reset(unsigned int width, unsigned int height); + + private: + void SplitFreeRectAlongAxis(const NzRectui& freeRect, const NzRectui& placedRect, bool splitHorizontal); + void SplitFreeRectByHeuristic(const NzRectui& freeRect, const NzRectui& placedRect, GuillotineSplitHeuristic method); + + static int ScoreByHeuristic(int width, int height, const NzRectui& freeRect, FreeRectChoiceHeuristic rectChoice); + + std::vector m_freeRectangles; + float m_occupancy; + unsigned int m_height; + unsigned int m_width; +}; + +#endif // NAZARA_GUILLOTINEBINPACK_HPP diff --git a/src/Nazara/Core/GuillotineBinPack.cpp b/src/Nazara/Core/GuillotineBinPack.cpp new file mode 100644 index 000000000..6cbae97aa --- /dev/null +++ b/src/Nazara/Core/GuillotineBinPack.cpp @@ -0,0 +1,387 @@ +// Copyright (C) 2014 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 + +// Implémentation originale de Jukka Jylänki (Merci de sa contribution au domaine public) +// http://clb.demon.fi/projects/even-more-rectangle-bin-packing +// Je n'ai vraiment fait qu'adapter le code au moteur (Avec quelques améliorations), je n'ai aucun mérite sur le code ci-dessous + +#include +#include +#include +#include +#include + +namespace +{ + int ScoreBestAreaFit(int width, int height, const NzRectui& freeRectSize) + { + return freeRectSize.width * freeRectSize.height - width * height; + } + + int ScoreBestLongSideFit(int width, int height, const NzRectui& freeRectSize) + { + int leftoverHoriz = std::abs(freeRectSize.width - width); + int leftoverVert = std::abs(freeRectSize.height - height); + int leftover = std::max(leftoverHoriz, leftoverVert); + + return leftover; + } + + int ScoreBestShortSideFit(int width, int height, const NzRectui& freeRectSize) + { + int leftoverHoriz = std::abs(freeRectSize.width - width); + int leftoverVert = std::abs(freeRectSize.height - height); + int leftover = std::min(leftoverHoriz, leftoverVert); + + return leftover; + } + + int ScoreWorstAreaFit(int width, int height, const NzRectui& freeRectSize) + { + return -ScoreBestAreaFit(width, height, freeRectSize); + } + + int ScoreWorstLongSideFit(int width, int height, const NzRectui& freeRectSize) + { + return -ScoreBestLongSideFit(width, height, freeRectSize); + } + + int ScoreWorstShortSideFit(int width, int height, const NzRectui& freeRectSize) + { + return -ScoreBestShortSideFit(width, height, freeRectSize); + } +} + +NzGuillotineBinPack::NzGuillotineBinPack() +{ + Reset(); +} + +NzGuillotineBinPack::NzGuillotineBinPack(unsigned int width, unsigned int height) +{ + Reset(width, height); +} + +void NzGuillotineBinPack::Clear() +{ + m_freeRectangles.clear(); + m_freeRectangles.push_back(NzRectui(0, 0, m_width, m_height)); + + m_occupancy = 0.f; +} + +void NzGuillotineBinPack::FreeRectangle(const NzRectui& rect) +{ + ///DOC: Cette méthode ne devrait recevoir que des rectangles calculés par la méthode Insert et peut provoquer de la fragmentation + m_freeRectangles.push_back(rect); + + m_occupancy -= static_cast(rect.width * rect.height) / (m_width*m_height); +} + +unsigned int NzGuillotineBinPack::GetHeight() const +{ + return m_height; +} + +float NzGuillotineBinPack::GetOccupancy() const +{ + return m_occupancy; +} + +NzVector2ui NzGuillotineBinPack::GetSize() const +{ + return NzVector2ui(m_width, m_height); +} + +unsigned int NzGuillotineBinPack::GetWidth() const +{ + return m_width; +} + +bool NzGuillotineBinPack::Insert(NzRectui* rects, bool* flipped, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod) +{ + std::vector remainingRects(count); // La position du rectangle + for (unsigned int i = 0; i < count; ++i) + remainingRects[i] = &rects[i]; + + // Pack rectangles one at a time until we have cleared the rects array of all rectangles. + while (!remainingRects.empty()) + { + // Stores the penalty score of the best rectangle placement - bigger=worse, smaller=better. + bool bestFlipped; + int bestFreeRect; + int bestRect; + int bestScore = std::numeric_limits::max(); + + for (std::size_t i = 0; i < m_freeRectangles.size(); ++i) + { + NzRectui& freeRect = m_freeRectangles[i]; + + for (std::size_t j = 0; j < remainingRects.size(); ++j) + { + NzRectui& rect = *remainingRects[j]; + + // If this rectangle is a perfect match, we pick it instantly. + if (rect.width == freeRect.width && rect.height == freeRect.height) + { + bestFreeRect = i; + bestRect = j; + bestFlipped = false; + bestScore = std::numeric_limits::min(); + i = m_freeRectangles.size(); // Force a jump out of the outer loop as well - we got an instant fit. + break; + } + // If flipping this rectangle is a perfect match, pick that then. + else if (rect.height == freeRect.width && rect.width == freeRect.height) + { + bestFreeRect = i; + bestRect = j; + bestFlipped = true; + bestScore = std::numeric_limits::min(); + i = m_freeRectangles.size(); // Force a jump out of the outer loop as well - we got an instant fit. + break; + } + // Try if we can fit the rectangle upright. + else if (rect.width <= freeRect.width && rect.height <= freeRect.height) + { + int score = ScoreByHeuristic(rect.width, rect.height, freeRect, rectChoice); + if (score < bestScore) + { + bestFreeRect = i; + bestRect = j; + bestFlipped = false; + bestScore = score; + } + } + // If not, then perhaps flipping sideways will make it fit? + else if (rect.height <= freeRect.width && rect.width <= freeRect.height) + { + int score = ScoreByHeuristic(rect.height, rect.width, freeRect, rectChoice); + if (score < bestScore) + { + bestFreeRect = i; + bestRect = j; + bestFlipped = true; + bestScore = score; + } + } + } + } + + // If we didn't manage to find any rectangle to pack, abort. + if (bestScore == std::numeric_limits::max()) + return false; + + // Otherwise, we're good to go and do the actual packing. + unsigned int position = remainingRects[bestRect] - rects; + NzRectui& rect = *remainingRects[bestRect]; + rect.x = m_freeRectangles[bestFreeRect].x; + rect.y = m_freeRectangles[bestFreeRect].y; + + if (bestFlipped) + std::swap(rect.width, rect.height); + + if (flipped) + flipped[position] = bestFlipped; + + // Remove the free space we lost in the bin. + SplitFreeRectByHeuristic(m_freeRectangles[bestFreeRect], rect, splitMethod); + m_freeRectangles.erase(m_freeRectangles.begin() + bestFreeRect); + + // Remove the rectangle we just packed from the input list. + remainingRects.erase(remainingRects.begin() + bestRect); + + // Perform a Rectangle Merge step if desired. + if (merge) + MergeFreeRectangles(); + + m_occupancy += static_cast(rect.width * rect.height) / (m_width*m_height); + } + + return true; +} + +bool NzGuillotineBinPack::MergeFreeRectangles() +{ + ///DOC: Renvoie true s'il y a eu fusion (et donc si une fusion est encore possible) + std::size_t oriSize = m_freeRectangles.size(); + + // Do a Theta(n^2) loop to see if any pair of free rectangles could me merged into one. + // Note that we miss any opportunities to merge three rectangles into one. (should call this function again to detect that) + for (std::size_t i = 0; i < m_freeRectangles.size(); ++i) + { + NzRectui& firstRect = m_freeRectangles[i]; + + for (std::size_t j = i+1; j < m_freeRectangles.size(); ++j) + { + NzRectui& secondRect = m_freeRectangles[j]; + + if (firstRect.width == secondRect.width && firstRect.x == secondRect.x) + { + if (firstRect.y == secondRect.y + secondRect.height) + { + firstRect.y -= secondRect.height; + firstRect.height += secondRect.height; + m_freeRectangles.erase(m_freeRectangles.begin() + j); + --j; + } + else if (firstRect.y + firstRect.height == secondRect.y) + { + firstRect.height += secondRect.height; + m_freeRectangles.erase(m_freeRectangles.begin() + j); + --j; + } + } + else if (firstRect.height == secondRect.height && firstRect.y == secondRect.y) + { + if (firstRect.x == secondRect.x + secondRect.width) + { + firstRect.x -= secondRect.width; + firstRect.width += secondRect.width; + m_freeRectangles.erase(m_freeRectangles.begin() + j); + --j; + } + else if (firstRect.x + firstRect.width == secondRect.x) + { + firstRect.width += secondRect.width; + m_freeRectangles.erase(m_freeRectangles.begin() + j); + --j; + } + } + } + } + + return m_freeRectangles.size() < oriSize; +} + +void NzGuillotineBinPack::Reset() +{ + m_height = 0; + m_width = 0; + + Clear(); +} + +void NzGuillotineBinPack::Reset(unsigned int width, unsigned int height) +{ + m_height = height; + m_width = width; + + Clear(); +} + +void NzGuillotineBinPack::SplitFreeRectAlongAxis(const NzRectui& freeRect, const NzRectui& placedRect, bool splitHorizontal) +{ + // Form the two new rectangles. + NzRectui bottom; + bottom.x = freeRect.x; + bottom.y = freeRect.y + placedRect.height; + bottom.height = freeRect.height - placedRect.height; + + NzRectui right; + right.x = freeRect.x + placedRect.width; + right.y = freeRect.y; + right.width = freeRect.width - placedRect.width; + + if (splitHorizontal) + { + bottom.width = freeRect.width; + right.height = placedRect.height; + } + else // Split vertically + { + bottom.width = placedRect.width; + right.height = freeRect.height; + } + + // Add the new rectangles into the free rectangle pool if they weren't degenerate. + if (bottom.width > 0 && bottom.height > 0) + m_freeRectangles.push_back(bottom); + + if (right.width > 0 && right.height > 0) + m_freeRectangles.push_back(right); +} + +void NzGuillotineBinPack::SplitFreeRectByHeuristic(const NzRectui& freeRect, const NzRectui& placedRect, GuillotineSplitHeuristic method) +{ + // Compute the lengths of the leftover area. + const int w = freeRect.width - placedRect.width; + const int h = freeRect.height - placedRect.height; + + // Placing placedRect into freeRect results in an L-shaped free area, which must be split into + // two disjoint rectangles. This can be achieved with by splitting the L-shape using a single line. + // We have two choices: horizontal or vertical. + + // Use the given heuristic to decide which choice to make. + + bool splitHorizontal; + switch (method) + { + case SplitLongerAxis: + // Split along the longer total axis. + splitHorizontal = (freeRect.width > freeRect.height); + break; + + case SplitLongerLeftoverAxis: + // Split along the longer leftover axis. + splitHorizontal = (w > h); + break; + + case SplitMaximizeArea: + // Maximize the smaller area == minimize the larger area. + // Tries to make the rectangles more even-sized. + splitHorizontal = (placedRect.width * h <= w * placedRect.height); + break; + + case SplitMinimizeArea: + // Maximize the larger area == minimize the smaller area. + // Tries to make the single bigger rectangle. + splitHorizontal = (placedRect.width * h > w * placedRect.height); + break; + + case SplitShorterAxis: + // Split along the shorter total axis. + splitHorizontal = (freeRect.width <= freeRect.height); + break; + + case SplitShorterLeftoverAxis: + // Split along the shorter leftover axis. + splitHorizontal = (w <= h); + break; + + default: + NazaraError("Split heuristic out of enum (0x" + NzString::Number(method, 16) + ')'); + splitHorizontal = true; + } + + // Perform the actual split. + SplitFreeRectAlongAxis(freeRect, placedRect, splitHorizontal); +} + +int NzGuillotineBinPack::ScoreByHeuristic(int width, int height, const NzRectui& freeRect, FreeRectChoiceHeuristic rectChoice) +{ + switch (rectChoice) + { + case RectBestAreaFit: + return ScoreBestAreaFit(width, height, freeRect); + + case RectBestLongSideFit: + return ScoreBestLongSideFit(width, height, freeRect); + + case RectBestShortSideFit: + return ScoreBestShortSideFit(width, height, freeRect); + + case RectWorstAreaFit: + return ScoreWorstAreaFit(width, height, freeRect); + + case RectWorstLongSideFit: + return ScoreWorstLongSideFit(width, height, freeRect); + + case RectWorstShortSideFit: + return ScoreWorstShortSideFit(width, height, freeRect); + } + + NazaraError("Rect choice heuristic out of enum (0x" + NzString::Number(rectChoice, 16) + ')'); + return std::numeric_limits::max(); +} From eda4ef852d60d4b2952106bfe0c9485b9fbfeb34 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 02:55:49 +0100 Subject: [PATCH 071/233] Fixed Image::Get[Width|Height|Depth] returning 1 on invalid images Former-commit-id: 0822a90c3e4b29addcb74ab9a268fd88ff167f76 --- src/Nazara/Utility/Image.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index 5fb12ff6f..407a376b3 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -11,12 +11,16 @@ #include ///TODO: Rajouter des warnings (Formats compressés avec les méthodes Copy/Update, tests taille dans Copy) -///TODO: Rendre les méthodes exception-safe +///TODO: Rendre les méthodes exception-safe (Virer toute cette merde de calcul de pointeurs, faire usage du RAII) +///FIXME: Gérer correctement les formats utilisant moins d'un octet par pixel namespace { inline unsigned int GetLevelSize(unsigned int size, nzUInt8 level) { + if (size == 0) // Possible dans le cas d'une image invalide + return 0; + return std::max(size >> level, 1U); } @@ -28,7 +32,7 @@ namespace bool NzImageParams::IsValid() const { - return true; + return true; // Rien à vérifier } NzImage::NzImage() : @@ -195,7 +199,7 @@ void NzImage::Copy(const NzImage& source, const NzBoxui& srcBox, const NzVector3 bool NzImage::Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth, nzUInt8 levelCount) { - ReleaseImage(); + Destroy(); #if NAZARA_UTILITY_SAFE if (!NzPixelFormat::IsValid(format)) From e14789830ceaf245df3681096db4a3dc46f21fcc Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 02:56:05 +0100 Subject: [PATCH 072/233] Removed useless line Former-commit-id: 3499a0aa828a9886f55ad7c5da55e52ef930eb49 --- src/Nazara/Renderer/RenderWindow.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Nazara/Renderer/RenderWindow.cpp b/src/Nazara/Renderer/RenderWindow.cpp index 44e0fdf89..9580ccc56 100644 --- a/src/Nazara/Renderer/RenderWindow.cpp +++ b/src/Nazara/Renderer/RenderWindow.cpp @@ -320,4 +320,3 @@ void NzRenderWindow::OnWindowResized() { NotifySizeChange(); } - From df6fdf67847210ac40710ab9b851ccf70a9b6dd9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 02:57:30 +0100 Subject: [PATCH 073/233] Added a Size parameter to View class Allowing independent from rendertarget size Former-commit-id: c131b6dd95692c72a969bf0cc6edd997911bbe58 --- include/Nazara/Graphics/View.hpp | 4 ++++ src/Nazara/Graphics/View.cpp | 19 ++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/include/Nazara/Graphics/View.hpp b/include/Nazara/Graphics/View.hpp index 899c34de6..bc048aeb6 100644 --- a/include/Nazara/Graphics/View.hpp +++ b/include/Nazara/Graphics/View.hpp @@ -20,6 +20,7 @@ class NAZARA_API NzView : public NzAbstractViewer, public NzNode, NzRenderTarget { public: NzView(); + NzView(const NzVector2f& size); ~NzView(); void EnsureFrustumUpdate() const; @@ -32,6 +33,7 @@ class NAZARA_API NzView : public NzAbstractViewer, public NzNode, NzRenderTarget NzVector3f GetForward() const; const NzFrustumf& GetFrustum() const; const NzMatrix4f& GetProjectionMatrix() const; + const NzVector2f& GetSize() const; const NzRenderTarget* GetTarget() const; const NzRectf& GetTargetRegion() const; const NzMatrix4f& GetViewMatrix() const; @@ -39,6 +41,7 @@ class NAZARA_API NzView : public NzAbstractViewer, public NzNode, NzRenderTarget float GetZFar() const; float GetZNear() const; + void SetSize(const NzVector2f& size); void SetTarget(const NzRenderTarget* renderTarget); void SetTarget(const NzRenderTarget& renderTarget); void SetTargetRegion(const NzRectf& region); @@ -63,6 +66,7 @@ class NAZARA_API NzView : public NzAbstractViewer, public NzNode, NzRenderTarget mutable NzMatrix4f m_viewMatrix; NzRectf m_targetRegion; mutable NzRecti m_viewport; + NzVector2f m_size; const NzRenderTarget* m_target; mutable bool m_frustumUpdated; mutable bool m_projectionMatrixUpdated; diff --git a/src/Nazara/Graphics/View.cpp b/src/Nazara/Graphics/View.cpp index 3caa0b48f..44d00294c 100644 --- a/src/Nazara/Graphics/View.cpp +++ b/src/Nazara/Graphics/View.cpp @@ -10,6 +10,7 @@ NzView::NzView() : m_targetRegion(0.f, 0.f, 1.f, 1.f), +m_size(0.f), m_target(nullptr), m_frustumUpdated(false), m_projectionMatrixUpdated(false), @@ -20,6 +21,12 @@ m_zNear(-1.f) { } +NzView::NzView(const NzVector2f& size) : +NzView() // On délègue +{ + m_size = size; +} + NzView::~NzView() { if (m_target) @@ -256,10 +263,16 @@ void NzView::UpdateFrustum() const void NzView::UpdateProjectionMatrix() const { - if (!m_viewportUpdated) - UpdateViewport(); + if (m_size.x <= 0.f || m_size.y <= 0.f) // Si la taille est nulle, on prendra la taille du viewport + { + if (!m_viewportUpdated) + UpdateViewport(); + + m_projectionMatrix.MakeOrtho(0.f, m_viewport.width, 0.f, m_viewport.height, m_zNear, m_zFar); + } + else + m_projectionMatrix.MakeOrtho(0.f, m_size.x, 0.f, m_size.y, m_zNear, m_zFar); - m_projectionMatrix.MakeOrtho(m_viewport.x, m_viewport.x + m_viewport.width, m_viewport.y, m_viewport.y + m_viewport.height, m_zNear, m_zFar); m_projectionMatrixUpdated = true; } From 90e6bf4493b372556e68cedc84c11c95474fae79 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 02:58:01 +0100 Subject: [PATCH 074/233] Made Music class non copyable Former-commit-id: ccbd014514b3c9f59c3fee940cc307afb890f634 --- include/Nazara/Audio/Music.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Audio/Music.hpp b/include/Nazara/Audio/Music.hpp index bff875cb5..716d68cc0 100644 --- a/include/Nazara/Audio/Music.hpp +++ b/include/Nazara/Audio/Music.hpp @@ -26,7 +26,7 @@ using NzMusicLoader = NzResourceLoader; struct NzMusicImpl; -class NAZARA_API NzMusic : public NzSoundEmitter +class NAZARA_API NzMusic : public NzSoundEmitter, NzNonCopyable { friend NzMusicLoader; From c24e0ef8fac2d036b18fd02fadca7dbe7c11cd8f Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 02:58:52 +0100 Subject: [PATCH 075/233] Improved Music.cpp (Added comments) Former-commit-id: 0a4aabbafd3d76d280ac98332fa2059b1ad73b39 --- src/Nazara/Audio/Music.cpp | 41 +++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/src/Nazara/Audio/Music.cpp b/src/Nazara/Audio/Music.cpp index f6704bf4d..aad189270 100644 --- a/src/Nazara/Audio/Music.cpp +++ b/src/Nazara/Audio/Music.cpp @@ -116,6 +116,7 @@ nzUInt32 NzMusic::GetPlayingOffset() const } #endif + ///TODO return 0; } @@ -131,6 +132,7 @@ nzSoundStatus NzMusic::GetStatus() const nzSoundStatus status = GetInternalStatus(); + // Pour compenser les éventuels retards (ou le laps de temps entre Play() et la mise en route du thread) if (m_impl->streaming && status == nzSoundStatus_Stopped) status = nzSoundStatus_Playing; @@ -180,14 +182,17 @@ void NzMusic::Play() } #endif + // Nous sommes déjà en train de jouer if (m_impl->streaming) { + // Peut-être sommes-nous en pause if (GetStatus() != nzSoundStatus_Playing) alSourcePlay(m_source); return; } + // Lancement du thread de streaming m_impl->stream->Seek(0); m_impl->streaming = true; m_impl->thread = NzThread(&NzMusic::MusicThread, this); @@ -195,6 +200,19 @@ void NzMusic::Play() return; } +void NzMusic::SetPlayingOffset(nzUInt32 offset) +{ + #if NAZARA_AUDIO_SAFE + if (!m_impl) + { + NazaraError("Music not created"); + return; + } + #endif + + ///TODO +} + void NzMusic::Stop() { #if NAZARA_AUDIO_SAFE @@ -217,39 +235,44 @@ bool NzMusic::FillAndQueueBuffer(unsigned int buffer) unsigned int sampleCount = m_impl->chunkSamples.size(); unsigned int sampleRead = 0; + // Lecture depuis le stream pour remplir le buffer for (;;) { sampleRead += m_impl->stream->Read(&m_impl->chunkSamples[sampleRead], sampleCount - sampleRead); - if (sampleRead < sampleCount && m_impl->loop) - m_impl->stream->Seek(0); - else - break; + if (sampleRead < sampleCount && !m_impl->loop) + break; // Fin du stream (On ne boucle pas) + + m_impl->stream->Seek(0); // On boucle au début du stream et on remplit à nouveau } + // Mise à jour du buffer (envoi à OpenAL) et placement dans la file d'attente if (sampleRead > 0) { alBufferData(buffer, m_impl->audioFormat, &m_impl->chunkSamples[0], sampleRead*sizeof(nzInt16), m_impl->sampleRate); alSourceQueueBuffers(m_source, 1, &buffer); } - return sampleRead != sampleCount; // Fin du fichier (N'arrive pas en cas de loop) + return sampleRead != sampleCount; // Fin du stream (N'arrive pas en cas de loop) } void NzMusic::MusicThread() { + // Allocation des buffers de streaming ALuint buffers[NAZARA_AUDIO_STREAMED_BUFFER_COUNT]; alGenBuffers(NAZARA_AUDIO_STREAMED_BUFFER_COUNT, buffers); for (unsigned int i = 0; i < NAZARA_AUDIO_STREAMED_BUFFER_COUNT; ++i) { - if (FillAndQueueBuffer(buffers[i])) // Fin du fichier ? - break; // Nous avons atteint la fin du fichier, inutile de rajouter des buffers + if (FillAndQueueBuffer(buffers[i])) + break; // Nous avons atteint la fin du stream, inutile de rajouter des buffers } alSourcePlay(m_source); + // Boucle de lecture (remplissage de nouveaux buffers au fur et à mesure) while (m_impl->streaming) { + // La lecture s'est arrêtée, nous avons atteint la fin du stream nzSoundStatus status = GetInternalStatus(); if (status == nzSoundStatus_Stopped) { @@ -257,6 +280,7 @@ void NzMusic::MusicThread() break; } + // On traite les buffers lus ALint processedCount = 0; alGetSourcei(m_source, AL_BUFFERS_PROCESSED, &processedCount); @@ -268,11 +292,14 @@ void NzMusic::MusicThread() break; } + // On retourne dormir un peu NzThread::Sleep(50); } + // Arrêt de la lecture du son (dans le cas où ça ne serait pas déjà fait) alSourceStop(m_source); + // On supprime les buffers du stream ALint queuedBufferCount; alGetSourcei(m_source, AL_BUFFERS_QUEUED, &queuedBufferCount); From bb95e6862a35e85ca7514cf941854732f99dbc40 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 02:59:56 +0100 Subject: [PATCH 076/233] Fixed sprites being rendered upside-down in 2D This is still waiting for a fix because it will be upside-down in 3D Former-commit-id: ca4bef616f3496db22349eb907ec32a0b6c3deb8 --- src/Nazara/Graphics/ForwardRenderTechnique.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 68726c809..896e7c70a 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -421,19 +421,19 @@ void NzForwardRenderTechnique::DrawSprites(const NzScene* scene) const NzVector3f center = sprite->GetPosition(); NzQuaternionf rotation = sprite->GetRotation(); - vertices->position = center + rotation * NzVector3f(-halfSize.x, -halfSize.y, 0.f); + vertices->position = center + rotation * NzVector3f(-halfSize.x, halfSize.y, 0.f); vertices->uv.Set(textureCoords.x, textureCoords.y + textureCoords.height); vertices++; - vertices->position = center + rotation * NzVector3f(halfSize.x, -halfSize.y, 0.f); + vertices->position = center + rotation * NzVector3f(halfSize.x, halfSize.y, 0.f); vertices->uv.Set(textureCoords.width, textureCoords.y + textureCoords.height); vertices++; - vertices->position = center + rotation * NzVector3f(-halfSize.x, halfSize.y, 0.f); + vertices->position = center + rotation * NzVector3f(-halfSize.x, -halfSize.y, 0.f); vertices->uv.Set(textureCoords.x, textureCoords.y); vertices++; - vertices->position = center + rotation * NzVector3f(halfSize.x, halfSize.y, 0.f); + vertices->position = center + rotation * NzVector3f(halfSize.x, -halfSize.y, 0.f); vertices->uv.Set(textureCoords.width, textureCoords.y); vertices++; } From 27e9996e7bea21d2723efbd9b25850e9650ffc3b Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 03:00:10 +0100 Subject: [PATCH 077/233] Improved error message Former-commit-id: 0315fe27119a0da88334ee67575e144c488d655c --- src/Nazara/Graphics/DeferredGeometryPass.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Graphics/DeferredGeometryPass.cpp b/src/Nazara/Graphics/DeferredGeometryPass.cpp index e1a008493..577afe5a0 100644 --- a/src/Nazara/Graphics/DeferredGeometryPass.cpp +++ b/src/Nazara/Graphics/DeferredGeometryPass.cpp @@ -228,7 +228,7 @@ bool NzDeferredGeometryPass::Resize(const NzVector2ui& dimensions) } catch (const std::exception& e) { - NazaraError("Failed to create G-Buffer RTT"); + NazaraError("Failed to create G-Buffer RTT: " + NzString(e.what())); return false; } } From 605bcc703851f25a93e4ba784ec70c13f259707e Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 03:00:19 +0100 Subject: [PATCH 078/233] Fixed possible warning Former-commit-id: fac12a042d206976109ffde42865c561b021ed93 --- src/Nazara/Graphics/DeferredBloomPass.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Nazara/Graphics/DeferredBloomPass.cpp b/src/Nazara/Graphics/DeferredBloomPass.cpp index 9b66184dd..754a4b88c 100644 --- a/src/Nazara/Graphics/DeferredBloomPass.cpp +++ b/src/Nazara/Graphics/DeferredBloomPass.cpp @@ -10,9 +10,9 @@ NzDeferredBloomPass::NzDeferredBloomPass() : m_uniformUpdated(false), -m_brightLuminance(0.8), -m_brightMiddleGrey(0.5), -m_brightThreshold(0.8), +m_brightLuminance(0.8f), +m_brightMiddleGrey(0.5f), +m_brightThreshold(0.8f), m_blurPassCount(5) { m_bilinearSampler.SetAnisotropyLevel(1); From aa37c632cbea26bbd94007a520867a5c154d8d99 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 03:00:35 +0100 Subject: [PATCH 079/233] Fixed possible warning Former-commit-id: 4d14bf2cee4756db0720fda0d904d5bc7b2bafd9 --- src/Nazara/Graphics/Material.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 123db7ffc..3c9861acc 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -690,8 +690,8 @@ void NzMaterial::GenerateShader(nzUInt32 flags) const m_normalMap.IsValid() || m_heightMap.IsValid() || m_specularMap.IsValid()); list.SetParameter("TRANSFORM", m_transformEnabled); - list.SetParameter("FLAG_DEFERRED", static_cast(flags & nzShaderFlags_Deferred)); - list.SetParameter("FLAG_INSTANCING", static_cast(flags & nzShaderFlags_Instancing)); + list.SetParameter("FLAG_DEFERRED", static_cast((flags & nzShaderFlags_Deferred) != 0)); + list.SetParameter("FLAG_INSTANCING", static_cast((flags & nzShaderFlags_Instancing) != 0)); ShaderInstance& instance = m_shaders[flags]; instance.uberInstance = m_uberShader->Get(list); From 3db73921c2d082ee301827cc884c147f53cc71f7 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 03:03:35 +0100 Subject: [PATCH 080/233] Made 2D nodes easier to use Former-commit-id: 80c0340b93c203bd874568c9d4fb5e2fc88a5860 --- include/Nazara/Utility/Node.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/Nazara/Utility/Node.hpp b/include/Nazara/Utility/Node.hpp index 290f3a933..4536739a7 100644 --- a/include/Nazara/Utility/Node.hpp +++ b/include/Nazara/Utility/Node.hpp @@ -50,13 +50,13 @@ class NAZARA_API NzNode NzNode& Interpolate(const NzNode& nodeA, const NzNode& nodeB, float interpolation, nzCoordSys coordSys = nzCoordSys_Global); NzNode& Move(const NzVector3f& movement, nzCoordSys coordSys = nzCoordSys_Local); - NzNode& Move(float movementX, float movementY, float movementZ, nzCoordSys coordSys = nzCoordSys_Local); + NzNode& Move(float movementX, float movementY, float movementZ = 0.f, nzCoordSys coordSys = nzCoordSys_Local); NzNode& Rotate(const NzQuaternionf& rotation, nzCoordSys coordSys = nzCoordSys_Local); NzNode& Scale(const NzVector3f& scale); NzNode& Scale(float scale); - NzNode& Scale(float scaleX, float scaleY, float scaleZ); + NzNode& Scale(float scaleX, float scaleY, float scaleZ = 1.f); void SetInheritRotation(bool inheritRotation); void SetInheritScale(bool inheritScale); @@ -64,18 +64,18 @@ class NAZARA_API NzNode void SetInitialRotation(const NzQuaternionf& quat); void SetInitialScale(const NzVector3f& scale); void SetInitialScale(float scale); - void SetInitialScale(float scaleX, float scaleY, float scaleZ); + void SetInitialScale(float scaleX, float scaleY, float scaleZ = 1.f); void SetInitialPosition(const NzVector3f& translation); - void SetInitialPosition(float translationX, float translationXY, float translationZ); + void SetInitialPosition(float translationX, float translationXY, float translationZ = 0.f); void SetName(const NzString& name); void SetParent(const NzNode* node = nullptr, bool keepDerived = false); void SetParent(const NzNode& node, bool keepDerived = false); void SetPosition(const NzVector3f& translation, nzCoordSys coordSys = nzCoordSys_Local); - void SetPosition(float translationX, float translationXY, float translationZ, nzCoordSys coordSys = nzCoordSys_Local); + void SetPosition(float translationX, float translationY, float translationZ = 0.f, nzCoordSys coordSys = nzCoordSys_Local); void SetRotation(const NzQuaternionf& quat, nzCoordSys coordSys = nzCoordSys_Local); void SetScale(const NzVector3f& scale, nzCoordSys coordSys = nzCoordSys_Local); void SetScale(float scale, nzCoordSys coordSys = nzCoordSys_Local); - void SetScale(float scaleX, float scaleY, float scaleZ, nzCoordSys coordSys = nzCoordSys_Local); + void SetScale(float scaleX, float scaleY, float scaleZ = 1.f, nzCoordSys coordSys = nzCoordSys_Local); void SetTransformMatrix(const NzMatrix4f& matrix); // Local -> global From b56e40f35a23b364312f9785781014f86a5e102f Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 03:03:45 +0100 Subject: [PATCH 081/233] Added comment Former-commit-id: 045a48cb1b0e798de31cd2aff0708324648da409 --- include/Nazara/Utility/Algorithm.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/Nazara/Utility/Algorithm.hpp b/include/Nazara/Utility/Algorithm.hpp index 59812fca4..37d4a5705 100644 --- a/include/Nazara/Utility/Algorithm.hpp +++ b/include/Nazara/Utility/Algorithm.hpp @@ -32,6 +32,7 @@ NAZARA_API void NzComputePlaneIndexVertexCount(const NzVector2ui& subdivision, u NAZARA_API void NzComputeUvSphereIndexVertexCount(unsigned int sliceCount, unsigned int stackCount, unsigned int* indexCount, unsigned int* vertexCount); template NzBoxf NzComputeVerticesAABB(const T* vertices, unsigned int vertexCount); +///TODO: Remplacer le pointeur vertices par une structure composée de plusieurs SparsePtr NAZARA_API void NzGenerateBox(const NzVector3f& lengths, const NzVector3ui& subdivision, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); NAZARA_API void NzGenerateCone(float length, float radius, unsigned int subdivision, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); NAZARA_API void NzGenerateCubicSphere(float size, unsigned int subdivision, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzMeshVertex* vertices, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); From 5ae54677f1a3bd6690f157fd163b2e6038e76d70 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 03:04:04 +0100 Subject: [PATCH 082/233] Fixed Matrix4::IsIdentity() Former-commit-id: 7f3dfb47241ec2625e7ba02decb53ad5fd3d60ac --- include/Nazara/Math/Matrix4.inl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index a3fe4b53a..89363a31e 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -562,9 +562,9 @@ template bool NzMatrix4::IsIdentity() const { return (NzNumberEquals(m11, F(1.0)) && NzNumberEquals(m12, F(0.0)) && NzNumberEquals(m13, F(0.0)) && NzNumberEquals(m14, F(0.0)) && - NzNumberEquals(m11, F(0.0)) && NzNumberEquals(m12, F(1.0)) && NzNumberEquals(m13, F(0.0)) && NzNumberEquals(m14, F(0.0)) && - NzNumberEquals(m11, F(0.0)) && NzNumberEquals(m12, F(0.0)) && NzNumberEquals(m13, F(1.0)) && NzNumberEquals(m14, F(0.0)) && - NzNumberEquals(m11, F(0.0)) && NzNumberEquals(m12, F(0.0)) && NzNumberEquals(m13, F(0.0)) && NzNumberEquals(m14, F(1.0))); + NzNumberEquals(m21, F(0.0)) && NzNumberEquals(m22, F(1.0)) && NzNumberEquals(m23, F(0.0)) && NzNumberEquals(m24, F(0.0)) && + NzNumberEquals(m31, F(0.0)) && NzNumberEquals(m32, F(0.0)) && NzNumberEquals(m33, F(1.0)) && NzNumberEquals(m34, F(0.0)) && + NzNumberEquals(m41, F(0.0)) && NzNumberEquals(m42, F(0.0)) && NzNumberEquals(m43, F(0.0)) && NzNumberEquals(m44, F(1.0))); } template From 42b28e732c894ded6711176d9bb29ae45bf53a3e Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 03:04:24 +0100 Subject: [PATCH 083/233] Removed whitespace Former-commit-id: e7bfe92a625f6102abc4fe3b11b498c43b371ee9 --- include/Nazara/Renderer/RenderTarget.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Renderer/RenderTarget.hpp b/include/Nazara/Renderer/RenderTarget.hpp index c62d1c5b6..eaec9f2ce 100644 --- a/include/Nazara/Renderer/RenderTarget.hpp +++ b/include/Nazara/Renderer/RenderTarget.hpp @@ -61,7 +61,7 @@ class NAZARA_API NzRenderTarget private: mutable std::unordered_map m_listeners; - bool m_listenersLocked; + bool m_listenersLocked; }; #endif // NAZARA_RENDERTARGET_HPP From a51cbc1e4993cd19b9ca12d9ca76e6ebf08ffeb5 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 03:05:27 +0100 Subject: [PATCH 084/233] Added Sprite::SetSize(float, float) overload Former-commit-id: 672a2e4f5c2a2d40b4af42c7ee4b7b37d3774117 --- include/Nazara/Graphics/Sprite.hpp | 1 + src/Nazara/Graphics/Sprite.cpp | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/include/Nazara/Graphics/Sprite.hpp b/include/Nazara/Graphics/Sprite.hpp index 54ebb71a1..b383f1e44 100644 --- a/include/Nazara/Graphics/Sprite.hpp +++ b/include/Nazara/Graphics/Sprite.hpp @@ -32,6 +32,7 @@ class NAZARA_API NzSprite : public NzSceneNode void SetMaterial(NzMaterial* material, bool resizeSprite = true); void SetSize(const NzVector2f& size); + void SetSize(float sizeX, float sizeY); void SetTexture(NzTexture* texture, bool resizeSprite = true); void SetTextureCoords(const NzRectf& coords); void SetTextureRect(const NzRectui& rect); diff --git a/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index 7d14a1a8e..df181ac5d 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -109,10 +109,17 @@ void NzSprite::SetMaterial(NzMaterial* material, bool resizeSprite) void NzSprite::SetSize(const NzVector2f& size) { m_size = size; + + // On invalide la bounding box m_boundingVolume.MakeNull(); m_boundingVolumeUpdated = false; } +void NzSprite::SetSize(float sizeX, float sizeY) +{ + SetSize(NzVector2f(sizeX, sizeY)); +} + void NzSprite::SetTexture(NzTexture* texture, bool resizeSprite) { std::unique_ptr material(new NzMaterial); From 15ddc29179242c6ad6f3e2cc1615cfe27083a0c0 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 03:06:12 +0100 Subject: [PATCH 085/233] Added implicit conversion to SparsePtr Former-commit-id: 5116a5e7687706640cd5d2ef99f5c181e00ee841 --- include/Nazara/Core/SparsePtr.hpp | 2 ++ include/Nazara/Core/SparsePtr.inl | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/include/Nazara/Core/SparsePtr.hpp b/include/Nazara/Core/SparsePtr.hpp index aff3460ac..94c3f249f 100644 --- a/include/Nazara/Core/SparsePtr.hpp +++ b/include/Nazara/Core/SparsePtr.hpp @@ -22,6 +22,7 @@ class NzSparsePtr NzSparsePtr(); NzSparsePtr(T* ptr); NzSparsePtr(VoidPtr ptr, unsigned int stride); + template NzSparsePtr(const NzSparsePtr& ptr); NzSparsePtr(const NzSparsePtr& ptr) = default; ~NzSparsePtr() = default; @@ -32,6 +33,7 @@ class NzSparsePtr void Reset(T* ptr); void Reset(VoidPtr ptr, unsigned int stride); void Reset(const NzSparsePtr& ptr); + template void Reset(const NzSparsePtr& ptr); void SetPtr(VoidPtr ptr); void SetStride(unsigned int stride); diff --git a/include/Nazara/Core/SparsePtr.inl b/include/Nazara/Core/SparsePtr.inl index b98599bfd..ca0d7e328 100644 --- a/include/Nazara/Core/SparsePtr.inl +++ b/include/Nazara/Core/SparsePtr.inl @@ -22,6 +22,13 @@ NzSparsePtr::NzSparsePtr(VoidPtr ptr, unsigned int stride) Reset(ptr, stride); } +template +template +NzSparsePtr::NzSparsePtr(const NzSparsePtr& ptr) +{ + Reset(ptr); +} + template typename NzSparsePtr::VoidPtr NzSparsePtr::GetPtr() const { @@ -62,6 +69,16 @@ void NzSparsePtr::Reset(const NzSparsePtr& ptr) SetStride(ptr.GetStride()); } +template +template +void NzSparsePtr::Reset(const NzSparsePtr& ptr) +{ + static_assert(std::is_convertible::value, "Source type pointer cannot be implicitely converted to target type pointer"); + + SetPtr(static_cast(ptr.GetPtr())); + SetStride(ptr.GetStride()); +} + template void NzSparsePtr::SetPtr(VoidPtr ptr) { @@ -120,6 +137,7 @@ template NzSparsePtr& NzSparsePtr::operator+=(unsigned int count) { m_ptr += count*m_stride; + return *this; } @@ -127,6 +145,7 @@ template NzSparsePtr& NzSparsePtr::operator-=(unsigned int count) { m_ptr -= count*m_stride; + return *this; } @@ -134,6 +153,7 @@ template NzSparsePtr& NzSparsePtr::operator++() { m_ptr += m_stride; + return *this; } From d22c4a5ac9e0f94ee2d4fcf88fe6a4274f3a7504 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 7 Dec 2014 03:09:39 +0100 Subject: [PATCH 086/233] Added A8 pixel format PixelFormat::GetBytesPerPixel() will no longer warn with less-than-one-byte formats Former-commit-id: af41f0c2bc7a35c2ee617980878628ff1c8bf868 --- include/Nazara/Utility/Enums.hpp | 1 + include/Nazara/Utility/PixelFormat.inl | 18 +++-- src/Nazara/Renderer/OpenGL.cpp | 3 + src/Nazara/Renderer/Texture.cpp | 15 ++-- src/Nazara/Utility/PixelFormat.cpp | 103 ++++++++++++++++++++++++- 5 files changed, 121 insertions(+), 19 deletions(-) diff --git a/include/Nazara/Utility/Enums.hpp b/include/Nazara/Utility/Enums.hpp index 25e09c10a..a5aec05bc 100644 --- a/include/Nazara/Utility/Enums.hpp +++ b/include/Nazara/Utility/Enums.hpp @@ -130,6 +130,7 @@ enum nzPixelFormat { nzPixelFormat_Undefined = -1, + nzPixelFormat_A8, // 1*uint8 nzPixelFormat_BGR8, // 3*uint8 nzPixelFormat_BGRA8, // 4*uint8 nzPixelFormat_DXT1, diff --git a/include/Nazara/Utility/PixelFormat.inl b/include/Nazara/Utility/PixelFormat.inl index c92f8b8c0..2154d2f05 100644 --- a/include/Nazara/Utility/PixelFormat.inl +++ b/include/Nazara/Utility/PixelFormat.inl @@ -168,6 +168,9 @@ inline nzUInt8 NzPixelFormat::GetBitsPerPixel(nzPixelFormat format) { switch (format) { + case nzPixelFormat_A8: + return 8; + case nzPixelFormat_BGR8: return 24; @@ -287,20 +290,14 @@ inline nzUInt8 NzPixelFormat::GetBitsPerPixel(nzPixelFormat format) inline nzUInt8 NzPixelFormat::GetBytesPerPixel(nzPixelFormat format) { - nzUInt8 bytesPerPixel = GetBitsPerPixel(format)/8; - - #if NAZARA_UTILITY_SAFE - if (bytesPerPixel == 0) - NazaraWarning("This format is either invalid or using less than one byte per pixel"); - #endif - - return bytesPerPixel; + return GetBitsPerPixel(format)/8; } inline nzPixelFormatType NzPixelFormat::GetType(nzPixelFormat format) { switch (format) { + case nzPixelFormat_A8: case nzPixelFormat_BGR8: case nzPixelFormat_BGRA8: case nzPixelFormat_DXT1: @@ -372,6 +369,7 @@ inline bool NzPixelFormat::HasAlpha(nzPixelFormat format) { switch (format) { + case nzPixelFormat_A8: case nzPixelFormat_BGRA8: case nzPixelFormat_DXT3: case nzPixelFormat_DXT5: @@ -444,6 +442,7 @@ inline bool NzPixelFormat::IsCompressed(nzPixelFormat format) case nzPixelFormat_DXT5: return true; + case nzPixelFormat_A8: case nzPixelFormat_BGR8: case nzPixelFormat_BGRA8: case nzPixelFormat_L8: @@ -529,6 +528,9 @@ inline NzString NzPixelFormat::ToString(nzPixelFormat format) { switch (format) { + case nzPixelFormat_A8: + return "A8"; + case nzPixelFormat_BGR8: return "BGR8"; diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index ef9e096d9..3c8b5c872 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -1465,6 +1465,9 @@ bool NzOpenGL::TranslateFormat(nzPixelFormat pixelFormat, Format* format, Format { switch (pixelFormat) { + case nzPixelFormat_A8: + return false; ///FIXME: Tester le mode d'OpenGL pour se permettre une fonctionnalité dépréciée ? + case nzPixelFormat_BGR8: format->dataFormat = GL_BGR; format->dataType = GL_UNSIGNED_BYTE; diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index cb5b4ff45..b2d59cb6e 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -1272,6 +1272,13 @@ bool NzTexture::IsFormatSupported(nzPixelFormat format) case nzPixelFormat_RGBA32UI: return NzOpenGL::GetVersion() >= 300; + // Dépréciés depuis OpenGL 3 + ///FIXME: Accepter si le contexte OpenGL est de compatibilité/OpenGL 2 ? + case nzPixelFormat_A8: + case nzPixelFormat_L8: + case nzPixelFormat_LA8: + return false; + // Formats de profondeur (Supportés avec les FBOs) case nzPixelFormat_Depth16: case nzPixelFormat_Depth24: @@ -1286,12 +1293,7 @@ bool NzTexture::IsFormatSupported(nzPixelFormat format) case nzPixelFormat_Stencil16: return false; - // Dépréciés depuis OpenGL 3 - ///FIXME: Il doit bien exister des remplaçants (GL_RED ?) - case nzPixelFormat_L8: - case nzPixelFormat_LA8: - return false; - + // Formats compressés case nzPixelFormat_DXT1: case nzPixelFormat_DXT3: case nzPixelFormat_DXT5: @@ -1302,7 +1304,6 @@ bool NzTexture::IsFormatSupported(nzPixelFormat format) } NazaraError("Invalid pixel format"); - return false; } diff --git a/src/Nazara/Utility/PixelFormat.cpp b/src/Nazara/Utility/PixelFormat.cpp index 776781251..07fc36431 100644 --- a/src/Nazara/Utility/PixelFormat.cpp +++ b/src/Nazara/Utility/PixelFormat.cpp @@ -50,6 +50,94 @@ namespace return nullptr; } + /**********************************A8***********************************/ + template<> + nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) + { + while (start < end) + { + *dst++ = 0xFF; + *dst++ = 0xFF; + *dst++ = 0xFF; + *dst++ = *start; + + start += 1; + } + + return dst; + } + + template<> + nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) + { + while (start < end) + { + *dst++ = 0xFF; + *dst++ = *start; + + start += 1; + } + + return dst; + } + + template<> + nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) + { + nzUInt16* ptr = reinterpret_cast(dst); + while (start < end) + { + *ptr = (static_cast(c8to5(start[2])) << 11) | + (static_cast(c8to5(start[1])) << 6) | + (static_cast(c8to5(start[0])) << 1) | + ((*start > 0xF) ? 1 : 0); // > 128 + + #ifdef NAZARA_BIG_ENDIAN + NzByteSwap(ptr, sizeof(nzUInt16)); + #endif + + ptr++; + start += 1; + } + + return reinterpret_cast(ptr); + } + + template<> + nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) + { + nzUInt16* ptr = reinterpret_cast(dst); + while (start < end) + { + *ptr = 0xFFF0 | c8to4(*start); + + #ifdef NAZARA_BIG_ENDIAN + NzByteSwap(ptr, sizeof(nzUInt16)); + #endif + + ptr++; + start += 1; + } + + return dst; + } + + template<> + nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) + { + while (start < end) + { + *dst++ = 0xFF; + *dst++ = 0xFF; + *dst++ = 0xFF; + *dst++ = *start; + + start += 1; + } + + return dst; + } + /**********************************BGR8***********************************/ template<> nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) @@ -243,7 +331,7 @@ namespace *ptr = (static_cast(c8to5(start[2])) << 11) | (static_cast(c8to5(start[1])) << 6) | (static_cast(c8to5(start[0])) << 1) | - ((start[3] == 0xFF) ? 1 : 0); + ((start[3] > 0xF) ? 1 : 0); // > 128 #ifdef NAZARA_BIG_ENDIAN NzByteSwap(ptr, sizeof(nzUInt16)); @@ -465,7 +553,7 @@ namespace { nzUInt16 l = static_cast(c8to5(start[0])); - *ptr = (l << 11) | (l << 6) | (l << 1) | ((start[1] == 0xFF) ? 1 : 0); + *ptr = (l << 11) | (l << 6) | (l << 1) | ((start[1] > 0xF) ? 1 : 0); #ifdef NAZARA_BIG_ENDIAN NzByteSwap(ptr, sizeof(nzUInt16)); @@ -638,7 +726,7 @@ namespace nzUInt16 b = c4to5((pixel & 0x00F0) >> 4); nzUInt16 a = c4to5((pixel & 0x000F) >> 0); - *ptr = (r << 11) | (g << 6) | (b << 1) | ((a == 0xFF) ? 1 : 0); + *ptr = (r << 11) | (g << 6) | (b << 1) | ((a > 0x3) ? 1 : 0); #ifdef NAZARA_BIG_ENDIAN NzByteSwap(ptr, sizeof(nzUInt16)); @@ -1044,7 +1132,7 @@ namespace *ptr = (static_cast(c8to5(start[0])) << 11) | (static_cast(c8to5(start[1])) << 6) | (static_cast(c8to5(start[2])) << 1) | - ((start[3] == 0xFF) ? 1 : 0); + ((start[3] > 0xF) ? 1 : 0); // > 128 #ifdef NAZARA_BIG_ENDIAN NzByteSwap(ptr, sizeof(nzUInt16)); @@ -1106,6 +1194,13 @@ bool NzPixelFormat::Initialize() // Réinitialisation std::memset(s_convertFunctions, 0, (nzPixelFormat_Max+1)*(nzPixelFormat_Max+1)*sizeof(NzPixelFormat::ConvertFunction)); + /***********************************A8************************************/ + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + /**********************************BGR8***********************************/ RegisterConverter(); RegisterConverter(); From a393271f0426f4e97cb2ae05e9ac47bb1bd0cead Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 10 Dec 2014 14:38:32 +0100 Subject: [PATCH 087/233] Improved GuillotineBinPack Added explicit copy/move constructor/operator Added Expand method Added Insert overloads (you are now able to query which rectangles were inserted) Made occupancy computation more precise Overloaded methods taking a unsigned int pair with Vector2ui Former-commit-id: f063c04a1aea0d26594db642c2466264fe139450 --- include/Nazara/Core/GuillotineBinPack.hpp | 14 ++++- src/Nazara/Core/GuillotineBinPack.cpp | 67 +++++++++++++++++++++-- 2 files changed, 76 insertions(+), 5 deletions(-) diff --git a/include/Nazara/Core/GuillotineBinPack.hpp b/include/Nazara/Core/GuillotineBinPack.hpp index f0464a3f7..fecac3d00 100644 --- a/include/Nazara/Core/GuillotineBinPack.hpp +++ b/include/Nazara/Core/GuillotineBinPack.hpp @@ -40,10 +40,16 @@ class NAZARA_API NzGuillotineBinPack NzGuillotineBinPack(); NzGuillotineBinPack(unsigned int width, unsigned int height); + NzGuillotineBinPack(const NzVector2ui& size); + NzGuillotineBinPack(const NzGuillotineBinPack&) = default; + NzGuillotineBinPack(NzGuillotineBinPack&&) = default; ~NzGuillotineBinPack() = default; void Clear(); + void Expand(unsigned int newWidth, unsigned newHeight); + void Expand(const NzVector2ui& newSize); + void FreeRectangle(const NzRectui& rect); unsigned int GetHeight() const; @@ -51,12 +57,18 @@ class NAZARA_API NzGuillotineBinPack NzVector2ui GetSize() const; unsigned int GetWidth() const; + bool Insert(NzRectui* rects, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod); bool Insert(NzRectui* rects, bool* flipped, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod); + bool Insert(NzRectui* rects, bool* flipped, bool* inserted, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod); bool MergeFreeRectangles(); void Reset(); void Reset(unsigned int width, unsigned int height); + void Reset(const NzVector2ui& size); + + NzGuillotineBinPack& operator=(const NzGuillotineBinPack&) = default; + NzGuillotineBinPack& operator=(NzGuillotineBinPack&&) = default; private: void SplitFreeRectAlongAxis(const NzRectui& freeRect, const NzRectui& placedRect, bool splitHorizontal); @@ -65,8 +77,8 @@ class NAZARA_API NzGuillotineBinPack static int ScoreByHeuristic(int width, int height, const NzRectui& freeRect, FreeRectChoiceHeuristic rectChoice); std::vector m_freeRectangles; - float m_occupancy; unsigned int m_height; + unsigned int m_usedArea; unsigned int m_width; }; diff --git a/src/Nazara/Core/GuillotineBinPack.cpp b/src/Nazara/Core/GuillotineBinPack.cpp index 6cbae97aa..7a32f3ae1 100644 --- a/src/Nazara/Core/GuillotineBinPack.cpp +++ b/src/Nazara/Core/GuillotineBinPack.cpp @@ -7,6 +7,7 @@ // Je n'ai vraiment fait qu'adapter le code au moteur (Avec quelques améliorations), je n'ai aucun mérite sur le code ci-dessous #include +#include #include #include #include @@ -63,12 +64,40 @@ NzGuillotineBinPack::NzGuillotineBinPack(unsigned int width, unsigned int height Reset(width, height); } +NzGuillotineBinPack::NzGuillotineBinPack(const NzVector2ui& size) +{ + Reset(size); +} + void NzGuillotineBinPack::Clear() { m_freeRectangles.clear(); m_freeRectangles.push_back(NzRectui(0, 0, m_width, m_height)); - m_occupancy = 0.f; + m_usedArea = 0; +} + +void NzGuillotineBinPack::Expand(unsigned int newWidth, unsigned newHeight) +{ + unsigned int oldWidth = m_width; + unsigned int oldHeight = m_height; + + m_width = std::max(newWidth, m_width); + m_height = std::max(newHeight, m_height); + + if (m_width > oldWidth) + m_freeRectangles.push_back(NzRectui(oldWidth, 0, m_width - oldWidth, oldHeight)); + + if (m_height > oldHeight) + m_freeRectangles.push_back(NzRectui(0, oldHeight, m_width, m_height - oldHeight)); + + // On va ensuite fusionner les rectangles tant que possible + while (MergeFreeRectangles()); +} + +void NzGuillotineBinPack::Expand(const NzVector2ui& newSize) +{ + Expand(newSize.x, newSize.y); } void NzGuillotineBinPack::FreeRectangle(const NzRectui& rect) @@ -76,7 +105,7 @@ void NzGuillotineBinPack::FreeRectangle(const NzRectui& rect) ///DOC: Cette méthode ne devrait recevoir que des rectangles calculés par la méthode Insert et peut provoquer de la fragmentation m_freeRectangles.push_back(rect); - m_occupancy -= static_cast(rect.width * rect.height) / (m_width*m_height); + m_usedArea -= rect.width * rect.height; } unsigned int NzGuillotineBinPack::GetHeight() const @@ -86,7 +115,7 @@ unsigned int NzGuillotineBinPack::GetHeight() const float NzGuillotineBinPack::GetOccupancy() const { - return m_occupancy; + return static_cast(m_usedArea)/(m_width*m_height); } NzVector2ui NzGuillotineBinPack::GetSize() const @@ -99,7 +128,17 @@ unsigned int NzGuillotineBinPack::GetWidth() const return m_width; } +bool NzGuillotineBinPack::Insert(NzRectui* rects, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod) +{ + return Insert(rects, nullptr, nullptr, count, merge, rectChoice, splitMethod); +} + bool NzGuillotineBinPack::Insert(NzRectui* rects, bool* flipped, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod) +{ + return Insert(rects, flipped, nullptr, count, merge, rectChoice, splitMethod); +} + +bool NzGuillotineBinPack::Insert(NzRectui* rects, bool* flipped, bool* inserted, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod) { std::vector remainingRects(count); // La position du rectangle for (unsigned int i = 0; i < count; ++i) @@ -171,7 +210,19 @@ bool NzGuillotineBinPack::Insert(NzRectui* rects, bool* flipped, unsigned int co // If we didn't manage to find any rectangle to pack, abort. if (bestScore == std::numeric_limits::max()) + { + // Si nous le pouvons, on marque les rectangles n'ayant pas pu être insérés + if (inserted) + { + for (NzRectui* rect : remainingRects) + { + unsigned int position = rect - rects; + inserted[position] = false; + } + } + return false; + } // Otherwise, we're good to go and do the actual packing. unsigned int position = remainingRects[bestRect] - rects; @@ -185,6 +236,9 @@ bool NzGuillotineBinPack::Insert(NzRectui* rects, bool* flipped, unsigned int co if (flipped) flipped[position] = bestFlipped; + if (inserted) + inserted[position] = true; + // Remove the free space we lost in the bin. SplitFreeRectByHeuristic(m_freeRectangles[bestFreeRect], rect, splitMethod); m_freeRectangles.erase(m_freeRectangles.begin() + bestFreeRect); @@ -196,7 +250,7 @@ bool NzGuillotineBinPack::Insert(NzRectui* rects, bool* flipped, unsigned int co if (merge) MergeFreeRectangles(); - m_occupancy += static_cast(rect.width * rect.height) / (m_width*m_height); + m_usedArea += rect.width * rect.height; } return true; @@ -271,6 +325,11 @@ void NzGuillotineBinPack::Reset(unsigned int width, unsigned int height) Clear(); } +void NzGuillotineBinPack::Reset(const NzVector2ui& size) +{ + Reset(size.x, size.y); +} + void NzGuillotineBinPack::SplitFreeRectAlongAxis(const NzRectui& freeRect, const NzRectui& placedRect, bool splitHorizontal) { // Form the two new rectangles. From db0bbd5be463d33ce8891840254232dfd659c95b Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 10 Dec 2014 14:41:12 +0100 Subject: [PATCH 088/233] Added conversions to A8 pixel format Former-commit-id: 8fc541a3bba588572a7fd87e69c695b470708181 --- src/Nazara/Utility/PixelFormat.cpp | 82 ++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/src/Nazara/Utility/PixelFormat.cpp b/src/Nazara/Utility/PixelFormat.cpp index 07fc36431..e72e503ba 100644 --- a/src/Nazara/Utility/PixelFormat.cpp +++ b/src/Nazara/Utility/PixelFormat.cpp @@ -258,6 +258,19 @@ namespace } /**********************************BGRA8**********************************/ + template<> + nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) + { + while (start < end) + { + *dst++ = start[3]; + + start += 4; + } + + return dst; + } + template<> nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) { @@ -501,6 +514,19 @@ namespace } /***********************************LA8***********************************/ + template<> + nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) + { + while (start < end) + { + *dst++ = start[1]; + + start += 2; + } + + return dst; + } + template<> nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) { @@ -619,6 +645,25 @@ namespace } /*********************************RGBA4***********************************/ + template<> + nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) + { + while (start < end) + { + nzUInt16 pixel = *reinterpret_cast(start); + + #ifdef NAZARA_BIG_ENDIAN + NzByteSwap(&pixel, sizeof(nzUInt16)); + #endif + + *dst++ = c4to8(pixel & 0x000F); + + start += 2; + } + + return dst; + } + template<> nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) { @@ -783,6 +828,25 @@ namespace } /*********************************RGB5A1**********************************/ + template<> + nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) + { + while (start < end) + { + nzUInt16 pixel = *reinterpret_cast(start); + + #ifdef NAZARA_BIG_ENDIAN + NzByteSwap(&pixel, sizeof(nzUInt16)); + #endif + + *dst++ = static_cast((pixel & 0x1)*0xFF); + + start += 2; + } + + return dst; + } + template<> nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) { @@ -1065,6 +1129,19 @@ namespace } /**********************************RGBA8**********************************/ + template<> + nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) + { + while (start < end) + { + *dst++ = start[3]; + + start += 4; + } + + return dst; + } + template<> nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) { @@ -1219,6 +1296,7 @@ bool NzPixelFormat::Initialize() RegisterConverter(); /**********************************BGRA8**********************************/ + RegisterConverter(); RegisterConverter(); RegisterConverter(); RegisterConverter();/* @@ -1322,6 +1400,7 @@ bool NzPixelFormat::Initialize() RegisterConverter(); /***********************************LA8***********************************/ + RegisterConverter(); RegisterConverter(); RegisterConverter(); RegisterConverter();/* @@ -1339,6 +1418,7 @@ bool NzPixelFormat::Initialize() RegisterConverter(); /**********************************RGBA4**********************************/ + RegisterConverter(); RegisterConverter(); RegisterConverter(); RegisterConverter(); @@ -1356,6 +1436,7 @@ bool NzPixelFormat::Initialize() RegisterConverter(); /*********************************RGB5A1**********************************/ + RegisterConverter(); RegisterConverter(); RegisterConverter(); RegisterConverter(); @@ -1390,6 +1471,7 @@ bool NzPixelFormat::Initialize() RegisterConverter(); /**********************************RGBA8**********************************/ + RegisterConverter(); RegisterConverter(); RegisterConverter(); RegisterConverter(); From 3a5868b915e54e441984f6a1687c4ad344e44435 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 10 Dec 2014 14:41:43 +0100 Subject: [PATCH 089/233] Fixed pixel format conversion from A8 to RGB5A1 Former-commit-id: ae5dbe7dd41f5b2856661820bf40ae93e3556c36 --- src/Nazara/Utility/PixelFormat.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Nazara/Utility/PixelFormat.cpp b/src/Nazara/Utility/PixelFormat.cpp index e72e503ba..b6679598d 100644 --- a/src/Nazara/Utility/PixelFormat.cpp +++ b/src/Nazara/Utility/PixelFormat.cpp @@ -87,9 +87,9 @@ namespace nzUInt16* ptr = reinterpret_cast(dst); while (start < end) { - *ptr = (static_cast(c8to5(start[2])) << 11) | - (static_cast(c8to5(start[1])) << 6) | - (static_cast(c8to5(start[0])) << 1) | + *ptr = (static_cast(0x1F) << 11) | + (static_cast(0x1F) << 6) | + (static_cast(0x1F) << 1) | ((*start > 0xF) ? 1 : 0); // > 128 #ifdef NAZARA_BIG_ENDIAN From 96798da027c87932ff932ce5e90877c05324c078 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 10 Dec 2014 14:41:56 +0100 Subject: [PATCH 090/233] Added TODO Former-commit-id: 11658e200641ba0846bc8b89376e034cd0b6c9a4 --- include/Nazara/Utility/PixelFormat.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/Nazara/Utility/PixelFormat.hpp b/include/Nazara/Utility/PixelFormat.hpp index 9f864e9ad..f4443c22b 100644 --- a/include/Nazara/Utility/PixelFormat.hpp +++ b/include/Nazara/Utility/PixelFormat.hpp @@ -13,6 +13,10 @@ #include #include +///TODO: Permettre la conversion automatique entre les formats via des renseignements de bits et de type pour chaque format. +/// Ce serait plus lent que la conversion spécialisée (qui ne disparaît donc pas) mais ça permettrait au moteur de faire la conversion +/// entre n'importe quel formats non-compressés. + class NzPixelFormat { friend class NzUtility; From 7316cbb6940fb1ce71f3498bba0e85c019a9e2e5 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 10 Dec 2014 19:01:03 +0100 Subject: [PATCH 091/233] Added OpenGL support for pixel formats A8/L8/LA8 Former-commit-id: b17942f7bf22daf90ddf5d8093da6c26b64a67ce --- include/Nazara/Renderer/OpenGL.hpp | 1 + src/Nazara/Renderer/OpenGL.cpp | 85 +++++++++++++++++++++++++++++- src/Nazara/Renderer/Texture.cpp | 19 ++++--- 3 files changed, 96 insertions(+), 9 deletions(-) diff --git a/include/Nazara/Renderer/OpenGL.hpp b/include/Nazara/Renderer/OpenGL.hpp index df6c199d7..8aa5a438d 100644 --- a/include/Nazara/Renderer/OpenGL.hpp +++ b/include/Nazara/Renderer/OpenGL.hpp @@ -69,6 +69,7 @@ class NAZARA_API NzOpenGL GLenum dataFormat; GLenum dataType; GLint internalFormat; + GLint swizzle[4]; }; NzOpenGL() = delete; diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index 3c8b5c872..3edf4e499 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -1463,10 +1463,41 @@ void NzOpenGL::SetViewport(const NzRecti& viewport) bool NzOpenGL::TranslateFormat(nzPixelFormat pixelFormat, Format* format, FormatType type) { + // Par défaut + format->swizzle[0] = GL_RED; + format->swizzle[1] = GL_GREEN; + format->swizzle[2] = GL_BLUE; + format->swizzle[3] = GL_ALPHA; + switch (pixelFormat) { case nzPixelFormat_A8: - return false; ///FIXME: Tester le mode d'OpenGL pour se permettre une fonctionnalité dépréciée ? + if (type == FormatType_Texture) // Format supporté uniquement par les textures + { + if (GetVersion() >= 300) + { + format->dataFormat = GL_RED; + format->dataType = GL_UNSIGNED_BYTE; + format->internalFormat = GL_R8; + + // Simulation du format + format->swizzle[0] = GL_ONE; + format->swizzle[1] = GL_ONE; + format->swizzle[2] = GL_ONE; + format->swizzle[3] = GL_RED; + } + else + { + // Le bon vieux format GL_ALPHA + format->dataFormat = GL_ALPHA; + format->dataType = GL_UNSIGNED_BYTE; + format->internalFormat = GL_ALPHA; + } + + return true; + } + else + return false; case nzPixelFormat_BGR8: format->dataFormat = GL_BGR; @@ -1499,8 +1530,58 @@ bool NzOpenGL::TranslateFormat(nzPixelFormat pixelFormat, Format* format, Format return true; case nzPixelFormat_L8: + if (type == FormatType_Texture) // Format supporté uniquement par les textures + { + if (GetVersion() >= 300) + { + format->dataFormat = GL_RED; + format->dataType = GL_UNSIGNED_BYTE; + format->internalFormat = GL_R8; + + // Simulation du format + format->swizzle[0] = GL_RED; + format->swizzle[1] = GL_RED; + format->swizzle[2] = GL_RED; + format->swizzle[3] = GL_ONE; + } + else + { + format->dataFormat = 0x1909; // GL_LUMINANCE + format->dataType = GL_UNSIGNED_BYTE; + format->internalFormat = 0x1909; // GL_LUMINANCE + } + + return true; + } + else + return false; + case nzPixelFormat_LA8: - return false; + if (type == FormatType_Texture) // Format supporté uniquement par les textures + { + if (GetVersion() >= 300) + { + format->dataFormat = GL_RG; + format->dataType = GL_UNSIGNED_BYTE; + format->internalFormat = GL_RG8; + + // Simulation du format + format->swizzle[0] = GL_RED; + format->swizzle[1] = GL_RED; + format->swizzle[2] = GL_RED; + format->swizzle[3] = GL_GREEN; + } + else + { + format->dataFormat = 0x190A; // GL_LUMINANCE_ALPHA + format->dataType = GL_UNSIGNED_BYTE; + format->internalFormat = 0x190A; // GL_LUMINANCE_ALPHA; + } + + return true; + } + else + return false; case nzPixelFormat_R8: format->dataFormat = GL_RED; diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index b2d59cb6e..6e73cc545 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -133,6 +133,15 @@ namespace return false; } + // Application du swizzle + if (NzOpenGL::GetVersion() >= 300) + { + glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, openGLFormat.swizzle[0]); + glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, openGLFormat.swizzle[1]); + glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, openGLFormat.swizzle[2]); + glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, openGLFormat.swizzle[3]); + } + return true; } @@ -1226,8 +1235,11 @@ bool NzTexture::IsFormatSupported(nzPixelFormat format) switch (format) { // Formats de base + case nzPixelFormat_A8: case nzPixelFormat_BGR8: case nzPixelFormat_BGRA8: + case nzPixelFormat_L8: + case nzPixelFormat_LA8: case nzPixelFormat_RGB8: case nzPixelFormat_RGBA8: return true; @@ -1272,13 +1284,6 @@ bool NzTexture::IsFormatSupported(nzPixelFormat format) case nzPixelFormat_RGBA32UI: return NzOpenGL::GetVersion() >= 300; - // Dépréciés depuis OpenGL 3 - ///FIXME: Accepter si le contexte OpenGL est de compatibilité/OpenGL 2 ? - case nzPixelFormat_A8: - case nzPixelFormat_L8: - case nzPixelFormat_LA8: - return false; - // Formats de profondeur (Supportés avec les FBOs) case nzPixelFormat_Depth16: case nzPixelFormat_Depth24: From 20607238df36ab5f63fd9467aec7e64c8b8f1d3c Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 11 Dec 2014 18:56:55 +0100 Subject: [PATCH 092/233] SparsePtr: Allowed negative stride Former-commit-id: 9ca3101347bdc071503ec9edb75b4f896a6dd2e0 --- include/Nazara/Core/SparsePtr.hpp | 20 ++++++++++---------- include/Nazara/Core/SparsePtr.inl | 18 +++++++++--------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/include/Nazara/Core/SparsePtr.hpp b/include/Nazara/Core/SparsePtr.hpp index 94c3f249f..74a64425d 100644 --- a/include/Nazara/Core/SparsePtr.hpp +++ b/include/Nazara/Core/SparsePtr.hpp @@ -21,34 +21,34 @@ class NzSparsePtr NzSparsePtr(); NzSparsePtr(T* ptr); - NzSparsePtr(VoidPtr ptr, unsigned int stride); + NzSparsePtr(VoidPtr ptr, int stride); template NzSparsePtr(const NzSparsePtr& ptr); NzSparsePtr(const NzSparsePtr& ptr) = default; ~NzSparsePtr() = default; VoidPtr GetPtr() const; - unsigned int GetStride() const; + int GetStride() const; void Reset(); void Reset(T* ptr); - void Reset(VoidPtr ptr, unsigned int stride); + void Reset(VoidPtr ptr, int stride); void Reset(const NzSparsePtr& ptr); template void Reset(const NzSparsePtr& ptr); void SetPtr(VoidPtr ptr); - void SetStride(unsigned int stride); + void SetStride(int stride); operator bool() const; operator T*() const; T& operator*() const; T& operator->() const; - T& operator[](unsigned int index) const; + T& operator[](int index) const; - NzSparsePtr operator+(unsigned int count) const; - NzSparsePtr operator-(unsigned int count) const; + NzSparsePtr operator+(int count) const; + NzSparsePtr operator-(int count) const; - NzSparsePtr& operator+=(unsigned int count); - NzSparsePtr& operator-=(unsigned int count); + NzSparsePtr& operator+=(int count); + NzSparsePtr& operator-=(int count); NzSparsePtr& operator++(); NzSparsePtr operator++(int); @@ -67,7 +67,7 @@ class NzSparsePtr private: BytePtr m_ptr; - unsigned int m_stride; + int m_stride; }; #include diff --git a/include/Nazara/Core/SparsePtr.inl b/include/Nazara/Core/SparsePtr.inl index ca0d7e328..661c9292a 100644 --- a/include/Nazara/Core/SparsePtr.inl +++ b/include/Nazara/Core/SparsePtr.inl @@ -17,7 +17,7 @@ NzSparsePtr::NzSparsePtr(T* ptr) } template -NzSparsePtr::NzSparsePtr(VoidPtr ptr, unsigned int stride) +NzSparsePtr::NzSparsePtr(VoidPtr ptr, int stride) { Reset(ptr, stride); } @@ -36,7 +36,7 @@ typename NzSparsePtr::VoidPtr NzSparsePtr::GetPtr() const } template -unsigned int NzSparsePtr::GetStride() const +int NzSparsePtr::GetStride() const { return m_stride; } @@ -56,7 +56,7 @@ void NzSparsePtr::Reset(T* ptr) } template -void NzSparsePtr::Reset(VoidPtr ptr, unsigned int stride) +void NzSparsePtr::Reset(VoidPtr ptr, int stride) { SetPtr(ptr); SetStride(stride); @@ -86,7 +86,7 @@ void NzSparsePtr::SetPtr(VoidPtr ptr) } template -void NzSparsePtr::SetStride(unsigned int stride) +void NzSparsePtr::SetStride(int stride) { m_stride = stride; } @@ -116,25 +116,25 @@ T& NzSparsePtr::operator->() const } template -T& NzSparsePtr::operator[](unsigned int index) const +T& NzSparsePtr::operator[](int index) const { return *reinterpret_cast(m_ptr + index*m_stride); } template -NzSparsePtr NzSparsePtr::operator+(unsigned int count) const +NzSparsePtr NzSparsePtr::operator+(int count) const { return NzSparsePtr(m_ptr + count*m_stride, m_stride); } template -NzSparsePtr NzSparsePtr::operator-(unsigned int count) const +NzSparsePtr NzSparsePtr::operator-(int count) const { return NzSparsePtr(m_ptr - count*m_stride, m_stride); } template -NzSparsePtr& NzSparsePtr::operator+=(unsigned int count) +NzSparsePtr& NzSparsePtr::operator+=(int count) { m_ptr += count*m_stride; @@ -142,7 +142,7 @@ NzSparsePtr& NzSparsePtr::operator+=(unsigned int count) } template -NzSparsePtr& NzSparsePtr::operator-=(unsigned int count) +NzSparsePtr& NzSparsePtr::operator-=(int count) { m_ptr -= count*m_stride; From 02643f944274a9acfeee18492f062f8f9cb8aa16 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 17 Dec 2014 13:52:40 +0100 Subject: [PATCH 093/233] Improved Win32 code Former-commit-id: cfaecc7d8df56fa4cb2a27570531ffbce3fdfe87 --- src/Nazara/Utility/Win32/InputImpl.cpp | 4 ++-- src/Nazara/Utility/Win32/WindowImpl.cpp | 4 ++-- src/Nazara/Utility/Win32/WindowImpl.hpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Nazara/Utility/Win32/InputImpl.cpp b/src/Nazara/Utility/Win32/InputImpl.cpp index bafaf0f24..62337423d 100644 --- a/src/Nazara/Utility/Win32/InputImpl.cpp +++ b/src/Nazara/Utility/Win32/InputImpl.cpp @@ -222,7 +222,7 @@ NzVector2i NzEventImpl::GetMousePosition(const NzWindow& relativeTo) } else { - NazaraError("Window's handle is invalid"); + NazaraError("Invalid window handle"); // Attention que (-1, -1) est une position tout à fait valide et ne doit pas servir de test return NzVector2i(-1, -1); @@ -289,5 +289,5 @@ void NzEventImpl::SetMousePosition(int x, int y, const NzWindow& relativeTo) SetCursorPos(pos.x, pos.y); } else - NazaraError("Window's handle is invalid"); + NazaraError("Invalid window handle"); } diff --git a/src/Nazara/Utility/Win32/WindowImpl.cpp b/src/Nazara/Utility/Win32/WindowImpl.cpp index 64a1fae74..1da1b9251 100644 --- a/src/Nazara/Utility/Win32/WindowImpl.cpp +++ b/src/Nazara/Utility/Win32/WindowImpl.cpp @@ -79,7 +79,7 @@ m_scrolling(0) { } -bool NzWindowImpl::Create(NzVideoMode mode, const NzString& title, nzUInt32 style) +bool NzWindowImpl::Create(const NzVideoMode& mode, const NzString& title, nzUInt32 style) { bool fullscreen = (style & nzWindowStyle_Fullscreen) != 0; DWORD win32Style, win32StyleEx; @@ -183,7 +183,7 @@ bool NzWindowImpl::Create(NzVideoMode mode, const NzString& title, nzUInt32 styl GetWindowRect(m_handle, &windowRect); m_position.Set(windowRect.left, windowRect.top); - m_size.Set(clientRect.right-clientRect.left, clientRect.bottom-clientRect.top); + m_size.Set(clientRect.right - clientRect.left, clientRect.bottom - clientRect.top); return true; } diff --git a/src/Nazara/Utility/Win32/WindowImpl.hpp b/src/Nazara/Utility/Win32/WindowImpl.hpp index ebd91f9ee..1a726391d 100644 --- a/src/Nazara/Utility/Win32/WindowImpl.hpp +++ b/src/Nazara/Utility/Win32/WindowImpl.hpp @@ -34,7 +34,7 @@ class NzWindowImpl : NzNonCopyable NzWindowImpl(NzWindow* parent); ~NzWindowImpl() = default; - bool Create(NzVideoMode mode, const NzString& title, nzUInt32 style); + bool Create(const NzVideoMode& mode, const NzString& title, nzUInt32 style); bool Create(NzWindowHandle handle); void Destroy(); From 1ee02d4fcf0969c7ed3b35dbca16dd81b0425963 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 17 Dec 2014 13:53:59 +0100 Subject: [PATCH 094/233] Improved code, fixed missing includes Thanks to d@rk-marouane (@progdupeu.pl) Former-commit-id: 4147388501d4263e624f4c6402902ef071f88ffd --- include/Nazara/Core/Color.inl | 7 ++++--- src/Nazara/Utility/VideoMode.cpp | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/include/Nazara/Core/Color.inl b/include/Nazara/Core/Color.inl index 3357f5c20..662c86911 100644 --- a/include/Nazara/Core/Color.inl +++ b/include/Nazara/Core/Color.inl @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include #include @@ -235,7 +236,7 @@ inline void NzColor::ToCMYK(const NzColor& color, float* cyan, float* magenta, f float c, m, y; ToCMY(color, &c, &m, &y); - float k = std::min(std::min(std::min(1.f, c), m), y); + float k = std::min({1.f, c, m, y}); if (NzNumberEquals(k, 1.f)) { @@ -260,8 +261,8 @@ inline void NzColor::ToHSL(const NzColor& color, nzUInt8* hue, nzUInt8* saturati float g = color.g / 255.f; float b = color.b / 255.f; - float min = std::min(std::min(r, g), b); // Min. value of RGB - float max = std::max(std::max(r, g), b); // Max. value of RGB + float min = std::min({r, g, b}); // Min. value of RGB + float max = std::max({r, g, b}); // Max. value of RGB float deltaMax = max - min; //Delta RGB value diff --git a/src/Nazara/Utility/VideoMode.cpp b/src/Nazara/Utility/VideoMode.cpp index ce28eeed3..c3d2b81c1 100644 --- a/src/Nazara/Utility/VideoMode.cpp +++ b/src/Nazara/Utility/VideoMode.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include NzVideoMode::NzVideoMode() : From ba8aed916f90e77321a956599c176b1b1794a1d1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 17 Dec 2014 13:54:44 +0100 Subject: [PATCH 096/233] Renamed unicode option to parseunicode Former-commit-id: 600c6fd480d9e96c90319b367545dd5199a10664 --- build/scripts/actions/unicode.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/scripts/actions/unicode.lua b/build/scripts/actions/unicode.lua index 4db23db8a..8105cb3a0 100644 --- a/build/scripts/actions/unicode.lua +++ b/build/scripts/actions/unicode.lua @@ -191,7 +191,7 @@ end newaction { - trigger = "unicode", + trigger = "parseunicode", description = "Parse the Unicode Character Data and put the useful informations into a header", execute = parseUnicodeData } From 58fbed1dbd36aa694cc8ef8c9e55c7905cd07f9e Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 17 Dec 2014 13:56:01 +0100 Subject: [PATCH 098/233] Improved error message Former-commit-id: ca50bb0afe38364cb4f3bfe71b057fa8721337bd --- src/Nazara/Renderer/Renderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index c219f9c62..0552d8e38 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -1856,7 +1856,7 @@ bool NzRenderer::EnsureStateUpdate() default: { - NazaraInternalError("Unsupported component type"); + NazaraInternalError("Unsupported component type (0x" + NzString::Number(type, 16) + ')'); break; } } From e55c521e9677edc79d09f03394568d2d3e15a7ae Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 17 Dec 2014 13:56:33 +0100 Subject: [PATCH 099/233] Added support for skeletal models (WIP) Former-commit-id: 6a6c2d9f2c68267df79dc48fa56450d2a563e323 --- include/Nazara/Graphics/SkeletalModel.hpp | 88 +++++ src/Nazara/Graphics/Loaders/Mesh/Loader.cpp | 63 ++++ src/Nazara/Graphics/SkeletalModel.cpp | 357 ++++++++++++++++++++ 3 files changed, 508 insertions(+) create mode 100644 include/Nazara/Graphics/SkeletalModel.hpp create mode 100644 src/Nazara/Graphics/SkeletalModel.cpp diff --git a/include/Nazara/Graphics/SkeletalModel.hpp b/include/Nazara/Graphics/SkeletalModel.hpp new file mode 100644 index 000000000..7938ba4c4 --- /dev/null +++ b/include/Nazara/Graphics/SkeletalModel.hpp @@ -0,0 +1,88 @@ +// Copyright (C) 2014 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_SKELETALMODEL_HPP +#define NAZARA_SKELETALMODEL_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +struct NAZARA_API NzSkeletalModelParameters : public NzModelParameters +{ + bool loadAnimation = true; + NzAnimationParams animation; + + bool IsValid() const; +}; + +class NzSkeletalModel; + +using NzSkeletalModelLoader = NzResourceLoader; + +class NAZARA_API NzSkeletalModel : public NzModel, NzUpdatable +{ + friend NzSkeletalModelLoader; + //friend class NzScene; + + public: + NzSkeletalModel(); + NzSkeletalModel(const NzSkeletalModel& model); + NzSkeletalModel(NzSkeletalModel&& model); + ~NzSkeletalModel(); + + void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; + void AdvanceAnimation(float elapsedTime); + + void EnableAnimation(bool animation); + + NzAnimation* GetAnimation() const; + NzSkeleton* GetSkeleton(); + const NzSkeleton* GetSkeleton() const; + + bool HasAnimation() const; + + bool IsAnimated() const; + bool IsAnimationEnabled() const; + bool IsDrawable() const; + + bool LoadFromFile(const NzString& filePath, const NzSkeletalModelParameters& params = NzSkeletalModelParameters()); + bool LoadFromMemory(const void* data, std::size_t size, const NzSkeletalModelParameters& params = NzSkeletalModelParameters()); + bool LoadFromStream(NzInputStream& stream, const NzSkeletalModelParameters& params = NzSkeletalModelParameters()); + + void Reset(); + + bool SetAnimation(NzAnimation* animation); + void SetMesh(NzMesh* mesh) override; + bool SetSequence(const NzString& sequenceName); + void SetSequence(unsigned int sequenceIndex); + + NzSkeletalModel& operator=(const NzSkeletalModel& node); + NzSkeletalModel& operator=(NzSkeletalModel&& node); + + private: + void Register() override; + void Unregister() override; + void Update() override; + void UpdateBoundingVolume() const; + + NzAnimationRef m_animation; + NzSkeleton m_skeleton; + const NzSequence* m_currentSequence; + bool m_animationEnabled; + float m_interpolation; + unsigned int m_currentFrame; + unsigned int m_nextFrame; + + static NzSkeletalModelLoader::LoaderList s_loaders; +}; + +#endif // NAZARA_SKELETALMODEL_HPP diff --git a/src/Nazara/Graphics/Loaders/Mesh/Loader.cpp b/src/Nazara/Graphics/Loaders/Mesh/Loader.cpp index d64597248..2c2d5e514 100644 --- a/src/Nazara/Graphics/Loaders/Mesh/Loader.cpp +++ b/src/Nazara/Graphics/Loaders/Mesh/Loader.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -32,11 +33,71 @@ namespace } if (mesh->IsAnimable()) + { + NazaraError("Can't load animated mesh into static model"); + return false; + } + + // Nous ne pouvons plus avoir recours au smart pointeur à partir d'ici si nous voulons être exception-safe + NzMesh* meshPtr = mesh.get(); + + model->Reset(); + model->SetMesh(meshPtr); + mesh.release(); + + if (parameters.loadMaterials) + { + unsigned int matCount = model->GetMaterialCount(); + + for (unsigned int i = 0; i < matCount; ++i) + { + NzString mat = meshPtr->GetMaterial(i); + if (!mat.IsEmpty()) + { + std::unique_ptr material(new NzMaterial); + material->SetPersistent(false); + + if (material->LoadFromFile(mat, parameters.material)) + { + model->SetMaterial(i, material.get()); + material.release(); + } + else + NazaraWarning("Failed to load material #" + NzString::Number(i)); + } + } + } + + return true; + } + + nzTernary CheckAnimated(NzInputStream& stream, const NzSkeletalModelParameters& parameters) + { + NazaraUnused(stream); + NazaraUnused(parameters); + + return nzTernary_Unknown; + } + + bool LoadAnimated(NzSkeletalModel* model, NzInputStream& stream, const NzSkeletalModelParameters& parameters) + { + NazaraUnused(parameters); + + std::unique_ptr mesh(new NzMesh); + mesh->SetPersistent(false); + if (!mesh->LoadFromStream(stream, parameters.mesh)) + { + NazaraError("Failed to load model mesh"); + return false; + } + + if (!mesh->IsAnimable()) { NazaraError("Can't load static mesh into animated model"); return false; } + // Nous ne pouvons plus avoir recours au smart pointeur à partir d'ici si nous voulons être exception-safe NzMesh* meshPtr = mesh.get(); @@ -74,9 +135,11 @@ namespace void NzLoaders_Mesh_Register() { NzModelLoader::RegisterLoader(NzMeshLoader::IsExtensionSupported, CheckStatic, LoadStatic); + NzSkeletalModelLoader::RegisterLoader(NzMeshLoader::IsExtensionSupported, CheckAnimated, LoadAnimated); } void NzLoaders_Mesh_Unregister() { NzModelLoader::UnregisterLoader(NzMeshLoader::IsExtensionSupported, CheckStatic, LoadStatic); + NzSkeletalModelLoader::UnregisterLoader(NzMeshLoader::IsExtensionSupported, CheckAnimated, LoadAnimated); } diff --git a/src/Nazara/Graphics/SkeletalModel.cpp b/src/Nazara/Graphics/SkeletalModel.cpp new file mode 100644 index 000000000..b7fe39f98 --- /dev/null +++ b/src/Nazara/Graphics/SkeletalModel.cpp @@ -0,0 +1,357 @@ +// Copyright (C) 2014 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 + +bool NzSkeletalModelParameters::IsValid() const +{ + if (!NzModelParameters::IsValid()) + return false; + + if (loadAnimation && !animation.IsValid()) + return false; + + return true; +} + +NzSkeletalModel::NzSkeletalModel() : +m_currentSequence(nullptr), +m_animationEnabled(true) +{ +} + +NzSkeletalModel::NzSkeletalModel(const NzSkeletalModel& model) : +NzModel(model), +m_skeleton(model.m_skeleton), +m_currentSequence(model.m_currentSequence), +m_animationEnabled(model.m_animationEnabled), +m_interpolation(model.m_interpolation), +m_currentFrame(model.m_currentFrame), +m_nextFrame(model.m_nextFrame) +{ +} + +NzSkeletalModel::~NzSkeletalModel() +{ + Reset(); +} + +void NzSkeletalModel::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const +{ + const NzMatrix4f& transformMatrix = GetTransformMatrix(); + + unsigned int submeshCount = m_mesh->GetSubMeshCount(); + for (unsigned int i = 0; i < submeshCount; ++i) + { + const NzSkeletalMesh* mesh = static_cast(m_mesh->GetSubMesh(i)); + const NzMaterial* material = m_materials[mesh->GetMaterialIndex()]; + + NzMeshData meshData; + meshData.indexBuffer = mesh->GetIndexBuffer(); + meshData.primitiveMode = mesh->GetPrimitiveMode(); + meshData.vertexBuffer = NzSkinningManager::GetBuffer(mesh, &m_skeleton); + + renderQueue->AddMesh(material, meshData, m_skeleton.GetAABB(), transformMatrix); + } +} + +void NzSkeletalModel::AdvanceAnimation(float elapsedTime) +{ + #if NAZARA_GRAPHICS_SAFE + if (!m_animation) + { + NazaraError("Model has no animation"); + return; + } + #endif + + m_interpolation += m_currentSequence->frameRate * elapsedTime; + while (m_interpolation > 1.f) + { + m_interpolation -= 1.f; + + unsigned lastFrame = m_currentSequence->firstFrame + m_currentSequence->frameCount - 1; + if (m_nextFrame+1 > lastFrame) + { + if (m_animation->IsLoopPointInterpolationEnabled()) + { + m_currentFrame = m_nextFrame; + m_nextFrame = m_currentSequence->firstFrame; + } + else + { + m_currentFrame = m_currentSequence->firstFrame; + m_nextFrame = m_currentFrame+1; + } + } + else + { + m_currentFrame = m_nextFrame; + m_nextFrame++; + } + } + + m_animation->AnimateSkeleton(&m_skeleton, m_currentFrame, m_nextFrame, m_interpolation); + + InvalidateBoundingVolume(); +} + +void NzSkeletalModel::EnableAnimation(bool animation) +{ + m_animationEnabled = animation; +} + +NzAnimation* NzSkeletalModel::GetAnimation() const +{ + return m_animation; +} + +NzSkeleton* NzSkeletalModel::GetSkeleton() +{ + InvalidateBoundingVolume(); + + return &m_skeleton; +} + +const NzSkeleton* NzSkeletalModel::GetSkeleton() const +{ + return &m_skeleton; +} + +bool NzSkeletalModel::HasAnimation() const +{ + return m_animation != nullptr; +} + +bool NzSkeletalModel::IsAnimated() const +{ + return true; +} + +bool NzSkeletalModel::IsAnimationEnabled() const +{ + return m_animationEnabled; +} + +bool NzSkeletalModel::IsDrawable() const +{ + return m_mesh != nullptr && m_mesh->GetSubMeshCount() >= 1; +} + +bool NzSkeletalModel::LoadFromFile(const NzString& filePath, const NzSkeletalModelParameters& params) +{ + return NzSkeletalModelLoader::LoadFromFile(this, filePath, params); +} + +bool NzSkeletalModel::LoadFromMemory(const void* data, std::size_t size, const NzSkeletalModelParameters& params) +{ + return NzSkeletalModelLoader::LoadFromMemory(this, data, size, params); +} + +bool NzSkeletalModel::LoadFromStream(NzInputStream& stream, const NzSkeletalModelParameters& params) +{ + return NzSkeletalModelLoader::LoadFromStream(this, stream, params); +} + +void NzSkeletalModel::Reset() +{ + NzModel::Reset(); + + m_skeleton.Destroy(); + + if (m_scene) + m_scene->UnregisterForUpdate(this); +} + +bool NzSkeletalModel::SetAnimation(NzAnimation* animation) +{ + #if NAZARA_GRAPHICS_SAFE + if (!m_mesh) + { + NazaraError("Model has no mesh"); + return false; + } + + if (animation) + { + if (!animation->IsValid()) + { + NazaraError("Invalid animation"); + return false; + } + + if (animation->GetType() != m_mesh->GetAnimationType()) + { + NazaraError("Animation type must match mesh animation type"); + return false; + } + + if (animation->GetJointCount() != m_mesh->GetJointCount()) + { + NazaraError("Animation joint count must match mesh joint count"); + return false; + } + } + #endif + + m_animation = animation; + if (m_animation) + { + m_currentFrame = 0; + m_interpolation = 0.f; + + SetSequence(0); + + if (m_scene) + m_scene->RegisterForUpdate(this); + } + else if (m_scene) + m_scene->UnregisterForUpdate(this); + + return true; +} + +void NzSkeletalModel::SetMesh(NzMesh* mesh) +{ + #if NAZARA_GRAPHICS_SAFE + if (mesh && mesh->GetAnimationType() != nzAnimationType_Skeletal) + { + NazaraError("Mesh animation type must be skeletal"); + return; + } + #endif + + NzModel::SetMesh(mesh); + + if (m_mesh) + { + if (m_animation && m_animation->GetJointCount() != m_mesh->GetJointCount()) + { + NazaraWarning("Animation joint count is not matching new mesh joint count, disabling animation..."); + SetAnimation(nullptr); + } + + m_skeleton = *m_mesh->GetSkeleton(); // Copie du squelette template + } +} + +bool NzSkeletalModel::SetSequence(const NzString& sequenceName) +{ + ///TODO: Rendre cette erreur "safe" avec le nouveau système de gestions d'erreur (No-log) + #if NAZARA_GRAPHICS_SAFE + if (!m_animation) + { + NazaraError("Model has no animation"); + return false; + } + #endif + + const NzSequence* currentSequence = m_animation->GetSequence(sequenceName); + if (!currentSequence) + { + NazaraError("Sequence not found"); + return false; + } + + m_currentSequence = currentSequence; + m_nextFrame = m_currentSequence->firstFrame; + + return true; +} + +void NzSkeletalModel::SetSequence(unsigned int sequenceIndex) +{ + #if NAZARA_GRAPHICS_SAFE + if (!m_animation) + { + NazaraError("Model has no animation"); + return; + } + #endif + + const NzSequence* currentSequence = m_animation->GetSequence(sequenceIndex); + #if NAZARA_GRAPHICS_SAFE + if (!currentSequence) + { + NazaraError("Sequence not found"); + return; + } + #endif + + m_currentSequence = currentSequence; + m_nextFrame = m_currentSequence->firstFrame; +} + +NzSkeletalModel& NzSkeletalModel::operator=(const NzSkeletalModel& node) +{ + NzSkeletalModel::operator=(node); + + m_animation = node.m_animation; + m_animationEnabled = node.m_animationEnabled; + m_currentFrame = node.m_currentFrame; + m_currentSequence = node.m_currentSequence; + m_interpolation = node.m_interpolation; + m_nextFrame = node.m_nextFrame; + m_skeleton = node.m_skeleton; + + return *this; +} + +NzSkeletalModel& NzSkeletalModel::operator=(NzSkeletalModel&& node) +{ + NzModel::operator=(node); + + // Ressources + m_animation = std::move(node.m_animation); + m_skeleton = std::move(node.m_skeleton); + + // Paramètres + m_animationEnabled = node.m_animationEnabled; + m_currentFrame = node.m_currentFrame; + m_currentSequence = node.m_currentSequence; + m_interpolation = node.m_interpolation; + m_nextFrame = node.m_nextFrame; + + return *this; +} + +void NzSkeletalModel::Register() +{ + if (m_animation) + m_scene->RegisterForUpdate(this); +} + +void NzSkeletalModel::Unregister() +{ + m_scene->UnregisterForUpdate(this); +} + +void NzSkeletalModel::Update() +{ + if (m_animationEnabled && m_animation) + AdvanceAnimation(m_scene->GetUpdateTime()); +} + +void NzSkeletalModel::UpdateBoundingVolume() const +{ + if (m_boundingVolume.IsNull()) + m_boundingVolume.Set(m_skeleton.GetAABB()); + + if (!m_transformMatrixUpdated) + UpdateTransformMatrix(); + + m_boundingVolume.Update(m_transformMatrix); + m_boundingVolumeUpdated = true; +} + +NzSkeletalModelLoader::LoaderList NzSkeletalModel::s_loaders; From 93314d5c0ee8107e7b5b27e2d6f4641b611518ab Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 17 Dec 2014 14:00:04 +0100 Subject: [PATCH 100/233] Fixed error messages Former-commit-id: e7dc2e53f9bce6676ac00ff17a36d2bcf8f10253 --- src/Nazara/Utility/Image.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index 407a376b3..7dc412dc8 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -468,7 +468,7 @@ bool NzImage::Fill(const NzColor& color, const NzRectui& rect, unsigned int z) return false; } - if (rect.x+rect.width > m_sharedImage->width || rect.y+rect.height > m_sharedImage->height) + if (rect.x + rect.width > m_sharedImage->width || rect.y + rect.height > m_sharedImage->height) { NazaraError("Rectangle dimensions are out of bounds"); return false; @@ -477,7 +477,7 @@ bool NzImage::Fill(const NzColor& color, const NzRectui& rect, unsigned int z) unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth; if (z >= depth) { - NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(depth) + ')'); + NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= " + NzString::Number(depth) + ')'); return false; } #endif @@ -697,20 +697,20 @@ NzColor NzImage::GetPixelColor(unsigned int x, unsigned int y, unsigned int z) c if (x >= m_sharedImage->width) { - NazaraError("X value exceeds width (" + NzString::Number(x) + " >= (" + NzString::Number(m_sharedImage->width) + ')'); + NazaraError("X value exceeds width (" + NzString::Number(x) + " >= " + NzString::Number(m_sharedImage->width) + ')'); return NzColor(); } if (y >= m_sharedImage->height) { - NazaraError("Y value exceeds height (" + NzString::Number(y) + " >= (" + NzString::Number(m_sharedImage->height) + ')'); + NazaraError("Y value exceeds height (" + NzString::Number(y) + " >= " + NzString::Number(m_sharedImage->height) + ')'); return NzColor(); } unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth; if (z >= depth) { - NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(depth) + ')'); + NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= " + NzString::Number(depth) + ')'); return NzColor(); } #endif @@ -744,7 +744,7 @@ nzUInt8* NzImage::GetPixels(unsigned int x, unsigned int y, unsigned int z, nzUI #if NAZARA_UTILITY_SAFE if (x >= width) { - NazaraError("X value exceeds width (" + NzString::Number(x) + " >= (" + NzString::Number(width) + ')'); + NazaraError("X value exceeds width (" + NzString::Number(x) + " >= " + NzString::Number(width) + ')'); return nullptr; } #endif @@ -753,14 +753,14 @@ nzUInt8* NzImage::GetPixels(unsigned int x, unsigned int y, unsigned int z, nzUI #if NAZARA_UTILITY_SAFE if (y >= height) { - NazaraError("Y value exceeds height (" + NzString::Number(y) + " >= (" + NzString::Number(height) + ')'); + NazaraError("Y value exceeds height (" + NzString::Number(y) + " >= " + NzString::Number(height) + ')'); return nullptr; } unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : GetLevelSize(m_sharedImage->depth, level); if (z >= depth) { - NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(depth) + ')'); + NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= " + NzString::Number(depth) + ')'); return nullptr; } @@ -1157,20 +1157,20 @@ bool NzImage::SetPixelColor(const NzColor& color, unsigned int x, unsigned int y if (x >= m_sharedImage->width) { - NazaraError("X value exceeds width (" + NzString::Number(x) + " >= (" + NzString::Number(m_sharedImage->width) + ')'); + NazaraError("X value exceeds width (" + NzString::Number(x) + " >= " + NzString::Number(m_sharedImage->width) + ')'); return false; } if (y >= m_sharedImage->height) { - NazaraError("Y value exceeds height (" + NzString::Number(y) + " >= (" + NzString::Number(m_sharedImage->height) + ')'); + NazaraError("Y value exceeds height (" + NzString::Number(y) + " >= " + NzString::Number(m_sharedImage->height) + ')'); return false; } unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth; if (z >= depth) { - NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(depth) + ')'); + NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= " + NzString::Number(depth) + ')'); return false; } #endif From 57b90112fb6c99c799f6595d31ef15c108a16278 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 17 Dec 2014 14:15:22 +0100 Subject: [PATCH 101/233] Removed useless includes Former-commit-id: 63c91b06d959075435fd03c740953be3537ca959 --- src/Nazara/Core/Resource.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Nazara/Core/Resource.cpp b/src/Nazara/Core/Resource.cpp index 461cda9b2..5610d9d13 100644 --- a/src/Nazara/Core/Resource.cpp +++ b/src/Nazara/Core/Resource.cpp @@ -6,9 +6,6 @@ #include #include #include -#include -#include -#include #if NAZARA_CORE_THREADSAFE && NAZARA_THREADSAFETY_RESOURCE #include From 2bfb798dd9e97dfc8699dada8e7abef7bf94a2c7 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 3 Jan 2015 21:45:37 +0100 Subject: [PATCH 102/233] Minor changes Former-commit-id: fd74c48a546663f4d4802826ee2d396b0874e2c9 --- include/Nazara/Lua/LuaClass.inl | 1 - src/Nazara/Core/File.cpp | 2 +- src/Nazara/Lua/LuaInstance.cpp | 2 +- src/Nazara/Renderer/Context.cpp | 2 +- src/Nazara/Renderer/Renderer.cpp | 2 +- src/Nazara/Renderer/Shader.cpp | 6 +++--- 6 files changed, 7 insertions(+), 8 deletions(-) diff --git a/include/Nazara/Lua/LuaClass.inl b/include/Nazara/Lua/LuaClass.inl index a63adc081..79c8a88ce 100644 --- a/include/Nazara/Lua/LuaClass.inl +++ b/include/Nazara/Lua/LuaClass.inl @@ -3,7 +3,6 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include #include #include diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index aa803a9fa..512a29144 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -733,7 +733,7 @@ bool NzFile::FillHash(NzAbstractHash* hash) const unsigned int size; while (remainingSize > 0) { - size = (remainingSize >= NAZARA_CORE_FILE_BUFFERSIZE) ? NAZARA_CORE_FILE_BUFFERSIZE : static_cast(remainingSize); + size = std::min(remainingSize, static_cast(NAZARA_CORE_FILE_BUFFERSIZE)); if (file.Read(&buffer[0], sizeof(char), size) != sizeof(char)*size) { NazaraError("Unable to read file"); diff --git a/src/Nazara/Lua/LuaInstance.cpp b/src/Nazara/Lua/LuaInstance.cpp index f6436138b..c1d0c96c8 100644 --- a/src/Nazara/Lua/LuaInstance.cpp +++ b/src/Nazara/Lua/LuaInstance.cpp @@ -557,7 +557,7 @@ bool NzLuaInstance::IsOfType(int index, nzLuaType type) const return lua_isuserdata(m_state, index) == 1; } - NazaraError("Lua type unhandled (0x" + NzString::Number(type, 16) + ')'); + NazaraError("Lua type not handled (0x" + NzString::Number(type, 16) + ')'); return false; } diff --git a/src/Nazara/Renderer/Context.cpp b/src/Nazara/Renderer/Context.cpp index 031e9b780..10654fcc3 100644 --- a/src/Nazara/Renderer/Context.cpp +++ b/src/Nazara/Renderer/Context.cpp @@ -38,7 +38,7 @@ namespace switch (source) { case GL_DEBUG_SOURCE_API: - ss << "OpenGL"; + ss << "OpenGL API"; break; case GL_DEBUG_SOURCE_WINDOW_SYSTEM: diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index 0552d8e38..28e0b5288 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -924,7 +924,7 @@ bool NzRenderer::IsComponentTypeSupported(nzComponentType type) return false; } - NazaraError("Attribute type out of enum (0x" + NzString::Number(type, 16) + ')'); + NazaraError("Attribute type not handled (0x" + NzString::Number(type, 16) + ')'); return false; } diff --git a/src/Nazara/Renderer/Shader.cpp b/src/Nazara/Renderer/Shader.cpp index 7729c1035..8d9239da2 100644 --- a/src/Nazara/Renderer/Shader.cpp +++ b/src/Nazara/Renderer/Shader.cpp @@ -254,10 +254,10 @@ NzString NzShader::GetSourceCode(nzShaderStage stage) const unsigned int totalLength = 0; for (unsigned int shader : m_attachedShaders[stage]) { - GLint length; - glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &length); + GLint length; + glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &length); - totalLength += length - 1; + totalLength += length - 1; } totalLength += (m_attachedShaders[stage].size()-1)*(sizeof(sep)/sizeof(char)); From 92df395a0eef8de58c268bdf06a34c7e75daeac6 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 3 Jan 2015 21:46:32 +0100 Subject: [PATCH 103/233] Fixed TriangleIterator with TriangleStrip mode Former-commit-id: 4d0303859e4818e9f5592b0226cb479f1c9d1ef3 --- src/Nazara/Utility/TriangleIterator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Utility/TriangleIterator.cpp b/src/Nazara/Utility/TriangleIterator.cpp index 72003cf8b..e8bd7af08 100644 --- a/src/Nazara/Utility/TriangleIterator.cpp +++ b/src/Nazara/Utility/TriangleIterator.cpp @@ -46,8 +46,8 @@ bool NzTriangleIterator::Advance() case nzPrimitiveMode_TriangleStrip: m_triangleIndices[2] = m_indexMapper.Get(m_currentIndex++); - m_triangleIndices[1] = m_triangleIndices[2]; m_triangleIndices[0] = m_triangleIndices[1]; + m_triangleIndices[1] = m_triangleIndices[2]; break; default: From e6090c80a8de22ba09e5b33f9d698ba013dd27fa Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 3 Jan 2015 21:47:40 +0100 Subject: [PATCH 104/233] Added default implementation of Unicode class Working for the ASCII set Former-commit-id: 70b1fdbb94ba91861494f64bf169c89bbfecc9ce --- src/Nazara/Core/Unicode.cpp | 326 +++++++++++++++++++++++++++++++++++- 1 file changed, 320 insertions(+), 6 deletions(-) diff --git a/src/Nazara/Core/Unicode.cpp b/src/Nazara/Core/Unicode.cpp index ac72ecc9b..a00abfdac 100644 --- a/src/Nazara/Core/Unicode.cpp +++ b/src/Nazara/Core/Unicode.cpp @@ -18,34 +18,348 @@ struct Character #include -#else // Implémentation bidon +#else // Implémentation supportant la table ASCII NzUnicode::Category NzUnicode::GetCategory(char32_t character) { - NazaraUnused(character); + switch (character) + { + case '\x00': + case '\x01': + case '\x02': + case '\x03': + case '\x04': + case '\x05': + case '\x06': + case '\x07': + case '\x08': + case '\x09': + case '\x0A': + case '\x0B': + case '\x0C': + case '\x0D': + case '\x0E': + case '\x0F': + case '\x10': + case '\x11': + case '\x12': + case '\x13': + case '\x14': + case '\x15': + case '\x16': + case '\x17': + case '\x18': + case '\x19': + case '\x1A': + case '\x1B': + case '\x1C': + case '\x1D': + case '\x1E': + case '\x1F': + case '\x7F': + return Category_Other_Control; + + case ' ': + return Category_Separator_Space; + + case '!': + case '"': + case '#': + case '$': + case '%': + case '&': + case '\'': + case '*': + case ',': + case '.': + case '/': + case ':': + case ';': + case '?': + case '@': + case '\\': + return Category_Punctuation_Other; + + case '(': + case '[': + case '{': + return Category_Punctuation_Open; + + case ')': + case '}': + case ']': + return Category_Punctuation_Close; + + case '+': + case '<': + case '=': + case '>': + case '|': + case '~': + return Category_Symbol_Math; + + case '-': + return Category_Punctuation_Dash; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + return Category_Number_DecimalDigit; + + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + return Category_Number_DecimalDigit; + + case '_': + return Category_Punctuation_Connector; + + case '^': + case '`': + return Category_Symbol_Modifier; + + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': + return Category_Number_DecimalDigit; + + default: + break; + } return Category_NoCategory; } NzUnicode::Direction NzUnicode::GetDirection(char32_t character) { - NazaraUnused(character); + switch (character) + { + case '\x00': + case '\x01': + case '\x02': + case '\x03': + case '\x04': + case '\x05': + case '\x06': + case '\x07': + case '\x08': + case '\x0E': + case '\x0F': + case '\x10': + case '\x11': + case '\x12': + case '\x13': + case '\x14': + case '\x15': + case '\x16': + case '\x17': + case '\x18': + case '\x19': + case '\x1A': + case '\x1B': + case '\x7F': + return Direction_Boundary_Neutral; + + case '\x09': + case '\x0B': + case '\x1F': + return Direction_Segment_Separator; + + case '\x0A': + case '\x0D': + case '\x1C': + case '\x1D': + case '\x1E': + return Direction_Paragraph_Separator; + + case '\x0C': + case ' ': + return Direction_White_Space; + + case '!': + case '"': + case '&': + case '\'': + case '(': + case ')': + case '*': + case ';': + case '<': + case '=': + case '>': + case '?': + case '@': + case '[': + case '\\': + case ']': + case '^': + case '_': + case '`': + case '{': + case '|': + case '}': + case '~': + return Direction_Other_Neutral; + + case '#': + case '$': + case '%': + return Direction_European_Terminator; + + case '+': + case '-': + return Direction_European_Separator; + + case ',': + case '.': + case '/': + case ':': + return Direction_Common_Separator; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + return Direction_European_Number; + + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': + return Direction_Left_To_Right; + + default: + break; + } return Direction_Boundary_Neutral; } char32_t NzUnicode::GetLowercase(char32_t character) { - return character; + if (character >= 'A' && character <= 'Z') + return character + ('a' - 'A'); + else + return character; } char32_t NzUnicode::GetTitlecase(char32_t character) { - return character; + return GetUppercase(character); } char32_t NzUnicode::GetUppercase(char32_t character) { - return character; + if (character >= 'a' && character <= 'z') + return character + ('A' - 'a'); + else + return character; } #endif From ad3c70bbc8b9f486d08cced1e337015ba4e372d5 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 3 Jan 2015 21:50:37 +0100 Subject: [PATCH 105/233] Added SparsePtr substraction operator Former-commit-id: e2dadc06b1f1abbd257689e6eaee77ebbfa0af5b --- include/Nazara/Core/SparsePtr.hpp | 2 ++ include/Nazara/Core/SparsePtr.inl | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/include/Nazara/Core/SparsePtr.hpp b/include/Nazara/Core/SparsePtr.hpp index 74a64425d..8d104827c 100644 --- a/include/Nazara/Core/SparsePtr.hpp +++ b/include/Nazara/Core/SparsePtr.hpp @@ -10,6 +10,7 @@ ///FIXME: Est-ce que SparsePtr est vraiment le meilleur nom pour cette classe ? #include +#include #include template @@ -46,6 +47,7 @@ class NzSparsePtr NzSparsePtr operator+(int count) const; NzSparsePtr operator-(int count) const; + std::ptrdiff_t operator-(const NzSparsePtr& ptr) const; NzSparsePtr& operator+=(int count); NzSparsePtr& operator-=(int count); diff --git a/include/Nazara/Core/SparsePtr.inl b/include/Nazara/Core/SparsePtr.inl index 661c9292a..eb6c988ae 100644 --- a/include/Nazara/Core/SparsePtr.inl +++ b/include/Nazara/Core/SparsePtr.inl @@ -133,6 +133,12 @@ NzSparsePtr NzSparsePtr::operator-(int count) const return NzSparsePtr(m_ptr - count*m_stride, m_stride); } +template +std::ptrdiff_t NzSparsePtr::operator-(const NzSparsePtr& ptr) const +{ + return (m_ptr - ptr.m_ptr)/m_stride; +} + template NzSparsePtr& NzSparsePtr::operator+=(int count) { From a1624af969f9cf07e2056f2399b999396f86f3af Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 3 Jan 2015 22:15:15 +0100 Subject: [PATCH 106/233] Improved [Box|Rect]::Intersect performances Allowed early returns Former-commit-id: 59001afdd9734666640d440cb8b87b5a426973ce --- include/Nazara/Math/Box.inl | 35 +++++++++++++++++++---------------- include/Nazara/Math/Rect.inl | 34 +++++++++++++++++----------------- 2 files changed, 36 insertions(+), 33 deletions(-) diff --git a/include/Nazara/Math/Box.inl b/include/Nazara/Math/Box.inl index 744d513ab..651a6de13 100644 --- a/include/Nazara/Math/Box.inl +++ b/include/Nazara/Math/Box.inl @@ -247,27 +247,30 @@ bool NzBox::Intersect(const NzBox& box, NzBox* intersection) const { T left = std::max(x, box.x); T right = std::min(x + width, box.x + box.width); + if (left >= right) + return false; + T top = std::max(y, box.y); T bottom = std::min(y + height, box.y + box.height); + if (top >= bottom) + return false; + T up = std::max(z, box.z); T down = std::min(z + depth, box.z + box.depth); - - if (left < right && top < bottom && up < down) - { - if (intersection) - { - intersection->x = left; - intersection->y = top; - intersection->z = up; - intersection->width = right - left; - intersection->height = bottom - top; - intersection->depth = down - up; - } - - return true; - } - else + if (up >= down) return false; + + if (intersection) + { + intersection->x = left; + intersection->y = top; + intersection->z = up; + intersection->width = right - left; + intersection->height = bottom - top; + intersection->depth = down - up; + } + + return true; } template diff --git a/include/Nazara/Math/Rect.inl b/include/Nazara/Math/Rect.inl index 611403706..3d1908b83 100644 --- a/include/Nazara/Math/Rect.inl +++ b/include/Nazara/Math/Rect.inl @@ -166,24 +166,24 @@ template bool NzRect::Intersect(const NzRect& rect, NzRect* intersection) const { T left = std::max(x, rect.x); - T right = std::min(x+width, rect.x+rect.width); - T top = std::max(y, rect.y); - T bottom = std::min(y+height, rect.y+rect.height); - - if (left < right && top < bottom) - { - if (intersection) - { - intersection->x = left; - intersection->y = top; - intersection->width = right-left; - intersection->height = bottom-top; - } - - return true; - } - else + T right = std::min(x + width, rect.x + rect.width); + if (left >= right) return false; + + T top = std::max(y, rect.y); + T bottom = std::min(y + height, rect.y + rect.height); + if (top >= bottom) + return false; + + if (intersection) + { + intersection->x = left; + intersection->y = top; + intersection->width = right - left; + intersection->height = bottom - top; + } + + return true; } template From 7c47a93a72d51be27b1f8f03e7cebaea9dd25022 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 3 Jan 2015 22:31:25 +0100 Subject: [PATCH 107/233] Renamed Corner enum to BoxCorner Added RectCorner and Rect::GetCorner method Former-commit-id: dc99823ceb17f6e91cdf12779c982ab7e024ec24 --- include/Nazara/Math/Box.hpp | 2 +- include/Nazara/Math/Box.inl | 18 +++--- include/Nazara/Math/Enums.hpp | 30 ++++++--- include/Nazara/Math/Frustum.hpp | 4 +- include/Nazara/Math/Frustum.inl | 50 +++++++-------- include/Nazara/Math/OrientedBox.hpp | 4 +- include/Nazara/Math/OrientedBox.inl | 30 ++++----- include/Nazara/Math/Ray.inl | 6 +- include/Nazara/Math/Rect.hpp | 2 + include/Nazara/Math/Rect.inl | 22 +++++++ src/Nazara/Renderer/DebugDrawer.cpp | 96 ++++++++++++++--------------- 11 files changed, 149 insertions(+), 115 deletions(-) diff --git a/include/Nazara/Math/Box.hpp b/include/Nazara/Math/Box.hpp index 0409caffc..1705f25df 100644 --- a/include/Nazara/Math/Box.hpp +++ b/include/Nazara/Math/Box.hpp @@ -38,7 +38,7 @@ class NzBox NzBox& ExtendTo(const NzVector3& point); NzSphere GetBoundingSphere() const; - NzVector3 GetCorner(nzCorner corner) const; + NzVector3 GetCorner(nzBoxCorner corner) const; NzVector3 GetCenter() const; NzVector3 GetLengths() const; NzVector3 GetMaximum() const; diff --git a/include/Nazara/Math/Box.inl b/include/Nazara/Math/Box.inl index 651a6de13..11578f605 100644 --- a/include/Nazara/Math/Box.inl +++ b/include/Nazara/Math/Box.inl @@ -117,32 +117,32 @@ NzBox& NzBox::ExtendTo(const NzVector3& point) } template -NzVector3 NzBox::GetCorner(nzCorner corner) const +NzVector3 NzBox::GetCorner(nzBoxCorner corner) const { switch (corner) { - case nzCorner_FarLeftBottom: + case nzBoxCorner_FarLeftBottom: return NzVector3(x, y, z); - case nzCorner_FarLeftTop: + case nzBoxCorner_FarLeftTop: return NzVector3(x, y + height, z); - case nzCorner_FarRightBottom: + case nzBoxCorner_FarRightBottom: return NzVector3(x + width, y, z); - case nzCorner_FarRightTop: + case nzBoxCorner_FarRightTop: return NzVector3(x + width, y + height, z); - case nzCorner_NearLeftBottom: + case nzBoxCorner_NearLeftBottom: return NzVector3(x, y, z + depth); - case nzCorner_NearLeftTop: + case nzBoxCorner_NearLeftTop: return NzVector3(x, y + height, z + depth); - case nzCorner_NearRightBottom: + case nzBoxCorner_NearRightBottom: return NzVector3(x + width, y, z + depth); - case nzCorner_NearRightTop: + case nzBoxCorner_NearRightTop: return NzVector3(x + width, y + height, z + depth); } diff --git a/include/Nazara/Math/Enums.hpp b/include/Nazara/Math/Enums.hpp index efa249643..214c9958c 100644 --- a/include/Nazara/Math/Enums.hpp +++ b/include/Nazara/Math/Enums.hpp @@ -7,18 +7,18 @@ #ifndef NAZARA_ENUMS_MATH_HPP #define NAZARA_ENUMS_MATH_HPP -enum nzCorner +enum nzBoxCorner { - nzCorner_FarLeftBottom, - nzCorner_FarLeftTop, - nzCorner_FarRightBottom, - nzCorner_FarRightTop, - nzCorner_NearLeftBottom, - nzCorner_NearLeftTop, - nzCorner_NearRightBottom, - nzCorner_NearRightTop, + nzBoxCorner_FarLeftBottom, + nzBoxCorner_FarLeftTop, + nzBoxCorner_FarRightBottom, + nzBoxCorner_FarRightTop, + nzBoxCorner_NearLeftBottom, + nzBoxCorner_NearLeftTop, + nzBoxCorner_NearRightBottom, + nzBoxCorner_NearRightTop, - nzCorner_Max = nzCorner_NearRightTop + nzBoxCorner_Max = nzBoxCorner_NearRightTop }; enum nzExtend @@ -51,4 +51,14 @@ enum nzIntersectionSide nzIntersectionSide_Max = nzIntersectionSide_Outside }; +enum nzRectCorner +{ + nzRectCorner_LeftBottom, + nzRectCorner_LeftTop, + nzRectCorner_RightBottom, + nzRectCorner_RightTop, + + nzRectCorner_Max = nzRectCorner_RightTop +}; + #endif // NAZARA_ENUMS_MATH_HPP diff --git a/include/Nazara/Math/Frustum.hpp b/include/Nazara/Math/Frustum.hpp index e5de19b50..f94c229b0 100644 --- a/include/Nazara/Math/Frustum.hpp +++ b/include/Nazara/Math/Frustum.hpp @@ -37,7 +37,7 @@ class NzFrustum NzFrustum& Extract(const NzMatrix4& clipMatrix); NzFrustum& Extract(const NzMatrix4& view, const NzMatrix4& projection); - const NzVector3& GetCorner(nzCorner corner) const; + const NzVector3& GetCorner(nzBoxCorner corner) const; const NzPlane& GetPlane(nzFrustumPlane plane) const; nzIntersectionSide Intersect(const NzBoundingVolume& volume) const; @@ -52,7 +52,7 @@ class NzFrustum NzString ToString() const; private: - NzVector3 m_corners[nzCorner_Max+1]; + NzVector3 m_corners[nzBoxCorner_Max+1]; NzPlane m_planes[nzFrustumPlane_Max+1]; }; diff --git a/include/Nazara/Math/Frustum.inl b/include/Nazara/Math/Frustum.inl index 0a7b02215..336f5ad0a 100644 --- a/include/Nazara/Math/Frustum.inl +++ b/include/Nazara/Math/Frustum.inl @@ -44,23 +44,23 @@ NzFrustum& NzFrustum::Build(T angle, T ratio, T zNear, T zFar, const NzVec NzVector3 fc = eye + f * zFar; // Calcul du frustum - m_corners[nzCorner_FarLeftBottom] = fc - u*farH - s*farW; - m_corners[nzCorner_FarLeftTop] = fc + u*farH - s*farW; - m_corners[nzCorner_FarRightTop] = fc + u*farH + s*farW; - m_corners[nzCorner_FarRightBottom] = fc - u*farH + s*farW; + m_corners[nzBoxCorner_FarLeftBottom] = fc - u*farH - s*farW; + m_corners[nzBoxCorner_FarLeftTop] = fc + u*farH - s*farW; + m_corners[nzBoxCorner_FarRightTop] = fc + u*farH + s*farW; + m_corners[nzBoxCorner_FarRightBottom] = fc - u*farH + s*farW; - m_corners[nzCorner_NearLeftBottom] = nc - u*nearH - s*nearW; - m_corners[nzCorner_NearLeftTop] = nc + u*nearH - s*nearW; - m_corners[nzCorner_NearRightTop] = nc + u*nearH + s*nearW; - m_corners[nzCorner_NearRightBottom] = nc - u*nearH + s*nearW; + m_corners[nzBoxCorner_NearLeftBottom] = nc - u*nearH - s*nearW; + m_corners[nzBoxCorner_NearLeftTop] = nc + u*nearH - s*nearW; + m_corners[nzBoxCorner_NearRightTop] = nc + u*nearH + s*nearW; + m_corners[nzBoxCorner_NearRightBottom] = nc - u*nearH + s*nearW; // Construction des plans du frustum - m_planes[nzFrustumPlane_Bottom].Set(m_corners[nzCorner_NearLeftBottom], m_corners[nzCorner_NearRightBottom], m_corners[nzCorner_FarRightBottom]); - m_planes[nzFrustumPlane_Far].Set(m_corners[nzCorner_FarRightTop], m_corners[nzCorner_FarLeftTop], m_corners[nzCorner_FarLeftBottom]); - m_planes[nzFrustumPlane_Left].Set(m_corners[nzCorner_NearLeftTop], m_corners[nzCorner_NearLeftBottom], m_corners[nzCorner_FarLeftBottom]); - m_planes[nzFrustumPlane_Near].Set(m_corners[nzCorner_NearLeftTop], m_corners[nzCorner_NearRightTop], m_corners[nzCorner_NearRightBottom]); - m_planes[nzFrustumPlane_Right].Set(m_corners[nzCorner_NearRightBottom], m_corners[nzCorner_NearRightTop], m_corners[nzCorner_FarRightBottom]); - m_planes[nzFrustumPlane_Top].Set(m_corners[nzCorner_NearRightTop], m_corners[nzCorner_NearLeftTop], m_corners[nzCorner_FarLeftTop]); + m_planes[nzFrustumPlane_Bottom].Set(m_corners[nzBoxCorner_NearLeftBottom], m_corners[nzBoxCorner_NearRightBottom], m_corners[nzBoxCorner_FarRightBottom]); + m_planes[nzFrustumPlane_Far].Set(m_corners[nzBoxCorner_FarRightTop], m_corners[nzBoxCorner_FarLeftTop], m_corners[nzBoxCorner_FarLeftBottom]); + m_planes[nzFrustumPlane_Left].Set(m_corners[nzBoxCorner_NearLeftTop], m_corners[nzBoxCorner_NearLeftBottom], m_corners[nzBoxCorner_FarLeftBottom]); + m_planes[nzFrustumPlane_Near].Set(m_corners[nzBoxCorner_NearLeftTop], m_corners[nzBoxCorner_NearRightTop], m_corners[nzBoxCorner_NearRightBottom]); + m_planes[nzFrustumPlane_Right].Set(m_corners[nzBoxCorner_NearRightBottom], m_corners[nzBoxCorner_NearRightTop], m_corners[nzBoxCorner_FarRightBottom]); + m_planes[nzFrustumPlane_Top].Set(m_corners[nzBoxCorner_NearRightTop], m_corners[nzBoxCorner_NearLeftTop], m_corners[nzBoxCorner_FarLeftTop]); return *this; } @@ -272,56 +272,56 @@ NzFrustum& NzFrustum::Extract(const NzMatrix4& clipMatrix) corner = invClipMatrix.Transform(corner); corner.Normalize(); - m_corners[nzCorner_FarLeftBottom] = NzVector3(corner.x, corner.y, corner.z); + m_corners[nzBoxCorner_FarLeftBottom] = NzVector3(corner.x, corner.y, corner.z); // FarLeftTop corner.Set(F(-1.0), F(1.0), F(1.0)); corner = invClipMatrix.Transform(corner); corner.Normalize(); - m_corners[nzCorner_FarLeftTop] = NzVector3(corner.x, corner.y, corner.z); + m_corners[nzBoxCorner_FarLeftTop] = NzVector3(corner.x, corner.y, corner.z); // FarRightBottom corner.Set(F(1.0), F(-1.0), F(1.0)); corner = invClipMatrix.Transform(corner); corner.Normalize(); - m_corners[nzCorner_FarRightBottom] = NzVector3(corner.x, corner.y, corner.z); + m_corners[nzBoxCorner_FarRightBottom] = NzVector3(corner.x, corner.y, corner.z); // FarRightTop corner.Set(F(1.0), F(1.0), F(1.0)); corner = invClipMatrix.Transform(corner); corner.Normalize(); - m_corners[nzCorner_FarRightTop] = NzVector3(corner.x, corner.y, corner.z); + m_corners[nzBoxCorner_FarRightTop] = NzVector3(corner.x, corner.y, corner.z); // NearLeftBottom corner.Set(F(-1.0), F(-1.0), F(0.0)); corner = invClipMatrix.Transform(corner); corner.Normalize(); - m_corners[nzCorner_NearLeftBottom] = NzVector3(corner.x, corner.y, corner.z); + m_corners[nzBoxCorner_NearLeftBottom] = NzVector3(corner.x, corner.y, corner.z); // NearLeftTop corner.Set(F(-1.0), F(1.0), F(0.0)); corner = invClipMatrix.Transform(corner); corner.Normalize(); - m_corners[nzCorner_NearLeftTop] = NzVector3(corner.x, corner.y, corner.z); + m_corners[nzBoxCorner_NearLeftTop] = NzVector3(corner.x, corner.y, corner.z); // NearRightBottom corner.Set(F(1.0), F(-1.0), F(0.0)); corner = invClipMatrix.Transform(corner); corner.Normalize(); - m_corners[nzCorner_NearRightBottom] = NzVector3(corner.x, corner.y, corner.z); + m_corners[nzBoxCorner_NearRightBottom] = NzVector3(corner.x, corner.y, corner.z); // NearRightTop corner.Set(F(1.0), F(1.0), F(0.0)); corner = invClipMatrix.Transform(corner); corner.Normalize(); - m_corners[nzCorner_NearRightTop] = NzVector3(corner.x, corner.y, corner.z); + m_corners[nzBoxCorner_NearRightTop] = NzVector3(corner.x, corner.y, corner.z); } else NazaraWarning("Clip matrix is not invertible, failed to compute frustum corners"); @@ -339,10 +339,10 @@ NzFrustum& NzFrustum::Extract(const NzMatrix4& view, const NzMatrix4 } template -const NzVector3& NzFrustum::GetCorner(nzCorner corner) const +const NzVector3& NzFrustum::GetCorner(nzBoxCorner corner) const { #ifdef NAZARA_DEBUG - if (corner > nzCorner_Max) + if (corner > nzBoxCorner_Max) { NazaraError("Corner not handled (0x" + NzString::Number(corner, 16) + ')'); @@ -481,7 +481,7 @@ template template NzFrustum& NzFrustum::Set(const NzFrustum& frustum) { - for (unsigned int i = 0; i <= nzCorner_Max; ++i) + for (unsigned int i = 0; i <= nzBoxCorner_Max; ++i) m_corners[i].Set(frustum.m_corners[i]); for (unsigned int i = 0; i <= nzFrustumPlane_Max; ++i) diff --git a/include/Nazara/Math/OrientedBox.hpp b/include/Nazara/Math/OrientedBox.hpp index 9f5b711b6..b6ea75fd7 100644 --- a/include/Nazara/Math/OrientedBox.hpp +++ b/include/Nazara/Math/OrientedBox.hpp @@ -24,7 +24,7 @@ class NzOrientedBox NzOrientedBox(const NzOrientedBox& orientedBox) = default; ~NzOrientedBox() = default; - const NzVector3& GetCorner(nzCorner corner) const; + const NzVector3& GetCorner(nzBoxCorner corner) const; bool IsValid() const; @@ -59,7 +59,7 @@ class NzOrientedBox NzBox localBox; private: - NzVector3 m_corners[nzCorner_Max+1]; // Ne peuvent pas être modifiés directement + NzVector3 m_corners[nzBoxCorner_Max+1]; // Ne peuvent pas être modifiés directement }; template diff --git a/include/Nazara/Math/OrientedBox.inl b/include/Nazara/Math/OrientedBox.inl index 992698bad..8d242d52e 100644 --- a/include/Nazara/Math/OrientedBox.inl +++ b/include/Nazara/Math/OrientedBox.inl @@ -37,10 +37,10 @@ NzOrientedBox::NzOrientedBox(const NzOrientedBox& orientedBox) } template -const NzVector3& NzOrientedBox::GetCorner(nzCorner corner) const +const NzVector3& NzOrientedBox::GetCorner(nzBoxCorner corner) const { #ifdef NAZARA_DEBUG - if (corner > nzCorner_Max) + if (corner > nzBoxCorner_Max) { NazaraError("Corner not handled (0x" + NzString::Number(corner, 16) + ')'); @@ -102,7 +102,7 @@ template template NzOrientedBox& NzOrientedBox::Set(const NzOrientedBox& orientedBox) { - for (unsigned int i = 0; i <= nzCorner_Max; ++i) + for (unsigned int i = 0; i <= nzBoxCorner_Max; ++i) m_corners[i].Set(orientedBox.m_corners[i]); localBox = orientedBox.localBox; @@ -115,21 +115,21 @@ NzString NzOrientedBox::ToString() const { NzStringStream ss; - return ss << "OrientedBox(FLB: " << m_corners[nzCorner_FarLeftBottom].ToString() << "\n" - << " FLT: " << m_corners[nzCorner_FarLeftTop].ToString() << "\n" - << " FRB: " << m_corners[nzCorner_FarRightBottom].ToString() << "\n" - << " FRT: " << m_corners[nzCorner_FarRightTop].ToString() << "\n" - << " NLB: " << m_corners[nzCorner_NearLeftBottom].ToString() << "\n" - << " NLT: " << m_corners[nzCorner_NearLeftTop].ToString() << "\n" - << " NRB: " << m_corners[nzCorner_NearRightBottom].ToString() << "\n" - << " NRT: " << m_corners[nzCorner_NearRightTop].ToString() << ")\n"; + return ss << "OrientedBox(FLB: " << m_corners[nzBoxCorner_FarLeftBottom].ToString() << "\n" + << " FLT: " << m_corners[nzBoxCorner_FarLeftTop].ToString() << "\n" + << " FRB: " << m_corners[nzBoxCorner_FarRightBottom].ToString() << "\n" + << " FRT: " << m_corners[nzBoxCorner_FarRightTop].ToString() << "\n" + << " NLB: " << m_corners[nzBoxCorner_NearLeftBottom].ToString() << "\n" + << " NLT: " << m_corners[nzBoxCorner_NearLeftTop].ToString() << "\n" + << " NRB: " << m_corners[nzBoxCorner_NearRightBottom].ToString() << "\n" + << " NRT: " << m_corners[nzBoxCorner_NearRightTop].ToString() << ")\n"; } template void NzOrientedBox::Update(const NzMatrix4& transformMatrix) { - for (unsigned int i = 0; i <= nzCorner_Max; ++i) - m_corners[i] = transformMatrix.Transform(localBox.GetCorner(static_cast(i))); + for (unsigned int i = 0; i <= nzBoxCorner_Max; ++i) + m_corners[i] = transformMatrix.Transform(localBox.GetCorner(static_cast(i))); } template @@ -148,7 +148,7 @@ template NzVector3& NzOrientedBox::operator()(unsigned int i) { #if NAZARA_MATH_SAFE - if (i > nzCorner_Max) + if (i > nzBoxCorner_Max) { NzStringStream ss; ss << "Index out of range: (" << i << " >= 3)"; @@ -165,7 +165,7 @@ template NzVector3 NzOrientedBox::operator()(unsigned int i) const { #if NAZARA_MATH_SAFE - if (i > nzCorner_Max) + if (i > nzBoxCorner_Max) { NzStringStream ss; ss << "Index out of range: (" << i << " >= 3)"; diff --git a/include/Nazara/Math/Ray.inl b/include/Nazara/Math/Ray.inl index ec4802bca..900ec2bbf 100644 --- a/include/Nazara/Math/Ray.inl +++ b/include/Nazara/Math/Ray.inl @@ -204,9 +204,9 @@ bool NzRay::Intersect(const NzBox& box, const NzMatrix4& transform, T* template bool NzRay::Intersect(const NzOrientedBox& orientedBox, T* closestHit, T* farthestHit) const { - NzVector3 width = (orientedBox.GetCorner(nzCorner_NearLeftBottom) - orientedBox.GetCorner(nzCorner_FarLeftBottom)).Normalize(); - NzVector3 height = (orientedBox.GetCorner(nzCorner_FarLeftTop) - orientedBox.GetCorner(nzCorner_FarLeftBottom)).Normalize(); - NzVector3 depth = (orientedBox.GetCorner(nzCorner_FarRightBottom) - orientedBox.GetCorner(nzCorner_FarLeftBottom)).Normalize(); + NzVector3 width = (orientedBox.GetCorner(nzBoxCorner_NearLeftBottom) - orientedBox.GetCorner(nzBoxCorner_FarLeftBottom)).Normalize(); + NzVector3 height = (orientedBox.GetCorner(nzBoxCorner_FarLeftTop) - orientedBox.GetCorner(nzBoxCorner_FarLeftBottom)).Normalize(); + NzVector3 depth = (orientedBox.GetCorner(nzBoxCorner_FarRightBottom) - orientedBox.GetCorner(nzBoxCorner_FarLeftBottom)).Normalize(); // Construction de la matrice de transformation de l'OBB NzMatrix4 matrix(width.x, height.x, depth.x, F(0.0), diff --git a/include/Nazara/Math/Rect.hpp b/include/Nazara/Math/Rect.hpp index a91c7b0e9..424d69079 100644 --- a/include/Nazara/Math/Rect.hpp +++ b/include/Nazara/Math/Rect.hpp @@ -8,6 +8,7 @@ #define NAZARA_RECT_HPP #include +#include #include template @@ -33,6 +34,7 @@ class NzRect NzRect& ExtendTo(const NzRect& rect); NzVector2 GetCenter() const; + NzVector2 GetCorner(nzRectCorner corner) const; NzVector2 GetLengths() const; NzVector2 GetMaximum() const; NzVector2 GetMinimum() const; diff --git a/include/Nazara/Math/Rect.inl b/include/Nazara/Math/Rect.inl index 3d1908b83..5cee6602d 100644 --- a/include/Nazara/Math/Rect.inl +++ b/include/Nazara/Math/Rect.inl @@ -109,6 +109,28 @@ NzVector2 NzRect::GetCenter() const return GetPosition() + GetLengths() / F(2.0); } +template +NzVector2 NzRect::GetCorner(nzRectCorner corner) const +{ + switch (corner) + { + case nzRectCorner_LeftBottom: + return NzVector2(x, y + height); + + case nzRectCorner_LeftTop: + return NzVector2(x, y); + + case nzRectCorner_RightBottom: + return NzVector2(x + width, y + height); + + case nzRectCorner_RightTop: + return NzVector2(x + width, y); + } + + NazaraError("Corner not handled (0x" + NzString::Number(corner, 16) + ')'); + return NzVector2(); +} + template NzVector2 NzRect::GetLengths() const { diff --git a/src/Nazara/Renderer/DebugDrawer.cpp b/src/Nazara/Renderer/DebugDrawer.cpp index 066566bc1..f0ee2e133 100644 --- a/src/Nazara/Renderer/DebugDrawer.cpp +++ b/src/Nazara/Renderer/DebugDrawer.cpp @@ -159,64 +159,64 @@ void NzDebugDrawer::Draw(const NzFrustumf& frustum) NzBufferMapper mapper(s_vertexBuffer, nzBufferAccess_DiscardAndWrite, 0, 24); NzVertexStruct_XYZ* vertex = reinterpret_cast(mapper.GetPointer()); - vertex->position.Set(frustum.GetCorner(nzCorner_NearLeftBottom)); + vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearLeftBottom)); vertex++; - vertex->position.Set(frustum.GetCorner(nzCorner_NearRightBottom)); + vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearRightBottom)); vertex++; - vertex->position.Set(frustum.GetCorner(nzCorner_NearLeftBottom)); + vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearLeftBottom)); vertex++; - vertex->position.Set(frustum.GetCorner(nzCorner_NearLeftTop)); + vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearLeftTop)); vertex++; - vertex->position.Set(frustum.GetCorner(nzCorner_NearLeftBottom)); + vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearLeftBottom)); vertex++; - vertex->position.Set(frustum.GetCorner(nzCorner_FarLeftBottom)); + vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarLeftBottom)); vertex++; - vertex->position.Set(frustum.GetCorner(nzCorner_FarRightTop)); + vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarRightTop)); vertex++; - vertex->position.Set(frustum.GetCorner(nzCorner_FarLeftTop)); + vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarLeftTop)); vertex++; - vertex->position.Set(frustum.GetCorner(nzCorner_FarRightTop)); + vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarRightTop)); vertex++; - vertex->position.Set(frustum.GetCorner(nzCorner_FarRightBottom)); + vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarRightBottom)); vertex++; - vertex->position.Set(frustum.GetCorner(nzCorner_FarRightTop)); + vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarRightTop)); vertex++; - vertex->position.Set(frustum.GetCorner(nzCorner_NearRightTop)); + vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearRightTop)); vertex++; - vertex->position.Set(frustum.GetCorner(nzCorner_FarLeftBottom)); + vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarLeftBottom)); vertex++; - vertex->position.Set(frustum.GetCorner(nzCorner_FarRightBottom)); + vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarRightBottom)); vertex++; - vertex->position.Set(frustum.GetCorner(nzCorner_FarLeftBottom)); + vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarLeftBottom)); vertex++; - vertex->position.Set(frustum.GetCorner(nzCorner_FarLeftTop)); + vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarLeftTop)); vertex++; - vertex->position.Set(frustum.GetCorner(nzCorner_NearLeftTop)); + vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearLeftTop)); vertex++; - vertex->position.Set(frustum.GetCorner(nzCorner_NearRightTop)); + vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearRightTop)); vertex++; - vertex->position.Set(frustum.GetCorner(nzCorner_NearLeftTop)); + vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearLeftTop)); vertex++; - vertex->position.Set(frustum.GetCorner(nzCorner_FarLeftTop)); + vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarLeftTop)); vertex++; - vertex->position.Set(frustum.GetCorner(nzCorner_NearRightBottom)); + vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearRightBottom)); vertex++; - vertex->position.Set(frustum.GetCorner(nzCorner_NearRightTop)); + vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearRightTop)); vertex++; - vertex->position.Set(frustum.GetCorner(nzCorner_NearRightBottom)); + vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearRightBottom)); vertex++; - vertex->position.Set(frustum.GetCorner(nzCorner_FarRightBottom)); + vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarRightBottom)); vertex++; mapper.Unmap(); @@ -241,64 +241,64 @@ void NzDebugDrawer::Draw(const NzOrientedBoxf& orientedBox) NzBufferMapper mapper(s_vertexBuffer, nzBufferAccess_DiscardAndWrite, 0, 24); NzVertexStruct_XYZ* vertex = reinterpret_cast(mapper.GetPointer()); - vertex->position.Set(orientedBox.GetCorner(nzCorner_NearLeftBottom)); + vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearLeftBottom)); vertex++; - vertex->position.Set(orientedBox.GetCorner(nzCorner_NearRightBottom)); + vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearRightBottom)); vertex++; - vertex->position.Set(orientedBox.GetCorner(nzCorner_NearLeftBottom)); + vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearLeftBottom)); vertex++; - vertex->position.Set(orientedBox.GetCorner(nzCorner_NearLeftTop)); + vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearLeftTop)); vertex++; - vertex->position.Set(orientedBox.GetCorner(nzCorner_NearLeftBottom)); + vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearLeftBottom)); vertex++; - vertex->position.Set(orientedBox.GetCorner(nzCorner_FarLeftBottom)); + vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarLeftBottom)); vertex++; - vertex->position.Set(orientedBox.GetCorner(nzCorner_FarRightTop)); + vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarRightTop)); vertex++; - vertex->position.Set(orientedBox.GetCorner(nzCorner_FarLeftTop)); + vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarLeftTop)); vertex++; - vertex->position.Set(orientedBox.GetCorner(nzCorner_FarRightTop)); + vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarRightTop)); vertex++; - vertex->position.Set(orientedBox.GetCorner(nzCorner_FarRightBottom)); + vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarRightBottom)); vertex++; - vertex->position.Set(orientedBox.GetCorner(nzCorner_FarRightTop)); + vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarRightTop)); vertex++; - vertex->position.Set(orientedBox.GetCorner(nzCorner_NearRightTop)); + vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearRightTop)); vertex++; - vertex->position.Set(orientedBox.GetCorner(nzCorner_FarLeftBottom)); + vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarLeftBottom)); vertex++; - vertex->position.Set(orientedBox.GetCorner(nzCorner_FarRightBottom)); + vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarRightBottom)); vertex++; - vertex->position.Set(orientedBox.GetCorner(nzCorner_FarLeftBottom)); + vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarLeftBottom)); vertex++; - vertex->position.Set(orientedBox.GetCorner(nzCorner_FarLeftTop)); + vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarLeftTop)); vertex++; - vertex->position.Set(orientedBox.GetCorner(nzCorner_NearLeftTop)); + vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearLeftTop)); vertex++; - vertex->position.Set(orientedBox.GetCorner(nzCorner_NearRightTop)); + vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearRightTop)); vertex++; - vertex->position.Set(orientedBox.GetCorner(nzCorner_NearLeftTop)); + vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearLeftTop)); vertex++; - vertex->position.Set(orientedBox.GetCorner(nzCorner_FarLeftTop)); + vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarLeftTop)); vertex++; - vertex->position.Set(orientedBox.GetCorner(nzCorner_NearRightBottom)); + vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearRightBottom)); vertex++; - vertex->position.Set(orientedBox.GetCorner(nzCorner_NearRightTop)); + vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearRightTop)); vertex++; - vertex->position.Set(orientedBox.GetCorner(nzCorner_NearRightBottom)); + vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearRightBottom)); vertex++; - vertex->position.Set(orientedBox.GetCorner(nzCorner_FarRightBottom)); + vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarRightBottom)); vertex++; mapper.Unmap(); From 596f407a7978a1e4da8c29f3bbcf8621e5cb7bf4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 3 Jan 2015 22:32:56 +0100 Subject: [PATCH 108/233] Added DebugDrawer::Draw(position, size) Draws a "size"-sized box centered on "position" Former-commit-id: 9385762a4118fe76364faa5819fd9a94efceefbf --- include/Nazara/Renderer/DebugDrawer.hpp | 1 + src/Nazara/Renderer/DebugDrawer.cpp | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/include/Nazara/Renderer/DebugDrawer.hpp b/include/Nazara/Renderer/DebugDrawer.hpp index fc632765a..1bb055c37 100644 --- a/include/Nazara/Renderer/DebugDrawer.hpp +++ b/include/Nazara/Renderer/DebugDrawer.hpp @@ -27,6 +27,7 @@ class NAZARA_API NzDebugDrawer static void Draw(const NzFrustumf& frustum); static void Draw(const NzOrientedBoxf& orientedBox); static void Draw(const NzSkeleton* skeleton); + static void Draw(const NzVector3f& position, float size = 0.1f); static void DrawBinormals(const NzStaticMesh* subMesh); static void DrawCone(const NzVector3f& origin, const NzQuaternionf& rotation, float angle, float length); static void DrawLine(const NzVector3f& p1, const NzVector3f& p2); diff --git a/src/Nazara/Renderer/DebugDrawer.cpp b/src/Nazara/Renderer/DebugDrawer.cpp index f0ee2e133..47c4388ef 100644 --- a/src/Nazara/Renderer/DebugDrawer.cpp +++ b/src/Nazara/Renderer/DebugDrawer.cpp @@ -363,6 +363,11 @@ void NzDebugDrawer::Draw(const NzSkeleton* skeleton) } } +void NzDebugDrawer::Draw(const NzVector3f& position, float size) +{ + Draw(NzBoxf(position.x - size*0.5f, position.y - size*0.5f, position.z - size*0.5f, size, size, size)); +} + void NzDebugDrawer::DrawBinormals(const NzStaticMesh* subMesh) { if (!Initialize()) From ed1cc7a0926970b9cfc11d5c37d0b8c385fc677f Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 3 Jan 2015 22:39:51 +0100 Subject: [PATCH 109/233] Added viewer-relative directions Former-commit-id: 9d80744bd227689426b76df7e3c273de13424041 --- include/Nazara/Graphics/AbstractViewer.hpp | 3 + include/Nazara/Graphics/Camera.hpp | 3 + include/Nazara/Graphics/Scene.hpp | 6 ++ include/Nazara/Graphics/SceneNode.hpp | 6 ++ include/Nazara/Graphics/View.hpp | 3 + include/Nazara/Utility/Node.hpp | 14 ++-- src/Nazara/Graphics/Camera.cpp | 15 ++++ src/Nazara/Graphics/Scene.cpp | 86 +++++++++++++++++++++- src/Nazara/Graphics/SceneNode.cpp | 79 ++++++++++++++++++++ src/Nazara/Graphics/View.cpp | 15 ++++ src/Nazara/Utility/Node.cpp | 2 +- 11 files changed, 223 insertions(+), 9 deletions(-) diff --git a/include/Nazara/Graphics/AbstractViewer.hpp b/include/Nazara/Graphics/AbstractViewer.hpp index 7e0306689..d6c3d5f3f 100644 --- a/include/Nazara/Graphics/AbstractViewer.hpp +++ b/include/Nazara/Graphics/AbstractViewer.hpp @@ -28,6 +28,9 @@ class NAZARA_API NzAbstractViewer virtual NzVector3f GetEyePosition() const = 0; virtual NzVector3f GetForward() const = 0; virtual const NzFrustumf& GetFrustum() const = 0; + virtual NzVector3f GetGlobalForward() const = 0; + virtual NzVector3f GetGlobalRight() const = 0; + virtual NzVector3f GetGlobalUp() const = 0; virtual const NzMatrix4f& GetProjectionMatrix() const = 0; virtual const NzRenderTarget* GetTarget() const = 0; virtual const NzMatrix4f& GetViewMatrix() const = 0; diff --git a/include/Nazara/Graphics/Camera.hpp b/include/Nazara/Graphics/Camera.hpp index 534f48df7..3cdb0eb41 100644 --- a/include/Nazara/Graphics/Camera.hpp +++ b/include/Nazara/Graphics/Camera.hpp @@ -32,6 +32,9 @@ class NAZARA_API NzCamera : public NzAbstractViewer, public NzNode, NzRenderTarg NzVector3f GetForward() const; float GetFOV() const; const NzFrustumf& GetFrustum() const; + NzVector3f GetGlobalForward() const; + NzVector3f GetGlobalRight() const; + NzVector3f GetGlobalUp() const; const NzMatrix4f& GetProjectionMatrix() const; const NzRenderTarget* GetTarget() const; const NzRectf& GetTargetRegion() const; diff --git a/include/Nazara/Graphics/Scene.hpp b/include/Nazara/Graphics/Scene.hpp index d286c4c19..8a9b1b89c 100644 --- a/include/Nazara/Graphics/Scene.hpp +++ b/include/Nazara/Graphics/Scene.hpp @@ -41,9 +41,15 @@ class NAZARA_API NzScene NzColor GetAmbientColor() const; NzAbstractBackground* GetBackground() const; + NzVector3f GetBackward() const; + NzVector3f GetDown() const; + NzVector3f GetForward() const; + NzVector3f GetLeft() const; NzAbstractRenderTechnique* GetRenderTechnique() const; + NzVector3f GetRight() const; NzSceneNode& GetRoot() const; NzAbstractViewer* GetViewer() const; + NzVector3f GetUp() const; float GetUpdateTime() const; unsigned int GetUpdatePerSecond() const; diff --git a/include/Nazara/Graphics/SceneNode.hpp b/include/Nazara/Graphics/SceneNode.hpp index 09aa1fab3..e5d70d10c 100644 --- a/include/Nazara/Graphics/SceneNode.hpp +++ b/include/Nazara/Graphics/SceneNode.hpp @@ -27,10 +27,16 @@ class NAZARA_API NzSceneNode : public NzNode void EnableDrawing(bool drawingEnabled); + NzVector3f GetBackward() const; virtual const NzBoundingVolumef& GetBoundingVolume() const = 0; + NzVector3f GetDown() const; + NzVector3f GetForward() const; + NzVector3f GetLeft() const; nzNodeType GetNodeType() const final; + NzVector3f GetRight() const; NzScene* GetScene() const; virtual nzSceneNodeType GetSceneNodeType() const = 0; + NzVector3f GetUp() const; virtual bool IsDrawable() const = 0; bool IsDrawingEnabled() const; diff --git a/include/Nazara/Graphics/View.hpp b/include/Nazara/Graphics/View.hpp index bc048aeb6..e9d0de8da 100644 --- a/include/Nazara/Graphics/View.hpp +++ b/include/Nazara/Graphics/View.hpp @@ -32,6 +32,9 @@ class NAZARA_API NzView : public NzAbstractViewer, public NzNode, NzRenderTarget NzVector3f GetEyePosition() const; NzVector3f GetForward() const; const NzFrustumf& GetFrustum() const; + NzVector3f GetGlobalForward() const; + NzVector3f GetGlobalRight() const; + NzVector3f GetGlobalUp() const; const NzMatrix4f& GetProjectionMatrix() const; const NzVector2f& GetSize() const; const NzRenderTarget* GetTarget() const; diff --git a/include/Nazara/Utility/Node.hpp b/include/Nazara/Utility/Node.hpp index 4536739a7..11f9d1f15 100644 --- a/include/Nazara/Utility/Node.hpp +++ b/include/Nazara/Utility/Node.hpp @@ -24,26 +24,26 @@ class NAZARA_API NzNode void EnsureDerivedUpdate() const; void EnsureTransformMatrixUpdate() const; - NzVector3f GetBackward() const; + virtual NzVector3f GetBackward() const; const std::vector& GetChilds() const; - NzVector3f GetDown() const; - NzVector3f GetForward() const; + virtual NzVector3f GetDown() const; + virtual NzVector3f GetForward() const; bool GetInheritPosition() const; bool GetInheritRotation() const; bool GetInheritScale() const; NzVector3f GetInitialPosition() const; NzQuaternionf GetInitialRotation() const; NzVector3f GetInitialScale() const; - NzVector3f GetLeft() const; + virtual NzVector3f GetLeft() const; const NzString& GetName() const; virtual nzNodeType GetNodeType() const; const NzNode* GetParent() const; NzVector3f GetPosition(nzCoordSys coordSys = nzCoordSys_Global) const; - NzVector3f GetRight() const; + virtual NzVector3f GetRight() const; NzQuaternionf GetRotation(nzCoordSys coordSys = nzCoordSys_Global) const; NzVector3f GetScale(nzCoordSys coordSys = nzCoordSys_Global) const; const NzMatrix4f& GetTransformMatrix() const; - NzVector3f GetUp() const; + virtual NzVector3f GetUp() const; bool HasChilds() const; @@ -95,7 +95,7 @@ class NAZARA_API NzNode virtual void InvalidateNode(); virtual void OnParenting(const NzNode* parent); void RemoveChild(NzNode* node) const; - void UpdateDerived() const; + virtual void UpdateDerived() const; virtual void UpdateTransformMatrix() const; mutable std::vector m_childs; diff --git a/src/Nazara/Graphics/Camera.cpp b/src/Nazara/Graphics/Camera.cpp index a0eb272a6..570b1f289 100644 --- a/src/Nazara/Graphics/Camera.cpp +++ b/src/Nazara/Graphics/Camera.cpp @@ -80,6 +80,21 @@ const NzFrustumf& NzCamera::GetFrustum() const return m_frustum; } +NzVector3f NzCamera::GetGlobalForward() const +{ + return NzVector3f::Forward(); +} + +NzVector3f NzCamera::GetGlobalRight() const +{ + return NzVector3f::Right(); +} + +NzVector3f NzCamera::GetGlobalUp() const +{ + return NzVector3f::Up(); +} + const NzMatrix4f& NzCamera::GetProjectionMatrix() const { if (!m_projectionMatrixUpdated) diff --git a/src/Nazara/Graphics/Scene.cpp b/src/Nazara/Graphics/Scene.cpp index 2c9f286a8..e66a99f03 100644 --- a/src/Nazara/Graphics/Scene.cpp +++ b/src/Nazara/Graphics/Scene.cpp @@ -134,6 +134,58 @@ NzAbstractBackground* NzScene::GetBackground() const return m_impl->background.get(); } +NzVector3f NzScene::GetBackward() const +{ + #if NAZARA_GRAPHICS_SAFE + if (!m_impl->viewer) + { + NazaraError("No viewer"); + return NzVector3f::Backward(); + } + #endif + + return -m_impl->viewer->GetGlobalForward(); +} + +NzVector3f NzScene::GetDown() const +{ + #if NAZARA_GRAPHICS_SAFE + if (!m_impl->viewer) + { + NazaraError("No viewer"); + return NzVector3f::Down(); + } + #endif + + return -m_impl->viewer->GetGlobalUp(); +} + +NzVector3f NzScene::GetForward() const +{ + #if NAZARA_GRAPHICS_SAFE + if (!m_impl->viewer) + { + NazaraError("No viewer"); + return NzVector3f::Forward(); + } + #endif + + return m_impl->viewer->GetGlobalForward(); +} + +NzVector3f NzScene::GetLeft() const +{ + #if NAZARA_GRAPHICS_SAFE + if (!m_impl->viewer) + { + NazaraError("No viewer"); + return NzVector3f::Left(); + } + #endif + + return -m_impl->viewer->GetGlobalRight(); +} + NzAbstractRenderTechnique* NzScene::GetRenderTechnique() const { if (!m_impl->renderTechnique) @@ -142,6 +194,19 @@ NzAbstractRenderTechnique* NzScene::GetRenderTechnique() const return m_impl->renderTechnique.get(); } +NzVector3f NzScene::GetRight() const +{ + #if NAZARA_GRAPHICS_SAFE + if (!m_impl->viewer) + { + NazaraError("No viewer"); + return NzVector3f::Right(); + } + #endif + + return m_impl->viewer->GetGlobalRight(); +} + NzSceneNode& NzScene::GetRoot() const { return m_impl->root; @@ -152,6 +217,19 @@ NzAbstractViewer* NzScene::GetViewer() const return m_impl->viewer; } +NzVector3f NzScene::GetUp() const +{ + #if NAZARA_GRAPHICS_SAFE + if (!m_impl->viewer) + { + NazaraError("No viewer"); + return NzVector3f::Up(); + } + #endif + + return m_impl->viewer->GetGlobalUp(); +} + float NzScene::GetUpdateTime() const { return m_impl->updateTime; @@ -197,7 +275,13 @@ void NzScene::SetRenderTechnique(NzAbstractRenderTechnique* renderTechnique) void NzScene::SetViewer(NzAbstractViewer* viewer) { - m_impl->viewer = viewer; + if (m_impl->viewer != viewer) + { + m_impl->viewer = viewer; + + // Invalidation de tous les nodes de la scène (utile pour la régénération des sommets dépendant du viewer) + m_impl->root.InvalidateNode(); + } } void NzScene::SetViewer(NzAbstractViewer& viewer) diff --git a/src/Nazara/Graphics/SceneNode.cpp b/src/Nazara/Graphics/SceneNode.cpp index fbd88b866..fcaf02743 100644 --- a/src/Nazara/Graphics/SceneNode.cpp +++ b/src/Nazara/Graphics/SceneNode.cpp @@ -31,16 +31,94 @@ void NzSceneNode::EnableDrawing(bool drawingEnabled) m_drawingEnabled = drawingEnabled; } +NzVector3f NzSceneNode::GetBackward() const +{ + if (m_scene) + { + if (!m_derivedUpdated) + UpdateDerived(); + + return m_derivedRotation * m_scene->GetBackward(); + } + else + return NzNode::GetBackward(); +} + +NzVector3f NzSceneNode::GetDown() const +{ + if (m_scene) + { + if (!m_derivedUpdated) + UpdateDerived(); + + return m_derivedRotation * m_scene->GetDown(); + } + else + return NzNode::GetDown(); +} + +NzVector3f NzSceneNode::GetForward() const +{ + if (m_scene) + { + if (!m_derivedUpdated) + UpdateDerived(); + + return m_derivedRotation * m_scene->GetForward(); + } + else + return NzNode::GetForward(); +} + +NzVector3f NzSceneNode::GetLeft() const +{ + if (m_scene) + { + if (!m_derivedUpdated) + UpdateDerived(); + + return m_derivedRotation * m_scene->GetLeft(); + } + else + return NzNode::GetLeft(); +} + nzNodeType NzSceneNode::GetNodeType() const { return nzNodeType_Scene; } +NzVector3f NzSceneNode::GetRight() const +{ + if (m_scene) + { + if (!m_derivedUpdated) + UpdateDerived(); + + return m_derivedRotation * m_scene->GetRight(); + } + else + return NzNode::GetRight(); +} + NzScene* NzSceneNode::GetScene() const { return m_scene; } +NzVector3f NzSceneNode::GetUp() const +{ + if (m_scene) + { + if (!m_derivedUpdated) + UpdateDerived(); + + return m_derivedRotation * m_scene->GetUp(); + } + else + return NzNode::GetUp(); +} + bool NzSceneNode::IsDrawingEnabled() const { return m_drawingEnabled; @@ -82,6 +160,7 @@ void NzSceneNode::OnParenting(const NzNode* parent) { if (parent) { + ///FIXME: Remonter jusqu'au premier parent de type SceneNode plutôt que de s'arrêter au premier venu if (parent->GetNodeType() == nzNodeType_Scene) SetScene(static_cast(parent)->m_scene); } diff --git a/src/Nazara/Graphics/View.cpp b/src/Nazara/Graphics/View.cpp index 44d00294c..045b22a22 100644 --- a/src/Nazara/Graphics/View.cpp +++ b/src/Nazara/Graphics/View.cpp @@ -80,6 +80,21 @@ const NzFrustumf& NzView::GetFrustum() const return m_frustum; } +NzVector3f NzView::GetGlobalForward() const +{ + return NzVector3f::UnitZ(); +} + +NzVector3f NzView::GetGlobalRight() const +{ + return NzVector3f::UnitX(); +} + +NzVector3f NzView::GetGlobalUp() const +{ + return -NzVector3f::UnitY(); +} + const NzMatrix4f& NzView::GetProjectionMatrix() const { if (!m_projectionMatrixUpdated) diff --git a/src/Nazara/Utility/Node.cpp b/src/Nazara/Utility/Node.cpp index 459f6d74f..6361ea3de 100644 --- a/src/Nazara/Utility/Node.cpp +++ b/src/Nazara/Utility/Node.cpp @@ -685,7 +685,7 @@ void NzNode::UpdateDerived() const m_derivedRotation.Normalize(); } else - m_derivedRotation = m_initialRotation * m_rotation; ///FIXME: Besoin d'une normalisation ? + m_derivedRotation = m_initialRotation * m_rotation; m_derivedScale = m_initialScale * m_scale; if (m_inheritScale) From 97ff9bc4ace9b187cab70eb75e32480b563c67f9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 4 Jan 2015 12:50:56 +0100 Subject: [PATCH 110/233] Improved texture creation Fixed possible wasted space on NVidia hardware Former-commit-id: 42a26c88d8bd03b1ac845c62984cf8c355f1902a --- include/Nazara/Renderer/Texture.hpp | 1 + src/Nazara/Renderer/Texture.cpp | 279 ++++++++++++++-------------- 2 files changed, 143 insertions(+), 137 deletions(-) diff --git a/include/Nazara/Renderer/Texture.hpp b/include/Nazara/Renderer/Texture.hpp index 024216d70..f78feb490 100644 --- a/include/Nazara/Renderer/Texture.hpp +++ b/include/Nazara/Renderer/Texture.hpp @@ -101,6 +101,7 @@ class NAZARA_API NzTexture : public NzResource, NzNonCopyable static bool IsTypeSupported(nzImageType type); private: + bool CreateTexture(bool proxy); void InvalidateMipmaps(); NzTextureImpl* m_impl = nullptr; diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index 6e73cc545..9605244c4 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include #include @@ -28,123 +29,6 @@ struct NzTextureImpl namespace { - bool CreateTexture(NzTextureImpl* impl, bool proxy) - { - NzOpenGL::Format openGLFormat; - if (!NzOpenGL::TranslateFormat(impl->format, &openGLFormat, NzOpenGL::FormatType_Texture)) - { - NazaraError("Format " + NzPixelFormat::ToString(impl->format) + " not supported by OpenGL"); - return false; - } - - GLenum target = (proxy) ? NzOpenGL::TextureTargetProxy[impl->type] : NzOpenGL::TextureTarget[impl->type]; - switch (impl->type) - { - case nzImageType_1D: - { - if (glTexStorage1D && !proxy) // Les drivers AMD semblent ne pas aimer glTexStorage avec un format proxy - glTexStorage1D(target, impl->levelCount, openGLFormat.internalFormat, impl->width); - else - { - unsigned int w = impl->width; - for (nzUInt8 level = 0; level < impl->levelCount; ++level) - { - glTexImage1D(target, level, openGLFormat.internalFormat, w, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr); - if (w > 1U) - w >>= 1; - } - } - break; - } - - case nzImageType_1D_Array: - case nzImageType_2D: - { - if (glTexStorage2D && !proxy) - glTexStorage2D(target, impl->levelCount, openGLFormat.internalFormat, impl->width, impl->height); - else - { - unsigned int w = impl->width; - unsigned int h = impl->height; - for (nzUInt8 level = 0; level < impl->levelCount; ++level) - { - glTexImage2D(target, level, openGLFormat.internalFormat, w, h, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr); - if (w > 1U) - w >>= 1; - - if (h > 1U) - h >>= 1; - } - } - break; - } - - case nzImageType_2D_Array: - case nzImageType_3D: - { - if (glTexStorage3D && !proxy) - glTexStorage3D(target, impl->levelCount, openGLFormat.internalFormat, impl->width, impl->height, impl->depth); - else - { - unsigned int w = impl->width; - unsigned int h = impl->height; - unsigned int d = impl->depth; - for (nzUInt8 level = 0; level < impl->levelCount; ++level) - { - glTexImage3D(target, level, openGLFormat.internalFormat, w, h, d, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr); - if (w > 1U) - w >>= 1; - - if (h > 1U) - h >>= 1; - - if (d > 1U) - d >>= 1; - } - } - break; - } - - case nzImageType_Cubemap: - { - if (glTexStorage2D && !proxy) - glTexStorage2D(target, impl->levelCount, openGLFormat.internalFormat, impl->width, impl->height); - else - { - unsigned int size = impl->width; // Les cubemaps ont une longueur et largeur identique - for (nzUInt8 level = 0; level < impl->levelCount; ++level) - { - for (GLenum face : NzOpenGL::CubemapFace) - glTexImage2D(face, level, openGLFormat.internalFormat, size, size, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr); - - if (size > 1U) - size >>= 1; - } - } - break; - } - } - - if (proxy) - { - GLint internalFormat = 0; - glGetTexLevelParameteriv(target, 0, GL_TEXTURE_INTERNAL_FORMAT, &internalFormat); - if (internalFormat == 0) - return false; - } - - // Application du swizzle - if (NzOpenGL::GetVersion() >= 300) - { - glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, openGLFormat.swizzle[0]); - glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, openGLFormat.swizzle[1]); - glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, openGLFormat.swizzle[2]); - glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, openGLFormat.swizzle[3]); - } - - return true; - } - inline void SetUnpackAlignement(nzUInt8 bpp) { if (bpp % 8 == 0) @@ -273,40 +157,44 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt levelCount = 1; } - std::unique_ptr impl(new NzTextureImpl); - glGenTextures(1, &impl->id); + m_impl = new NzTextureImpl; + m_impl->depth = GetValidSize(depth); + m_impl->format = format; + m_impl->height = GetValidSize(height); + m_impl->levelCount = levelCount; + m_impl->type = type; + m_impl->width = GetValidSize(width); - impl->depth = GetValidSize(depth); - impl->format = format; - impl->height = GetValidSize(height); - impl->levelCount = levelCount; - impl->type = type; - impl->width = GetValidSize(width); + glGenTextures(1, &m_impl->id); + NzOpenGL::BindTexture(m_impl->type, m_impl->id); - NzOpenGL::BindTexture(impl->type, impl->id); - - // Vérification du support par la carte graphique - if (!CreateTexture(impl.get(), true)) + // En cas d'erreur (sortie prématurée), on détruit la texture + NzCallOnExit onExit([this]() { - NzOpenGL::DeleteTexture(m_impl->id); + Destroy(); + }); + // On précise le nombre de mipmaps avant la spécification de la texture + // https://www.opengl.org/wiki/Hardware_specifics:_NVidia + SetMipmapRange(0, m_impl->levelCount-1); + if (m_impl->levelCount > 1U) + EnableMipmapping(true); + + // Vérification du support par la carte graphique (texture proxy) + if (!CreateTexture(true)) + { NazaraError("Texture's parameters not supported by driver"); return false; } // Création de la texture - if (!CreateTexture(impl.get(), false)) + if (!CreateTexture(false)) { - NzOpenGL::DeleteTexture(m_impl->id); - NazaraError("Failed to create texture"); return false; } - m_impl = impl.release(); - - if (m_impl->levelCount > 1U) - EnableMipmapping(true); + onExit.Reset(); NotifyCreated(); return true; @@ -1336,6 +1224,123 @@ bool NzTexture::IsTypeSupported(nzImageType type) return false; } +bool NzTexture::CreateTexture(bool proxy) +{ + NzOpenGL::Format openGLFormat; + if (!NzOpenGL::TranslateFormat(m_impl->format, &openGLFormat, NzOpenGL::FormatType_Texture)) + { + NazaraError("Format " + NzPixelFormat::ToString(m_impl->format) + " not supported by OpenGL"); + return false; + } + + GLenum target = (proxy) ? NzOpenGL::TextureTargetProxy[m_impl->type] : NzOpenGL::TextureTarget[m_impl->type]; + switch (m_impl->type) + { + case nzImageType_1D: + { + if (glTexStorage1D && !proxy) // Les drivers AMD semblent ne pas aimer glTexStorage avec un format proxy + glTexStorage1D(target, m_impl->levelCount, openGLFormat.internalFormat, m_impl->width); + else + { + unsigned int w = m_impl->width; + for (nzUInt8 level = 0; level < m_impl->levelCount; ++level) + { + glTexImage1D(target, level, openGLFormat.internalFormat, w, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr); + if (w > 1U) + w >>= 1; + } + } + break; + } + + case nzImageType_1D_Array: + case nzImageType_2D: + { + if (glTexStorage2D && !proxy) + glTexStorage2D(target, m_impl->levelCount, openGLFormat.internalFormat, m_impl->width, m_impl->height); + else + { + unsigned int w = m_impl->width; + unsigned int h = m_impl->height; + for (nzUInt8 level = 0; level < m_impl->levelCount; ++level) + { + glTexImage2D(target, level, openGLFormat.internalFormat, w, h, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr); + if (w > 1U) + w >>= 1; + + if (h > 1U) + h >>= 1; + } + } + break; + } + + case nzImageType_2D_Array: + case nzImageType_3D: + { + if (glTexStorage3D && !proxy) + glTexStorage3D(target, m_impl->levelCount, openGLFormat.internalFormat, m_impl->width, m_impl->height, m_impl->depth); + else + { + unsigned int w = m_impl->width; + unsigned int h = m_impl->height; + unsigned int d = m_impl->depth; + for (nzUInt8 level = 0; level < m_impl->levelCount; ++level) + { + glTexImage3D(target, level, openGLFormat.internalFormat, w, h, d, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr); + if (w > 1U) + w >>= 1; + + if (h > 1U) + h >>= 1; + + if (d > 1U) + d >>= 1; + } + } + break; + } + + case nzImageType_Cubemap: + { + if (glTexStorage2D && !proxy) + glTexStorage2D(target, m_impl->levelCount, openGLFormat.internalFormat, m_impl->width, m_impl->height); + else + { + unsigned int size = m_impl->width; // Les cubemaps ont une longueur et largeur identique + for (nzUInt8 level = 0; level < m_impl->levelCount; ++level) + { + for (GLenum face : NzOpenGL::CubemapFace) + glTexImage2D(face, level, openGLFormat.internalFormat, size, size, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr); + + if (size > 1U) + size >>= 1; + } + } + break; + } + } + + if (proxy) + { + GLint internalFormat = 0; + glGetTexLevelParameteriv(target, 0, GL_TEXTURE_INTERNAL_FORMAT, &internalFormat); + if (internalFormat == 0) + return false; + } + + // Application du swizzle + if (!proxy && NzOpenGL::GetVersion() >= 300) + { + glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, openGLFormat.swizzle[0]); + glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, openGLFormat.swizzle[1]); + glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, openGLFormat.swizzle[2]); + glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, openGLFormat.swizzle[3]); + } + + return true; +} + void NzTexture::InvalidateMipmaps() { #if NAZARA_RENDERER_SAFE From e69c2982b9e75915abe979a57b720dbdda1a8dfb Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 4 Jan 2015 13:08:26 +0100 Subject: [PATCH 111/233] Minor changes Former-commit-id: 1282e3600c687647f637aec42f05d033266e1d33 --- include/Nazara/Core/HashDigest.hpp | 2 +- src/Nazara/Audio/Loaders/sndfile/Loader.cpp | 2 +- src/Nazara/Core/Hash/SHA/Internal.cpp | 8 -------- src/Nazara/Renderer/UberShaderPreprocessor.cpp | 16 ++++++---------- 4 files changed, 8 insertions(+), 20 deletions(-) diff --git a/include/Nazara/Core/HashDigest.hpp b/include/Nazara/Core/HashDigest.hpp index da4afb227..8f61dd2f4 100644 --- a/include/Nazara/Core/HashDigest.hpp +++ b/include/Nazara/Core/HashDigest.hpp @@ -11,7 +11,7 @@ #include #include -#include +#include class NAZARA_API NzHashDigest { diff --git a/src/Nazara/Audio/Loaders/sndfile/Loader.cpp b/src/Nazara/Audio/Loaders/sndfile/Loader.cpp index 62a1268ab..d60d4e2de 100644 --- a/src/Nazara/Audio/Loaders/sndfile/Loader.cpp +++ b/src/Nazara/Audio/Loaders/sndfile/Loader.cpp @@ -61,7 +61,7 @@ namespace sf_count_t Tell(void* user_data) { - NzInputStream* stream = reinterpret_cast(user_data); + NzInputStream* stream = static_cast(user_data); return stream->GetCursorPos(); } diff --git a/src/Nazara/Core/Hash/SHA/Internal.cpp b/src/Nazara/Core/Hash/SHA/Internal.cpp index 9ea5069cb..d011ddbe3 100644 --- a/src/Nazara/Core/Hash/SHA/Internal.cpp +++ b/src/Nazara/Core/Hash/SHA/Internal.cpp @@ -770,14 +770,6 @@ void SHA224_Init(SHA_CTX* context) SHA256_Internal_Init(context, sha224_initial_hash_value); } -namespace -{ - void SHA224_Internal_Transform(SHA_CTX* context, const nzUInt32* data) - { - SHA256_Internal_Transform(context, data); - } -} - void SHA224_Update(SHA_CTX* context, const nzUInt8 *data, std::size_t len) { SHA256_Update(context, data, len); diff --git a/src/Nazara/Renderer/UberShaderPreprocessor.cpp b/src/Nazara/Renderer/UberShaderPreprocessor.cpp index 5dd74bc32..22790bbc4 100644 --- a/src/Nazara/Renderer/UberShaderPreprocessor.cpp +++ b/src/Nazara/Renderer/UberShaderPreprocessor.cpp @@ -81,22 +81,18 @@ NzUberShaderInstance* NzUberShaderPreprocessor::Get(const NzParameterList& param stage.SetSource(code); stage.Compile(); - shader->AttachStage(static_cast(i), stage); - - shaderStage.cache.emplace(flags, std::move(stage)); + stageIt = shaderStage.cache.emplace(flags, std::move(stage)).first; } - else - shader->AttachStage(static_cast(i), stageIt->second); + + shader->AttachStage(static_cast(i), stageIt->second); } } shader->Link(); // On construit l'instant - auto pair = m_cache.emplace(flags, shader.get()); + shaderIt = m_cache.emplace(flags, shader.get()).first; shader.release(); - - return &(pair.first)->second; // On retourne l'objet construit } catch (const std::exception& e) { @@ -106,8 +102,8 @@ NzUberShaderInstance* NzUberShaderPreprocessor::Get(const NzParameterList& param throw; } } - else - return &shaderIt->second; + + return &shaderIt->second; } void NzUberShaderPreprocessor::SetShader(nzShaderStage stage, const NzString& source, const NzString& shaderFlags, const NzString& requiredFlags) From 4de17fdffb27608f4740e0c70d06535f7a4eb421 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 4 Jan 2015 13:19:07 +0100 Subject: [PATCH 112/233] Remade sprite rendering Added VertexColor shader flag Added color sprite attribute Added VertexStruct_XY_Color(_UV) struct & declaration Former-commit-id: b664f4520aa55f4502f85f9dedab9b92040a8c16 --- .../Nazara/Graphics/AbstractRenderQueue.hpp | 3 +- .../Nazara/Graphics/DeferredRenderQueue.hpp | 2 +- include/Nazara/Graphics/Enums.hpp | 7 +- .../Nazara/Graphics/ForwardRenderQueue.hpp | 12 +- .../Graphics/ForwardRenderTechnique.hpp | 2 +- include/Nazara/Graphics/Sprite.hpp | 7 + include/Nazara/Utility/Enums.hpp | 2 + include/Nazara/Utility/VertexStruct.hpp | 25 ++- src/Nazara/Graphics/DeferredRenderQueue.cpp | 18 +- src/Nazara/Graphics/ForwardRenderQueue.cpp | 43 +++-- .../Graphics/ForwardRenderTechnique.cpp | 157 +++++++++--------- src/Nazara/Graphics/Material.cpp | 5 +- .../Resources/Shaders/Basic/core.frag | 3 +- .../Resources/Shaders/Basic/core.frag.h | 2 +- .../Resources/Shaders/Basic/core.vert | 9 + .../Resources/Shaders/Basic/core.vert.h | 2 +- .../Resources/Shaders/PhongLighting/core.frag | 3 +- .../Shaders/PhongLighting/core.frag.h | 2 +- .../Resources/Shaders/PhongLighting/core.vert | 10 ++ .../Shaders/PhongLighting/core.vert.h | 2 +- src/Nazara/Graphics/Sprite.cpp | 78 ++++++++- src/Nazara/Utility/VertexDeclaration.cpp | 15 ++ 22 files changed, 264 insertions(+), 145 deletions(-) diff --git a/include/Nazara/Graphics/AbstractRenderQueue.hpp b/include/Nazara/Graphics/AbstractRenderQueue.hpp index c3a9de2e4..5159a8fce 100644 --- a/include/Nazara/Graphics/AbstractRenderQueue.hpp +++ b/include/Nazara/Graphics/AbstractRenderQueue.hpp @@ -12,6 +12,7 @@ #include #include #include +#include class NzDrawable; class NzLight; @@ -28,7 +29,7 @@ class NAZARA_API NzAbstractRenderQueue : NzNonCopyable virtual void AddDrawable(const NzDrawable* drawable) = 0; virtual void AddLight(const NzLight* light) = 0; virtual void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) = 0; - virtual void AddSprite(const NzSprite* sprite) = 0; + virtual void AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount) = 0; virtual void Clear(bool fully) = 0; }; diff --git a/include/Nazara/Graphics/DeferredRenderQueue.hpp b/include/Nazara/Graphics/DeferredRenderQueue.hpp index 8cec0ecea..8020dffd7 100644 --- a/include/Nazara/Graphics/DeferredRenderQueue.hpp +++ b/include/Nazara/Graphics/DeferredRenderQueue.hpp @@ -31,7 +31,7 @@ class NAZARA_API NzDeferredRenderQueue : public NzAbstractRenderQueue, NzResourc void AddDrawable(const NzDrawable* drawable) override; void AddLight(const NzLight* light) override; void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) override; - void AddSprite(const NzSprite* sprite) override; + void AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount) override; void Clear(bool fully); diff --git a/include/Nazara/Graphics/Enums.hpp b/include/Nazara/Graphics/Enums.hpp index 59a8104c4..60b05238d 100644 --- a/include/Nazara/Graphics/Enums.hpp +++ b/include/Nazara/Graphics/Enums.hpp @@ -85,10 +85,11 @@ enum nzShaderFlags { nzShaderFlags_None = 0, - nzShaderFlags_Deferred = 0x1, - nzShaderFlags_Instancing = 0x2, + nzShaderFlags_Deferred = 0x1, + nzShaderFlags_Instancing = 0x2, + nzShaderFlags_VertexColor = 0x4, - nzShaderFlags_Max = nzShaderFlags_Instancing*2-1 + nzShaderFlags_Max = nzShaderFlags_VertexColor*2-1 }; #endif // NAZARA_ENUMS_GRAPHICS_HPP diff --git a/include/Nazara/Graphics/ForwardRenderQueue.hpp b/include/Nazara/Graphics/ForwardRenderQueue.hpp index 85710cd0d..e7c7c3087 100644 --- a/include/Nazara/Graphics/ForwardRenderQueue.hpp +++ b/include/Nazara/Graphics/ForwardRenderQueue.hpp @@ -33,7 +33,7 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResource void AddDrawable(const NzDrawable* drawable) override; void AddLight(const NzLight* light) override; void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) override; - void AddSprite(const NzSprite* sprite) override; + void AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount) override; void Clear(bool fully); @@ -43,6 +43,12 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResource bool OnResourceDestroy(const NzResource* resource, int index) override; void OnResourceReleased(const NzResource* resource, int index) override; + struct SpriteChain_XYZ_Color_UV + { + const NzVertexStruct_XYZ_Color_UV* vertices; + unsigned int spriteCount; + }; + struct TransparentModelData { NzMatrix4f transformMatrix; @@ -68,12 +74,12 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResource typedef std::map>, MeshDataComparator> MeshInstanceContainer; typedef std::map, BatchedModelMaterialComparator> ModelBatches; - typedef std::map> BatchedSpriteContainer; + typedef std::map> BasicSpriteBatches; typedef std::vector LightContainer; typedef std::vector TransparentModelContainer; + BasicSpriteBatches basicSprites; ModelBatches opaqueModels; - BatchedSpriteContainer sprites; TransparentModelContainer transparentModels; std::vector transparentModelData; std::vector otherDrawables; diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.hpp b/include/Nazara/Graphics/ForwardRenderTechnique.hpp index 9050cda20..18caea522 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.hpp +++ b/include/Nazara/Graphics/ForwardRenderTechnique.hpp @@ -34,8 +34,8 @@ class NAZARA_API NzForwardRenderTechnique : public NzAbstractRenderTechnique, Nz private: struct LightUniforms; + void DrawBasicSprites(const NzScene* scene) const; void DrawOpaqueModels(const NzScene* scene) const; - void DrawSprites(const NzScene* scene) const; void DrawTransparentModels(const NzScene* scene) const; const LightUniforms* GetLightUniforms(const NzShader* shader) const; diff --git a/include/Nazara/Graphics/Sprite.hpp b/include/Nazara/Graphics/Sprite.hpp index b383f1e44..a6040823c 100644 --- a/include/Nazara/Graphics/Sprite.hpp +++ b/include/Nazara/Graphics/Sprite.hpp @@ -10,6 +10,7 @@ #include #include #include +#include class NAZARA_API NzSprite : public NzSceneNode { @@ -23,6 +24,7 @@ class NAZARA_API NzSprite : public NzSceneNode void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; const NzBoundingVolumef& GetBoundingVolume() const override; + const NzColor& GetColor() const; NzMaterial* GetMaterial() const; nzSceneNodeType GetSceneNodeType() const override; const NzVector2f& GetSize() const; @@ -30,6 +32,7 @@ class NAZARA_API NzSprite : public NzSceneNode bool IsDrawable() const; + void SetColor(const NzColor& color); void SetMaterial(NzMaterial* material, bool resizeSprite = true); void SetSize(const NzVector2f& size); void SetSize(float sizeX, float sizeY); @@ -42,12 +45,16 @@ class NAZARA_API NzSprite : public NzSceneNode void Register() override; void Unregister() override; void UpdateBoundingVolume() const; + void UpdateVertices() const; mutable NzBoundingVolumef m_boundingVolume; + NzColor m_color; NzMaterialRef m_material; NzRectf m_textureCoords; NzVector2f m_size; + mutable NzVertexStruct_XYZ_Color_UV m_vertices[4]; mutable bool m_boundingVolumeUpdated; + mutable bool m_verticesUpdated; }; #endif // NAZARA_SPRITE_HPP diff --git a/include/Nazara/Utility/Enums.hpp b/include/Nazara/Utility/Enums.hpp index a5aec05bc..b6c1db419 100644 --- a/include/Nazara/Utility/Enums.hpp +++ b/include/Nazara/Utility/Enums.hpp @@ -254,6 +254,8 @@ enum nzVertexLayout nzVertexLayout_XY, nzVertexLayout_XY_UV, nzVertexLayout_XYZ, + nzVertexLayout_XYZ_Color, + nzVertexLayout_XYZ_Color_UV, nzVertexLayout_XYZ_Normal, nzVertexLayout_XYZ_Normal_UV, nzVertexLayout_XYZ_Normal_UV_Tangent, diff --git a/include/Nazara/Utility/VertexStruct.hpp b/include/Nazara/Utility/VertexStruct.hpp index 62c01c439..15cb02d28 100644 --- a/include/Nazara/Utility/VertexStruct.hpp +++ b/include/Nazara/Utility/VertexStruct.hpp @@ -7,6 +7,7 @@ #ifndef NAZARA_VERTEXSTRUCT_HPP #define NAZARA_VERTEXSTRUCT_HPP +#include #include #include @@ -17,7 +18,7 @@ struct NzVertexStruct_XY NzVector2f position; }; -struct NzVertexStruct_XY_UV : public NzVertexStruct_XY +struct NzVertexStruct_XY_UV : NzVertexStruct_XY { NzVector2f uv; }; @@ -29,29 +30,39 @@ struct NzVertexStruct_XYZ NzVector3f position; }; -struct NzVertexStruct_XYZ_Normal : public NzVertexStruct_XYZ +struct NzVertexStruct_XYZ_Color : NzVertexStruct_XYZ { - NzVector3f normal; + NzColor color; }; -struct NzVertexStruct_XYZ_Normal_UV : public NzVertexStruct_XYZ_Normal +struct NzVertexStruct_XYZ_Color_UV : NzVertexStruct_XYZ_Color { NzVector2f uv; }; -struct NzVertexStruct_XYZ_Normal_UV_Tangent : public NzVertexStruct_XYZ_Normal_UV +struct NzVertexStruct_XYZ_Normal : NzVertexStruct_XYZ +{ + NzVector3f normal; +}; + +struct NzVertexStruct_XYZ_Normal_UV : NzVertexStruct_XYZ_Normal +{ + NzVector2f uv; +}; + +struct NzVertexStruct_XYZ_Normal_UV_Tangent : NzVertexStruct_XYZ_Normal_UV { NzVector3f tangent; }; -struct NzVertexStruct_XYZ_UV : public NzVertexStruct_XYZ +struct NzVertexStruct_XYZ_UV : NzVertexStruct_XYZ { NzVector2f uv; }; /************************* Structures 3D (+ Skinning) ************************/ -struct NzVertexStruct_XYZ_Normal_UV_Tangent_Skinning : public NzVertexStruct_XYZ_Normal_UV_Tangent +struct NzVertexStruct_XYZ_Normal_UV_Tangent_Skinning : NzVertexStruct_XYZ_Normal_UV_Tangent { nzInt32 weightCount; diff --git a/src/Nazara/Graphics/DeferredRenderQueue.cpp b/src/Nazara/Graphics/DeferredRenderQueue.cpp index c4e393ec1..4c3d0cd35 100644 --- a/src/Nazara/Graphics/DeferredRenderQueue.cpp +++ b/src/Nazara/Graphics/DeferredRenderQueue.cpp @@ -103,29 +103,15 @@ void NzDeferredRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData } } -void NzDeferredRenderQueue::AddSprite(const NzSprite* sprite) +void NzDeferredRenderQueue::AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount) { - #if NAZARA_GRAPHICS_SAFE - if (!sprite) - { - NazaraError("Invalid sprite"); - return; - } - - if (!sprite->IsDrawable()) - { - NazaraError("Sprite is not drawable"); - return; - } - #endif - /*NzMaterial* material = sprite->GetMaterial(); if (!material->IsLightingEnabled() || material->IsEnabled(nzRendererParameter_Blend)) m_forwardQueue->AddSprite(sprite); else sprites[material].push_back(sprite);*/ - m_forwardQueue->AddSprite(sprite); + m_forwardQueue->AddSprites(material, vertices, spriteCount); } void NzDeferredRenderQueue::Clear(bool fully) diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index 90770660d..b0d1be9d6 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -12,6 +12,8 @@ #include #include +///FIXME: Régler ce problème de dépendance aux ressources + namespace { enum ResourceType @@ -121,23 +123,17 @@ void NzForwardRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& } } -void NzForwardRenderQueue::AddSprite(const NzSprite* sprite) +void NzForwardRenderQueue::AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount) { - #if NAZARA_GRAPHICS_SAFE - if (!sprite) + BasicSpriteBatches::iterator it = basicSprites.find(material); + if (it == basicSprites.end()) { - NazaraError("Invalid sprite"); - return; + it = basicSprites.insert(std::make_pair(material, BasicSpriteBatches::mapped_type())).first; + material->AddResourceListener(this, ResourceType_Material); } - if (!sprite->IsDrawable()) - { - NazaraError("Sprite is not drawable"); - return; - } - #endif - - sprites[sprite->GetMaterial()].push_back(sprite); + auto& spriteVector = it->second; + spriteVector.push_back(SpriteChain_XYZ_Color_UV({vertices, spriteCount})); } void NzForwardRenderQueue::Clear(bool fully) @@ -150,6 +146,13 @@ void NzForwardRenderQueue::Clear(bool fully) if (fully) { + for (auto& matIt : basicSprites) + { + const NzMaterial* material = matIt.first; + material->RemoveResourceListener(this); + } + basicSprites.clear(); + for (auto& matIt : opaqueModels) { const NzMaterial* material = matIt.first; @@ -167,7 +170,6 @@ void NzForwardRenderQueue::Clear(bool fully) } } opaqueModels.clear(); - sprites.clear(); } } @@ -210,6 +212,7 @@ bool NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int ind } case ResourceType_Material: + basicSprites.erase(static_cast(resource)); opaqueModels.erase(static_cast(resource)); break; @@ -260,6 +263,15 @@ void NzForwardRenderQueue::OnResourceReleased(const NzResource* resource, int in case ResourceType_Material: { + for (auto it = basicSprites.begin(); it != basicSprites.end(); ++it) + { + if (it->first == resource) + { + basicSprites.erase(it); + break; + } + } + for (auto it = opaqueModels.begin(); it != opaqueModels.end(); ++it) { if (it->first == resource) @@ -268,6 +280,7 @@ void NzForwardRenderQueue::OnResourceReleased(const NzResource* resource, int in break; } } + break; } @@ -299,7 +312,6 @@ bool NzForwardRenderQueue::BatchedModelMaterialComparator::operator()(const NzMa const NzShader* shader1 = mat1->GetShaderInstance()->GetShader(); const NzShader* shader2 = mat2->GetShaderInstance()->GetShader(); - if (shader1 != shader2) return shader1 < shader2; @@ -320,7 +332,6 @@ bool NzForwardRenderQueue::BatchedSpriteMaterialComparator::operator()(const NzM const NzShader* shader1 = mat1->GetShaderInstance()->GetShader(); const NzShader* shader2 = mat2->GetShaderInstance()->GetShader(); - if (shader1 != shader2) return shader1 < shader2; diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 896e7c70a..bc962cc19 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -49,7 +49,7 @@ namespace } NzForwardRenderTechnique::NzForwardRenderTechnique() : -m_spriteBuffer(NzVertexDeclaration::Get(nzVertexLayout_XYZ_UV), s_maxSprites*4, nzBufferStorage_Hardware, nzBufferUsage_Dynamic), +m_spriteBuffer(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Color_UV), s_maxSprites*4, nzBufferStorage_Hardware, nzBufferUsage_Dynamic), m_maxLightPassPerObject(3) { if (!s_indexBuffer) @@ -87,8 +87,8 @@ bool NzForwardRenderTechnique::Draw(const NzScene* scene) const if (!m_renderQueue.transparentModels.empty()) DrawTransparentModels(scene); - if (!m_renderQueue.sprites.empty()) - DrawSprites(scene); + if (!m_renderQueue.basicSprites.empty()) + DrawBasicSprites(scene); // Les autres drawables (Exemple: Terrain) for (const NzDrawable* drawable : m_renderQueue.otherDrawables) @@ -162,6 +162,77 @@ void NzForwardRenderTechnique::SetMaxLightPassPerObject(unsigned int passCount) m_maxLightPassPerObject = passCount; } +void NzForwardRenderTechnique::DrawBasicSprites(const NzScene* scene) const +{ + NzAbstractViewer* viewer = scene->GetViewer(); + const NzShader* lastShader = nullptr; + + NzRenderer::SetIndexBuffer(m_indexBuffer); + NzRenderer::SetMatrix(nzMatrixType_World, NzMatrix4f::Identity()); + NzRenderer::SetVertexBuffer(&m_spriteBuffer); + + for (auto& matIt : m_renderQueue.basicSprites) + { + const NzMaterial* material = matIt.first; + auto& spriteChainVector = matIt.second; + + unsigned int spriteChainCount = spriteChainVector.size(); + if (spriteChainCount > 0) + { + // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + const NzShader* shader = material->Apply(nzShaderFlags_VertexColor); + + // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas + if (shader != lastShader) + { + // Couleur ambiante de la scène + shader->SendColor(shader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); + // Position de la caméra + shader->SendVector(shader->GetUniformLocation(nzShaderUniform_EyePosition), 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 + NzBufferMapper vertexMapper(m_spriteBuffer, nzBufferAccess_DiscardAndWrite); + NzVertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(vertexMapper.GetPointer()); + + unsigned int spriteCount = 0; + { + NzForwardRenderQueue::SpriteChain_XYZ_Color_UV& currentChain = spriteChainVector[spriteChain]; + unsigned int count = std::min(s_maxSprites - 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 < s_maxSprites && spriteChain < spriteChainCount); + + vertexMapper.Unmap(); + + NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, spriteCount*6); + } + while (spriteChain < spriteChainCount); + + spriteChainVector.clear(); + } + } +} + void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const { NzAbstractViewer* viewer = scene->GetViewer(); @@ -275,7 +346,7 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const const NzMatrix4f* instanceMatrices = &instances[0]; unsigned int instanceCount = instances.size(); - unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing) + unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Le nombre maximum d'instances en une fois while (instanceCount > 0) { @@ -351,7 +422,7 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const } else { - // Sans instancing, on doit effectuer un drawcall pour chaque instance + // 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) @@ -373,82 +444,6 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const } } -void NzForwardRenderTechnique::DrawSprites(const NzScene* scene) const -{ - NzAbstractViewer* viewer = scene->GetViewer(); - const NzShader* lastShader = nullptr; - - NzRenderer::SetIndexBuffer(m_indexBuffer); - NzRenderer::SetMatrix(nzMatrixType_World, NzMatrix4f::Identity()); - NzRenderer::SetVertexBuffer(&m_spriteBuffer); - - for (auto& matIt : m_renderQueue.sprites) - { - const NzMaterial* material = matIt.first; - auto& spriteVector = matIt.second; - - unsigned int spriteCount = spriteVector.size(); - if (spriteCount > 0) - { - // On commence par appliquer du matériau (et récupérer le shader ainsi activé) - const NzShader* shader = material->Apply(); - - // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas - if (shader != lastShader) - { - // Couleur ambiante de la scène - shader->SendColor(shader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); - // Position de la caméra - shader->SendVector(shader->GetUniformLocation(nzShaderUniform_EyePosition), viewer->GetEyePosition()); - - lastShader = shader; - } - - const NzSprite** spritePtr = &spriteVector[0]; - do - { - unsigned int renderedSpriteCount = std::min(spriteCount, 64U); - spriteCount -= renderedSpriteCount; - - NzBufferMapper vertexMapper(m_spriteBuffer, nzBufferAccess_DiscardAndWrite, 0, renderedSpriteCount*4); - NzVertexStruct_XYZ_UV* vertices = reinterpret_cast(vertexMapper.GetPointer()); - - for (unsigned int i = 0; i < renderedSpriteCount; ++i) - { - const NzSprite* sprite = *spritePtr++; - const NzRectf& textureCoords = sprite->GetTextureCoords(); - const NzVector2f& halfSize = sprite->GetSize()*0.5f; - NzVector3f center = sprite->GetPosition(); - NzQuaternionf rotation = sprite->GetRotation(); - - vertices->position = center + rotation * NzVector3f(-halfSize.x, halfSize.y, 0.f); - vertices->uv.Set(textureCoords.x, textureCoords.y + textureCoords.height); - vertices++; - - vertices->position = center + rotation * NzVector3f(halfSize.x, halfSize.y, 0.f); - vertices->uv.Set(textureCoords.width, textureCoords.y + textureCoords.height); - vertices++; - - vertices->position = center + rotation * NzVector3f(-halfSize.x, -halfSize.y, 0.f); - vertices->uv.Set(textureCoords.x, textureCoords.y); - vertices++; - - vertices->position = center + rotation * NzVector3f(halfSize.x, -halfSize.y, 0.f); - vertices->uv.Set(textureCoords.width, textureCoords.y); - vertices++; - } - - vertexMapper.Unmap(); - - NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, renderedSpriteCount*6); - } - while (spriteCount > 0); - - spriteVector.clear(); - } - } -} - void NzForwardRenderTechnique::DrawTransparentModels(const NzScene* scene) const { NzAbstractViewer* viewer = scene->GetViewer(); diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 3c9861acc..2774b42fa 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -692,6 +692,7 @@ void NzMaterial::GenerateShader(nzUInt32 flags) const list.SetParameter("FLAG_DEFERRED", static_cast((flags & nzShaderFlags_Deferred) != 0)); list.SetParameter("FLAG_INSTANCING", static_cast((flags & nzShaderFlags_Instancing) != 0)); + list.SetParameter("FLAG_VERTEXCOLOR", static_cast((flags & nzShaderFlags_VertexColor) != 0)); ShaderInstance& instance = m_shaders[flags]; instance.uberInstance = m_uberShader->Get(list); @@ -759,7 +760,7 @@ bool NzMaterial::Initialize() } uberShader->SetShader(nzShaderStage_Fragment, fragmentShader, "ALPHA_MAPPING ALPHA_TEST AUTO_TEXCOORDS DIFFUSE_MAPPING"); - uberShader->SetShader(nzShaderStage_Vertex, vertexShader, "FLAG_INSTANCING TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); + uberShader->SetShader(nzShaderStage_Vertex, vertexShader, "FLAG_INSTANCING FLAG_VERTEXCOLOR TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); NzUberShaderLibrary::Register("Basic", uberShader.get()); uberShader.release(); @@ -800,7 +801,7 @@ bool NzMaterial::Initialize() } uberShader->SetShader(nzShaderStage_Fragment, fragmentShader, "FLAG_DEFERRED ALPHA_MAPPING ALPHA_TEST DIFFUSE_MAPPING EMISSIVE_MAPPING LIGHTING NORMAL_MAPPING PARALLAX_MAPPING SPECULAR_MAPPING"); - uberShader->SetShader(nzShaderStage_Vertex, vertexShader, "FLAG_DEFERRED FLAG_INSTANCING COMPUTE_TBNMATRIX LIGHTING PARALLAX_MAPPING TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); + uberShader->SetShader(nzShaderStage_Vertex, vertexShader, "FLAG_DEFERRED FLAG_INSTANCING FLAG_VERTEXCOLOR COMPUTE_TBNMATRIX LIGHTING PARALLAX_MAPPING TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); NzUberShaderLibrary::Register("PhongLighting", uberShader.get()); uberShader.release(); diff --git a/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag b/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag index a789242b9..57068325d 100644 --- a/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag +++ b/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag @@ -3,6 +3,7 @@ layout(early_fragment_tests) in; #endif /********************Entrant********************/ +in vec4 vColor; in vec2 vTexCoord; /********************Sortant********************/ @@ -18,7 +19,7 @@ uniform vec2 InvTargetSize; /********************Fonctions********************/ void main() { - vec4 fragmentColor = MaterialDiffuse; + vec4 fragmentColor = MaterialDiffuse * vColor; #if AUTO_TEXCOORDS vec2 texCoord = gl_FragCoord.xy * InvTargetSize; diff --git a/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag.h b/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag.h index 97c8ee9b1..319917ab6 100644 --- a/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag.h +++ b/src/Nazara/Graphics/Resources/Shaders/Basic/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,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,50,32,118,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,82,101,110,100,101,114,84,97,114,103,101,116,48,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,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,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,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,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,9,118,101,99,52,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,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,68,73,70,70,85,83,69,95,77,65,80,80,73,78,71,13,10,9,102,114,97,103,109,101,110,116,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,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,102,114,97,103,109,101,110,116,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,35,101,110,100,105,102,13,10,13,10,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,105,102,32,40,102,114,97,103,109,101,110,116,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,35,101,110,100,105,102,13,10,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,125, \ 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,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,50,32,118,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,82,101,110,100,101,114,84,97,114,103,101,116,48,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,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,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,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,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,9,118,101,99,52,32,102,114,97,103,109,101,110,116,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,68,73,70,70,85,83,69,95,77,65,80,80,73,78,71,13,10,9,102,114,97,103,109,101,110,116,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,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,102,114,97,103,109,101,110,116,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,35,101,110,100,105,102,13,10,13,10,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,105,102,32,40,102,114,97,103,109,101,110,116,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,35,101,110,100,105,102,13,10,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,125, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/Shaders/Basic/core.vert b/src/Nazara/Graphics/Resources/Shaders/Basic/core.vert index 0516e8090..6a5143444 100644 --- a/src/Nazara/Graphics/Resources/Shaders/Basic/core.vert +++ b/src/Nazara/Graphics/Resources/Shaders/Basic/core.vert @@ -1,9 +1,11 @@ /********************Entrant********************/ in mat4 InstanceData0; +in vec4 VertexColor; in vec3 VertexPosition; in vec2 VertexTexCoord; /********************Sortant********************/ +out vec4 vColor; out vec2 vTexCoord; /********************Uniformes********************/ @@ -14,6 +16,12 @@ uniform mat4 WorldViewProjMatrix; /********************Fonctions********************/ void main() { +#if FLAG_VERTEXCOLOR + vec4 color = VertexColor; +#else + vec4 color = vec4(1.0); +#endif + #if FLAG_INSTANCING #if TRANSFORM gl_Position = ViewProjMatrix * InstanceData0 * vec4(VertexPosition, 1.0); @@ -36,6 +44,7 @@ void main() #endif #endif + vColor = color; #if TEXTURE_MAPPING vTexCoord = vec2(VertexTexCoord); #endif diff --git a/src/Nazara/Graphics/Resources/Shaders/Basic/core.vert.h b/src/Nazara/Graphics/Resources/Shaders/Basic/core.vert.h index 681ed8a5a..6532129d4 100644 --- a/src/Nazara/Graphics/Resources/Shaders/Basic/core.vert.h +++ b/src/Nazara/Graphics/Resources/Shaders/Basic/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,105,110,32,109,97,116,52,32,73,110,115,116,97,110,99,101,68,97,116,97,48,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,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,50,32,118,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,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,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,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,73,78,83,84,65,78,67,73,78,71,13,10,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,35,101,108,115,101,13,10,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,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,35,101,108,115,101,13,10,9,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,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,13,10,35,101,108,115,101,13,10,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,35,101,108,115,101,13,10,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,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,35,101,108,115,101,13,10,9,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,35,101,110,100,105,102,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,118,101,99,50,40,86,101,114,116,101,120,84,101,120,67,111,111,114,100,41,59,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,105,110,32,109,97,116,52,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,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,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,50,32,118,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,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,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,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,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,10,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,35,101,108,115,101,13,10,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,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,35,101,108,115,101,13,10,9,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,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,13,10,35,101,108,115,101,13,10,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,35,101,108,115,101,13,10,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,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,35,101,108,115,101,13,10,9,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,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,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,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,118,101,99,50,40,86,101,114,116,101,120,84,101,120,67,111,111,114,100,41,59,13,10,35,101,110,100,105,102,13,10,125,13,10, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag index 055b5472e..cf0f596da 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag @@ -7,6 +7,7 @@ layout(early_fragment_tests) in; #define LIGHT_SPOT 2 /********************Entrant********************/ +in vec4 vColor; in mat3 vLightToWorld; in vec3 vNormal; in vec2 vTexCoord; @@ -76,7 +77,7 @@ vec4 EncodeNormal(in vec3 normal) void main() { - vec4 diffuseColor = MaterialDiffuse; + vec4 diffuseColor = MaterialDiffuse * vColor; vec2 texCoord = vTexCoord; #if LIGHTING && PARALLAX_MAPPING float height = texture(MaterialHeightMap, texCoord).r; diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h index 54e4bb415..60271acaf 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,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,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,76,105,103,104,116,32,76,105,103,104,116,115,91,51,93,59,13,10,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,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,52,32,83,99,101,110,101,65,109,98,105,101,110,116,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,59,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,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,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,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,32,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,41,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,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,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,76,105,103,104,116,32,76,105,103,104,116,115,91,51,93,59,13,10,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,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,52,32,83,99,101,110,101,65,109,98,105,101,110,116,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,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,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,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,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,32,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,41,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 diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert index 09430bb06..454df5b82 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert @@ -1,11 +1,13 @@ /********************Entrant********************/ in mat4 InstanceData0; +in vec4 VertexColor; in vec3 VertexPosition; in vec3 VertexNormal; in vec3 VertexTangent; in vec2 VertexTexCoord; /********************Sortant********************/ +out vec4 vColor; out mat3 vLightToWorld; out vec3 vNormal; out vec2 vTexCoord; @@ -22,6 +24,12 @@ uniform mat4 WorldViewProjMatrix; /********************Fonctions********************/ void main() { +#if FLAG_VERTEXCOLOR + vec4 color = VertexColor; +#else + vec4 color = vec4(1.0); +#endif + #if FLAG_INSTANCING #if TRANSFORM gl_Position = ViewProjMatrix * InstanceData0 * vec4(VertexPosition, 1.0); @@ -44,6 +52,8 @@ void main() #endif #endif + vColor = color; + #if LIGHTING #if FLAG_INSTANCING mat3 rotationMatrix = mat3(InstanceData0); diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.vert.h index c920136a2..3382bc09f 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,105,110,32,109,97,116,52,32,73,110,115,116,97,110,99,101,68,97,116,97,48,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,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,73,78,83,84,65,78,67,73,78,71,13,10,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,35,101,108,115,101,13,10,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,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,35,101,108,115,101,13,10,9,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,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,13,10,35,101,108,115,101,13,10,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,35,101,108,115,101,13,10,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,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,35,101,108,115,101,13,10,9,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,35,101,110,100,105,102,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,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,35,105,102,32,70,76,65,71,95,70,76,73,80,95,85,86,83,13,10,9,118,84,101,120,67,111,111,114,100,32,61,32,118,101,99,50,40,86,101,114,116,101,120,84,101,120,67,111,111,114,100,46,120,44,32,49,46,48,32,45,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,46,121,41,59,13,10,9,35,101,108,115,101,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,9,35,101,110,100,105,102,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,105,110,32,109,97,116,52,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,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,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,10,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,35,101,108,115,101,13,10,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,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,35,101,108,115,101,13,10,9,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,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,13,10,35,101,108,115,101,13,10,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,35,101,108,115,101,13,10,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,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,35,101,108,115,101,13,10,9,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,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,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,35,105,102,32,70,76,65,71,95,70,76,73,80,95,85,86,83,13,10,9,118,84,101,120,67,111,111,114,100,32,61,32,118,101,99,50,40,86,101,114,116,101,120,84,101,120,67,111,111,114,100,46,120,44,32,49,46,48,32,45,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,46,121,41,59,13,10,9,35,101,108,115,101,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,9,35,101,110,100,105,102,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 diff --git a/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index df181ac5d..b6dcf5ae0 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -3,20 +3,25 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include NzSprite::NzSprite() : m_boundingVolume(NzBoundingVolumef::Null()), +m_color(NzColor::White), m_textureCoords(0.f, 0.f, 1.f, 1.f), m_size(64.f, 64.f), -m_boundingVolumeUpdated(true) +m_boundingVolumeUpdated(true), +m_verticesUpdated(false) { } NzSprite::NzSprite(NzTexture* texture) : m_boundingVolume(NzBoundingVolumef::Null()), -m_textureCoords(0.f, 0.f, 1.f, 1.f) +m_color(NzColor::White), +m_textureCoords(0.f, 0.f, 1.f, 1.f), +m_verticesUpdated(false) { if (texture) { @@ -44,7 +49,9 @@ m_boundingVolume(sprite.m_boundingVolume), m_material(sprite.m_material), m_textureCoords(sprite.m_textureCoords), m_size(sprite.m_size), -m_boundingVolumeUpdated(sprite.m_boundingVolumeUpdated) +m_vertices(sprite.m_vertices), +m_boundingVolumeUpdated(sprite.m_boundingVolumeUpdated), +m_verticesUpdated(sprite.m_verticesUpdated) { SetParent(sprite); } @@ -55,7 +62,9 @@ m_boundingVolume(sprite.m_boundingVolume), m_material(std::move(sprite.m_material)), m_textureCoords(sprite.m_textureCoords), m_size(sprite.m_size), -m_boundingVolumeUpdated(sprite.m_boundingVolumeUpdated) +m_vertices(sprite.m_vertices), +m_boundingVolumeUpdated(sprite.m_boundingVolumeUpdated), +m_verticesUpdated(sprite.m_verticesUpdated) { } @@ -63,13 +72,23 @@ NzSprite::~NzSprite() = default; void NzSprite::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const { - renderQueue->AddSprite(this); + if (!m_verticesUpdated) + UpdateVertices(); + + renderQueue->AddSprites(m_material, m_vertices, 1); } const NzBoundingVolumef& NzSprite::GetBoundingVolume() const { - static NzBoundingVolumef infinity(NzBoundingVolumef::Infinite()); - return infinity; + if (!m_boundingVolumeUpdated) + UpdateBoundingVolume(); + + return m_boundingVolume; +} + +const NzColor& NzSprite::GetColor() const +{ + return m_color; } NzMaterial* NzSprite::GetMaterial() const @@ -97,6 +116,12 @@ bool NzSprite::IsDrawable() const return m_material != nullptr; } +void NzSprite::SetColor(const NzColor& color) +{ + m_color = color; + m_verticesUpdated = false; +} + void NzSprite::SetMaterial(NzMaterial* material, bool resizeSprite) { m_material = material; @@ -113,6 +138,7 @@ void NzSprite::SetSize(const NzVector2f& size) // On invalide la bounding box m_boundingVolume.MakeNull(); m_boundingVolumeUpdated = false; + m_verticesUpdated = false; } void NzSprite::SetSize(float sizeX, float sizeY) @@ -136,6 +162,7 @@ void NzSprite::SetTexture(NzTexture* texture, bool resizeSprite) void NzSprite::SetTextureCoords(const NzRectf& coords) { m_textureCoords = coords; + m_verticesUpdated = false; } void NzSprite::SetTextureRect(const NzRectui& rect) @@ -167,10 +194,13 @@ void NzSprite::InvalidateNode() NzSceneNode::InvalidateNode(); m_boundingVolumeUpdated = false; + m_verticesUpdated = false; } void NzSprite::Register() { + // Le changement de scène peut affecter les sommets + m_verticesUpdated = false; } void NzSprite::Unregister() @@ -180,7 +210,12 @@ void NzSprite::Unregister() void NzSprite::UpdateBoundingVolume() const { if (m_boundingVolume.IsNull()) - m_boundingVolume.Set(-m_size.x*0.5f, -m_size.y*0.5f, 0.f, m_size.x, m_size.y, 0.f); + { + NzVector3f down = m_scene->GetDown(); + NzVector3f right = m_scene->GetRight(); + + m_boundingVolume.Set(NzVector3f(0.f), m_size.x*right + m_size.y*down); + } if (!m_transformMatrixUpdated) UpdateTransformMatrix(); @@ -188,3 +223,30 @@ void NzSprite::UpdateBoundingVolume() const m_boundingVolume.Update(m_transformMatrix); m_boundingVolumeUpdated = true; } + +void NzSprite::UpdateVertices() const +{ + if (!m_transformMatrixUpdated) + UpdateTransformMatrix(); + + NzVector3f down = m_scene->GetDown(); + NzVector3f right = m_scene->GetRight(); + + m_vertices[0].color = m_color; + m_vertices[0].position = m_transformMatrix.Transform(NzVector3f(0.f)); + m_vertices[0].uv.Set(m_textureCoords.GetCorner(nzRectCorner_LeftTop)); + + m_vertices[1].color = m_color; + m_vertices[1].position = m_transformMatrix.Transform(m_size.x*right); + m_vertices[1].uv.Set(m_textureCoords.GetCorner(nzRectCorner_RightTop)); + + m_vertices[2].color = m_color; + m_vertices[2].position = m_transformMatrix.Transform(m_size.y*down); + m_vertices[2].uv.Set(m_textureCoords.GetCorner(nzRectCorner_LeftBottom)); + + m_vertices[3].color = m_color; + m_vertices[3].position = m_transformMatrix.Transform(m_size.x*right + m_size.y*down); + m_vertices[3].uv.Set(m_textureCoords.GetCorner(nzRectCorner_RightBottom)); + + m_verticesUpdated = true; +} diff --git a/src/Nazara/Utility/VertexDeclaration.cpp b/src/Nazara/Utility/VertexDeclaration.cpp index de4860d82..00e9d9768 100644 --- a/src/Nazara/Utility/VertexDeclaration.cpp +++ b/src/Nazara/Utility/VertexDeclaration.cpp @@ -205,6 +205,21 @@ bool NzVertexDeclaration::Initialize() NazaraAssert(declaration->GetStride() == sizeof(NzVertexStruct_XYZ), "Invalid stride for declaration nzVertexLayout_XYZ"); + // nzVertexLayout_XYZ_Color : NzVertexStruct_XYZ_Color + declaration = &s_declarations[nzVertexLayout_XYZ_Color_UV]; + declaration->EnableComponent(nzVertexComponent_Position, nzComponentType_Float3, NzOffsetOf(NzVertexStruct_XYZ_Color, position)); + declaration->EnableComponent(nzVertexComponent_Color, nzComponentType_Color, NzOffsetOf(NzVertexStruct_XYZ_Color, color)); + + NazaraAssert(declaration->GetStride() == sizeof(NzVertexStruct_XYZ_Color), "Invalid stride for declaration nzVertexLayout_XYZ_Color"); + + // nzVertexLayout_XYZ_Color_UV : NzVertexStruct_XYZ_Color_UV + declaration = &s_declarations[nzVertexLayout_XYZ_Color_UV]; + declaration->EnableComponent(nzVertexComponent_Position, nzComponentType_Float3, NzOffsetOf(NzVertexStruct_XYZ_Color_UV, position)); + declaration->EnableComponent(nzVertexComponent_Color, nzComponentType_Color, NzOffsetOf(NzVertexStruct_XYZ_Color_UV, color)); + declaration->EnableComponent(nzVertexComponent_TexCoord, nzComponentType_Float2, NzOffsetOf(NzVertexStruct_XYZ_Color_UV, uv)); + + NazaraAssert(declaration->GetStride() == sizeof(NzVertexStruct_XYZ_Color_UV), "Invalid stride for declaration nzVertexLayout_XYZ_Color_UV"); + // nzVertexLayout_XYZ_Normal : NzVertexStruct_XYZ_Normal declaration = &s_declarations[nzVertexLayout_XYZ_Normal]; declaration->EnableComponent(nzVertexComponent_Position, nzComponentType_Float3, NzOffsetOf(NzVertexStruct_XYZ_Normal, position)); From 119b0432015cb7efd8b582e15f54b84b507af6b2 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 4 Jan 2015 13:21:34 +0100 Subject: [PATCH 113/233] Updated STB_image to v2.00b Former-commit-id: a0887de0a051fab7ceb34c4ed5e9aedde0e6b1a9 --- src/Nazara/Utility/Loaders/STB/Loader.cpp | 30 +++++++++++------------ 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Nazara/Utility/Loaders/STB/Loader.cpp b/src/Nazara/Utility/Loaders/STB/Loader.cpp index 64f0f6aee..0f78fcca2 100644 --- a/src/Nazara/Utility/Loaders/STB/Loader.cpp +++ b/src/Nazara/Utility/Loaders/STB/Loader.cpp @@ -15,29 +15,29 @@ namespace { - int Read(void* userdata, char* data, int size) + int Read(void* userdata, char* data, int size) + { + NzInputStream* stream = static_cast(userdata); + return static_cast(stream->Read(data, size)); + } + + void Skip(void* userdata, int size) { - NzInputStream* stream = reinterpret_cast(userdata); - return static_cast(stream->Read(data, size)); + NzInputStream* stream = static_cast(userdata); + stream->SetCursorPos(static_cast(stream->GetCursorPos()) + static_cast(size)); } - void Skip(void* userdata, unsigned int size) - { - NzInputStream* stream = reinterpret_cast(userdata); - stream->Read(nullptr, size); - } - - int Eof(void* userdata) - { - NzInputStream* stream = reinterpret_cast(userdata); - return stream->GetCursorPos() >= stream->GetSize(); - } + int Eof(void* userdata) + { + NzInputStream* stream = static_cast(userdata); + return stream->GetCursorPos() >= stream->GetSize(); + } static stbi_io_callbacks callbacks = {Read, Skip, Eof}; bool IsSupported(const NzString& extension) { - static std::set supportedExtensions = {"bmp", "gif", "hdr", "jpg", "jpeg", "pic", "png", "psd", "tga"}; + static std::set supportedExtensions = {"bmp", "gif", "hdr", "jpg", "jpeg", "pic", "png", "ppm", "pgm", "psd", "tga"}; return supportedExtensions.find(extension) != supportedExtensions.end(); } From 8a836b20605873d77ee18f5cb692f9c8f1201194 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 4 Jan 2015 14:21:09 +0100 Subject: [PATCH 114/233] Added Font class (+ FreeType loader) Former-commit-id: 1811304cd0efe9a86cbae83faaf4c39d9fae248f --- include/Nazara/Utility/Enums.hpp | 21 + include/Nazara/Utility/Font.hpp | 133 +++++ include/Nazara/Utility/FontData.hpp | 36 ++ include/Nazara/Utility/FontGlyph.hpp | 19 + src/Nazara/Utility/Font.cpp | 507 ++++++++++++++++++ src/Nazara/Utility/FontData.cpp | 8 + src/Nazara/Utility/Loaders/FreeType.hpp | 15 + .../Utility/Loaders/FreeType/Loader.cpp | 393 ++++++++++++++ src/Nazara/Utility/Utility.cpp | 5 + 9 files changed, 1137 insertions(+) create mode 100644 include/Nazara/Utility/Font.hpp create mode 100644 include/Nazara/Utility/FontData.hpp create mode 100644 include/Nazara/Utility/FontGlyph.hpp create mode 100644 src/Nazara/Utility/Font.cpp create mode 100644 src/Nazara/Utility/FontData.cpp create mode 100644 src/Nazara/Utility/Loaders/FreeType.hpp create mode 100644 src/Nazara/Utility/Loaders/FreeType/Loader.cpp diff --git a/include/Nazara/Utility/Enums.hpp b/include/Nazara/Utility/Enums.hpp index b6c1db419..06e2a5c2a 100644 --- a/include/Nazara/Utility/Enums.hpp +++ b/include/Nazara/Utility/Enums.hpp @@ -218,6 +218,27 @@ enum nzPrimitiveMode nzPrimitiveMode_Max = nzPrimitiveMode_TriangleFan }; +enum nzTextAlign +{ + nzTextAlign_Left, + nzTextAlign_Middle, + nzTextAlign_Right, + + nzTextAlign_Max = nzTextAlign_Right +}; + +enum nzTextStyleFlags +{ + nzTextStyle_None = 0x0, + + nzTextStyle_Bold = 0x1, + nzTextStyle_Italic = 0x2, + nzTextStyle_StrikeThrough = 0x4, + nzTextStyle_Underlined = 0x8, + + nzTextStyle_Max = nzTextStyle_Underlined*2-1 +}; + enum nzVertexComponent { nzVertexComponent_Unused = -1, diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp new file mode 100644 index 000000000..190d3c716 --- /dev/null +++ b/include/Nazara/Utility/Font.hpp @@ -0,0 +1,133 @@ +// Copyright (C) 2014 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_FONT_HPP +#define NAZARA_FONT_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +struct NAZARA_API NzFontParams +{ + bool IsValid() const; +}; + +class NzFont; +class NzFontData; + +struct NzFontGlyph; // TEMP + +using NzFontConstRef = NzResourceRef; +using NzFontLoader = NzResourceLoader; +using NzFontRef = NzResourceRef; + +class NAZARA_API NzFont : public NzResource, NzNonCopyable +{ + friend NzFontLoader; + + public: + struct Atlas + { + NzGuillotineBinPack binPack; + NzImage image; + }; + + struct Glyph + { + NzRecti aabb; + NzRectui atlasRect; + bool flipped; + bool valid; + int advance; + unsigned int atlasIndex; + }; + + struct SizeInfo + { + unsigned int lineHeight; + float underlinePosition; + float underlineThickness; + }; + + NzFont(); + NzFont(NzFont&& font) = default; + ~NzFont(); + + void ClearGlyphCache(); + void ClearKerningCache(); + void ClearSizeInfoCache(); + + bool Create(NzFontData* data); + void Destroy(); + + bool ExtractGlyph(unsigned int characterSize, char32_t character, nzUInt32 style, NzFontGlyph* glyph) const; + + const Atlas& GetAtlas(unsigned int atlasIndex) const; + unsigned int GetAtlasCount() const; + unsigned int GetCachedGlyphCount(unsigned int characterSize, nzUInt32 style) const; + unsigned int GetCachedGlyphCount() const; + NzString GetFamilyName() const; + int GetKerning(unsigned int characterSize, char32_t first, char32_t second) const; + const Glyph& GetGlyph(unsigned int characterSize, nzUInt32 style, char32_t character) const; + unsigned int GetMaxAtlasSize() const; + unsigned int GetMinimumStepSize() const; + const SizeInfo& GetSizeInfo(unsigned int characterSize) const; + NzString GetStyleName() const; + + bool IsValid() const; + + bool Precache(unsigned int characterSize, nzUInt32 style, char32_t character) const; + bool Precache(unsigned int characterSize, nzUInt32 style, const NzString& characterSet) const; + + // Open + bool OpenFromFile(const NzString& filePath, const NzFontParams& params = NzFontParams()); + bool OpenFromMemory(const void* data, std::size_t size, const NzFontParams& params = NzFontParams()); + bool OpenFromStream(NzInputStream& stream, const NzFontParams& params = NzFontParams()); + + void SetMaxAtlasSize(unsigned int maxAtlasSize); + void SetMinimumStepSize(unsigned int minimumSizeStep); + + NzFont& operator=(NzFont&& font) = default; + + static unsigned int GetDefaultMaxAtlasSize(); + static void SetDefaultMaxAtlasSize(unsigned int maxAtlasSize); + + private: + using GlyphMap = std::unordered_map; + + struct QueuedGlyph + { + char32_t codepoint; + NzImage image; + GlyphMap* map; + }; + + nzUInt64 ComputeKey(unsigned int characterSize, nzUInt32 style) const; + unsigned int GetRealMaxAtlasSize() const; + unsigned int InsertRect(NzRectui* rect, bool* flipped) const; + const Glyph& PrecacheGlyph(GlyphMap& glyphMap, unsigned int characterSize, bool bold, char32_t character) const; + void ProcessGlyphQueue() const; + + std::unique_ptr m_data; + mutable std::unordered_map> m_kerningCache; + mutable std::unordered_map m_glyphes; + mutable std::unordered_map m_sizeInfoCache; + mutable std::vector m_atlases; + mutable std::vector m_glyphQueue; + unsigned int m_maxAtlasSize; + unsigned int m_minimumSizeStep; + + static NzFontLoader::LoaderList s_loaders; + static unsigned int s_maxAtlasSize; +}; + +#endif // NAZARA_FONT_HPP diff --git a/include/Nazara/Utility/FontData.hpp b/include/Nazara/Utility/FontData.hpp new file mode 100644 index 000000000..9805c1d2b --- /dev/null +++ b/include/Nazara/Utility/FontData.hpp @@ -0,0 +1,36 @@ +// Copyright (C) 2014 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_FONTDATA_HPP +#define NAZARA_FONTDATA_HPP + +#include +#include + +struct NzFontGlyph; + +class NAZARA_API NzFontData +{ + public: + NzFontData() = default; + virtual ~NzFontData(); + + virtual bool ExtractGlyph(unsigned int characterSize, char32_t character, bool bold, NzFontGlyph* dst) = 0; + + virtual NzString GetFamilyName() const = 0; + virtual NzString GetStyleName() const = 0; + + virtual bool HasKerning() const = 0; + + virtual bool IsScalable() const = 0; + + virtual int QueryKerning(unsigned int characterSize, char32_t first, char32_t second) const = 0; + virtual unsigned int QueryLineHeight(unsigned int characterSize) const = 0; + virtual float QueryUnderlinePosition(unsigned int characterSize) const = 0; + virtual float QueryUnderlineThickness(unsigned int characterSize) const = 0; +}; + +#endif // NAZARA_FONTDATA_HPP diff --git a/include/Nazara/Utility/FontGlyph.hpp b/include/Nazara/Utility/FontGlyph.hpp new file mode 100644 index 000000000..11bceb255 --- /dev/null +++ b/include/Nazara/Utility/FontGlyph.hpp @@ -0,0 +1,19 @@ +// Copyright (C) 2014 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_FONTGLYPH_HPP +#define NAZARA_FONTGLYPH_HPP + +#include + +struct NzFontGlyph +{ + NzImage image; + NzRecti aabb; + int advance; +}; + +#endif // NAZARA_FONTGLYPH_HPP diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp new file mode 100644 index 000000000..c6a888929 --- /dev/null +++ b/src/Nazara/Utility/Font.cpp @@ -0,0 +1,507 @@ +// Copyright (C) 2014 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 + +namespace +{ + const unsigned int s_atlasStartSize = 512; +} + +bool NzFontParams::IsValid() const +{ + return true; // Rien à tester +} + +NzFont::NzFont() : +m_maxAtlasSize(0), +m_minimumSizeStep(1) +{ +} + +NzFont::~NzFont() +{ + Destroy(); +} + +void NzFont::ClearGlyphCache() +{ + // Destruction des atlas et glyphes mémorisés + m_atlases.clear(); + m_glyphes.clear(); + m_glyphQueue.clear(); + + // Création du premier atlas + m_atlases.resize(1); + Atlas& atlas = m_atlases.back(); + atlas.binPack.Reset(s_atlasStartSize, s_atlasStartSize); +} + +void NzFont::ClearKerningCache() +{ + m_kerningCache.clear(); +} + +void NzFont::ClearSizeInfoCache() +{ + m_sizeInfoCache.clear(); +} + +bool NzFont::Create(NzFontData* data) +{ + Destroy(); + + #if NAZARA_UTILITY_SAFE + if (!data) + { + NazaraError("Invalid font data"); + return false; + } + #endif + + m_data.reset(data); + + ClearGlyphCache(); // Création du premier atlas en mémoire + + return true; +} + +void NzFont::Destroy() +{ + m_atlases.clear(); + m_data.reset(); + m_kerningCache.clear(); + m_glyphes.clear(); + m_glyphQueue.clear(); + m_sizeInfoCache.clear(); +} + +bool NzFont::ExtractGlyph(unsigned int characterSize, char32_t character, nzUInt32 style, NzFontGlyph* glyph) const +{ + #if NAZARA_UTILITY_SAFE + if (!IsValid()) + { + NazaraError("Invalid font"); + return false; + } + #endif + + return m_data->ExtractGlyph(characterSize, character, style & nzTextStyle_Bold, glyph); +} + +const NzFont::Atlas& NzFont::GetAtlas(unsigned int atlasIndex) const +{ + if (!m_glyphQueue.empty()) + ProcessGlyphQueue(); + + return m_atlases.at(atlasIndex); +} + +unsigned int NzFont::GetAtlasCount() const +{ + return m_atlases.size(); +} + +unsigned int NzFont::GetCachedGlyphCount(unsigned int characterSize, nzUInt32 style) const +{ + nzUInt64 key = ComputeKey(characterSize, style); + auto it = m_glyphes.find(key); + if (it == m_glyphes.end()) + return 0; + + return it->second.size(); +} + +unsigned int NzFont::GetCachedGlyphCount() const +{ + unsigned int count = 0; + for (auto& pair : m_glyphes) + count += pair.second.size(); + + return count; +} + +NzString NzFont::GetFamilyName() const +{ + #if NAZARA_UTILITY_SAFE + if (!IsValid()) + { + NazaraError("Invalid font"); + return NzString("Invalid font"); + } + #endif + + return m_data->GetFamilyName(); +} + +int NzFont::GetKerning(unsigned int characterSize, char32_t first, char32_t second) const +{ + #if NAZARA_UTILITY_SAFE + if (!IsValid()) + { + NazaraError("Invalid font"); + return 0; + } + #endif + + // On utilise un cache car la méthode interne QueryKerning peut se révéler coûteuse (car pouvant induire un changement de taille) + auto& map = m_kerningCache[characterSize]; + + nzUInt64 key = (static_cast(first) << 32) | second; // Combinaison de deux caractères 32 bits dans un nombre 64 bits + + auto it = map.find(key); + if (it == map.end()) + { + // Absent du cache: on va demander l'information à la police + int kerning = m_data->QueryKerning(characterSize, first, second); + map.insert(std::make_pair(key, kerning)); + + return kerning; + } + else + return it->second; // Présent dans le cache, tout va bien +} + +const NzFont::Glyph& NzFont::GetGlyph(unsigned int characterSize, nzUInt32 style, char32_t character) const +{ + nzUInt64 key = ComputeKey(characterSize, style); + return PrecacheGlyph(m_glyphes[key], characterSize, style, character); +} + +unsigned int NzFont::GetMaxAtlasSize() const +{ + return m_maxAtlasSize; +} + +unsigned int NzFont::GetMinimumStepSize() const +{ + return m_minimumSizeStep; +} + +const NzFont::SizeInfo& NzFont::GetSizeInfo(unsigned int characterSize) const +{ + #if NAZARA_UTILITY_SAFE + if (!IsValid()) + { + NazaraError("Invalid font"); + + static SizeInfo dummy; + return dummy; + } + #endif + + auto it = m_sizeInfoCache.find(characterSize); + if (it == m_sizeInfoCache.end()) + { + SizeInfo sizeInfo; + sizeInfo.lineHeight = m_data->QueryLineHeight(characterSize); + sizeInfo.underlinePosition = m_data->QueryUnderlinePosition(characterSize); + sizeInfo.underlineThickness = m_data->QueryUnderlineThickness(characterSize); + + it = m_sizeInfoCache.insert(std::make_pair(characterSize, sizeInfo)).first; + } + + return it->second; +} + +NzString NzFont::GetStyleName() const +{ + #if NAZARA_UTILITY_SAFE + if (!IsValid()) + { + NazaraError("Invalid font"); + return NzString("Invalid font"); + } + #endif + + return m_data->GetStyleName(); +} + +bool NzFont::IsValid() const +{ + return m_data != nullptr; +} + +bool NzFont::Precache(unsigned int characterSize, nzUInt32 style, char32_t character) const +{ + nzUInt64 key = ComputeKey(characterSize, style); + return PrecacheGlyph(m_glyphes[key], characterSize, style, character).valid; +} + +bool NzFont::Precache(unsigned int characterSize, nzUInt32 style, const NzString& characterSet) const +{ + unsigned int size; + std::unique_ptr characters(characterSet.GetUtf32Buffer(&size)); + if (!characters) + { + NazaraError("Invalid character set"); + return false; + } + + nzUInt64 key = ComputeKey(characterSize, style); + auto& glyphMap = m_glyphes[key]; + for (unsigned int i = 0; i < size; ++i) + PrecacheGlyph(glyphMap, characterSize, style, characters[i]); + + return true; +} + +bool NzFont::OpenFromFile(const NzString& filePath, const NzFontParams& params) +{ + return NzFontLoader::LoadFromFile(this, filePath, params); +} + +bool NzFont::OpenFromMemory(const void* data, std::size_t size, const NzFontParams& params) +{ + return NzFontLoader::LoadFromMemory(this, data, size, params); +} + +bool NzFont::OpenFromStream(NzInputStream& stream, const NzFontParams& params) +{ + return NzFontLoader::LoadFromStream(this, stream, params); +} + +void NzFont::SetMaxAtlasSize(unsigned int maxAtlasSize) +{ + unsigned int oldMaxAtlasSize = GetRealMaxAtlasSize(); + m_maxAtlasSize = maxAtlasSize; + + // Si l'un de nos atlas dépasse la nouvelle taille, on doit vider le cache + maxAtlasSize = GetRealMaxAtlasSize(); + if (maxAtlasSize < oldMaxAtlasSize) + { + for (Atlas& atlas : m_atlases) + { + unsigned int atlasSize = atlas.binPack.GetWidth(); + if (atlasSize > maxAtlasSize) + { + NazaraWarning("At least one atlas was over new max atlas size (" + NzString::Number(atlasSize) + " > " + NzString::Number(maxAtlasSize) + "), clearing glyph cache..."); + ClearGlyphCache(); + return; + } + } + } +} + +void NzFont::SetMinimumStepSize(unsigned int minimumStepSize) +{ + #if NAZARA_UTILITY_SAFE + if (minimumStepSize == 0) + { + NazaraError("Minimum step size cannot be zero as it implies division by zero"); + return; + } + #endif + + m_minimumSizeStep = minimumStepSize; +} + +unsigned int NzFont::GetDefaultMaxAtlasSize() +{ + return s_maxAtlasSize; +} + +void NzFont::SetDefaultMaxAtlasSize(unsigned int maxAtlasSize) +{ + s_maxAtlasSize = maxAtlasSize; +} + +nzUInt64 NzFont::ComputeKey(unsigned int characterSize, nzUInt32 style) const +{ + nzUInt64 sizePart = static_cast((characterSize/m_minimumSizeStep)*m_minimumSizeStep); + nzUInt64 stylePart = 0; + + if (style & nzTextStyle_Bold) // Les caractères gras sont générés différemment + stylePart |= nzTextStyle_Bold; + + // Les caractères italiques peuvent venir d'une autre police, dans le cas contraire ils sont générés au runtime + //if (style & nzTextStyle_Italic) + // stylePart |= nzTextStyle_Italic; + + return (stylePart << 32) | sizePart; +} + +unsigned int NzFont::GetRealMaxAtlasSize() const +{ + unsigned int maxAtlasSize = (m_maxAtlasSize == 0) ? s_maxAtlasSize : m_maxAtlasSize; + if (maxAtlasSize == 0) + maxAtlasSize = std::numeric_limits::max(); + + return maxAtlasSize; +} + +unsigned int NzFont::InsertRect(NzRectui* rect, bool* flipped) const +{ + ///DOC: Tous les pointeurs doivent être valides + // Précondition: Un rectangle ne peut pas être plus grand dans une dimension que la taille maximale de l'atlas + + unsigned int maxAtlasSize = GetRealMaxAtlasSize(); + + // Cette fonction ne fait qu'insérer un rectangle de façon virtuelle, l'insertion des images se fait après + for (unsigned int i = 0; i < m_atlases.size(); ++i) + { + Atlas& atlas = m_atlases[i]; + if (atlas.binPack.Insert(rect, flipped, 1, false, NzGuillotineBinPack::RectBestAreaFit, NzGuillotineBinPack::SplitMinimizeArea)) + // Insertion réussie dans l'un des atlas, pas de question à se poser + return i; + else if (i == m_atlases.size() - 1) // Dernière itération ? + { + // Dernier atlas, et le glyphe ne rentre pas, peut-on agrandir la taille de l'atlas ? + unsigned int size = atlas.binPack.GetWidth(); // l'atlas étant carré, on ne teste qu'une dimension + if (size < maxAtlasSize) + { + // On peut encore agrandir l'atlas + size = std::min(size*2, maxAtlasSize); + atlas.binPack.Expand(size, size); + + // On relance la boucle sur le dernier atlas + i--; + } + else + { + // On ne peut plus agrandir le dernier atlas, il est temps d'en créer un nouveau + m_atlases.resize(m_atlases.size() + 1); + Atlas& newAtlas = m_atlases.back(); + + newAtlas.binPack.Reset(s_atlasStartSize, s_atlasStartSize); + + // On laisse la boucle insérer toute seule le rectangle à la prochaine itération + } + } + } + + // Si nous arrivons ici, c'est qu'une erreur a eu lieu en amont + NazaraInternalError("This shouldn't happen"); + return std::numeric_limits::max(); +} + +const NzFont::Glyph& NzFont::PrecacheGlyph(GlyphMap& glyphMap, unsigned int characterSize, bool bold, char32_t character) const +{ + auto it = glyphMap.find(character); + if (it != glyphMap.end()) // Si le glyphe n'est pas déjà chargé + return it->second; + + Glyph glyph; + glyph.valid = false; + + // On extrait le glyphe depuis la police + NzFontGlyph fontGlyph; + if (ExtractGlyph(characterSize, character, bold, &fontGlyph)) + { + glyph.atlasRect.width = fontGlyph.image.GetWidth(); + glyph.atlasRect.height = fontGlyph.image.GetHeight(); + + unsigned int maxAtlasSize = GetRealMaxAtlasSize(); + if (glyph.atlasRect.width <= maxAtlasSize && glyph.atlasRect.height <= maxAtlasSize) + { + // Insertion du rectangle dans l'un des atlas + glyph.aabb = fontGlyph.aabb; + glyph.advance = fontGlyph.advance; + glyph.valid = true; + + if (glyph.atlasRect.width > 0 && glyph.atlasRect.height > 0) // Si l'image contient quelque chose + { + // Padding (pour éviter le débordement lors du filtrage) + const unsigned int padding = 1; // Un pixel entre chaque glyphe + + glyph.atlasRect.width += padding; + glyph.atlasRect.height += padding; + + // Insertion du rectangle dans l'atlas virtuel + glyph.atlasIndex = InsertRect(&glyph.atlasRect, &glyph.flipped); + + glyph.atlasRect.width -= padding; + glyph.atlasRect.height -= padding; + + // Mise en queue pour insertion dans l'atlas réel + m_glyphQueue.resize(m_glyphQueue.size()+1); + QueuedGlyph& queuedGlyph = m_glyphQueue.back(); + queuedGlyph.codepoint = character; + queuedGlyph.image = std::move(fontGlyph.image); + queuedGlyph.map = &glyphMap; + } + } + else + { + NazaraWarning("Glyph \"" + NzString::Unicode(character) + "\" is bigger than max atlas size"); + } + } + else + { + NazaraWarning("Failed to extract glyph \"" + NzString::Unicode(character) + "\""); + } + + return glyphMap.insert(std::make_pair(character, std::move(glyph))).first->second; +} + +void NzFont::ProcessGlyphQueue() const +{ + for (QueuedGlyph& queuedGlyph : m_glyphQueue) + { + GlyphMap& glyphMap = *queuedGlyph.map; + auto glyphIt = glyphMap.find(queuedGlyph.codepoint); + if (glyphIt == glyphMap.end()) + continue; // Le glyphe a certainement été supprimé du cache avant la mise à jour de l'atlas + + Glyph& glyph = glyphIt->second; + Atlas& atlas = m_atlases[glyph.atlasIndex]; + + // On s'assure que l'atlas est de la bonne taille + NzVector2ui atlasSize(atlas.image.GetWidth(), atlas.image.GetHeight()); + NzVector2ui binPackSize = atlas.binPack.GetSize(); + if (atlasSize != binPackSize) + { + // Création d'une nouvelle image + NzImage newAtlas(nzImageType_2D, nzPixelFormat_A8, binPackSize.x, binPackSize.y); + if (atlas.image.IsValid()) + { + newAtlas.Copy(atlas.image, NzRectui(atlasSize), NzVector2ui(0, 0)); // On copie les anciennes données + + // On initialise les nouvelles régions + newAtlas.Fill(NzColor(255, 255, 255, 0), NzRectui(0, atlasSize.y, binPackSize.x, binPackSize.y - atlasSize.y)); + newAtlas.Fill(NzColor(255, 255, 255, 0), NzRectui(atlasSize.x, 0, binPackSize.x - atlasSize.x, atlasSize.y)); + } + else + newAtlas.Fill(NzColor(255, 255, 255, 0)); // On initialise les pixels + + atlas.image = std::move(newAtlas); // On déplace la nouvelle image vers l'atlas + } + + unsigned int glyphWidth = queuedGlyph.image.GetWidth(); + unsigned int glyphHeight = queuedGlyph.image.GetHeight(); + + // On copie le glyphe dans l'atlas + if (glyph.flipped) + { + // On tourne le glyphe pour qu'il rentre dans le rectangle + const nzUInt8* src = queuedGlyph.image.GetConstPixels(); + nzUInt8* ptr = atlas.image.GetPixels(glyph.atlasRect.x, glyph.atlasRect.y + glyphWidth - 1); + + unsigned int lineStride = atlas.image.GetWidth(); // BPP = 1 + for (unsigned int y = 0; y < glyphHeight; ++y) + { + for (unsigned int x = 0; x < glyphWidth; ++x) + { + *ptr = *src++; // On copie et on avance dans le glyphe + ptr -= lineStride; // On remonte d'une ligne + } + + ptr += lineStride*glyphWidth + 1; + } + } + else + atlas.image.Copy(queuedGlyph.image, NzRectui(glyphWidth, glyphHeight), glyph.atlasRect.GetPosition()); + + queuedGlyph.image.Destroy(); // On libère l'image dès que possible (pour réduire la consommation) + } + + m_glyphQueue.clear(); +} + +NzFontLoader::LoaderList NzFont::s_loaders; +unsigned int NzFont::s_maxAtlasSize = 8192; // Valeur totalement arbitraire diff --git a/src/Nazara/Utility/FontData.cpp b/src/Nazara/Utility/FontData.cpp new file mode 100644 index 000000000..a5f4b13bd --- /dev/null +++ b/src/Nazara/Utility/FontData.cpp @@ -0,0 +1,8 @@ +// Copyright (C) 2014 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 + +NzFontData::~NzFontData() = default; diff --git a/src/Nazara/Utility/Loaders/FreeType.hpp b/src/Nazara/Utility/Loaders/FreeType.hpp new file mode 100644 index 000000000..6ee1f60ab --- /dev/null +++ b/src/Nazara/Utility/Loaders/FreeType.hpp @@ -0,0 +1,15 @@ +// Copyright (C) 2014 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_LOADERS_FREETYPE_HPP +#define NAZARA_LOADERS_FREETYPE_HPP + +#include + +void NzLoaders_FreeType_Register(); +void NzLoaders_FreeType_Unregister(); + +#endif // NAZARA_LOADERS_FREETYPE_HPP diff --git a/src/Nazara/Utility/Loaders/FreeType/Loader.cpp b/src/Nazara/Utility/Loaders/FreeType/Loader.cpp new file mode 100644 index 000000000..71269d9da --- /dev/null +++ b/src/Nazara/Utility/Loaders/FreeType/Loader.cpp @@ -0,0 +1,393 @@ +// Copyright (C) 2014 Jérôme Leclercq - 2009 Cruden BV +// 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 FT_FREETYPE_H +#include FT_BITMAP_H +#include FT_OUTLINE_H +#include +#include +#include +#include +#include +#include +#include +#include + +namespace +{ + FT_Library s_library = nullptr; + float s_invScaleFactor = 1.f / (1 << 6); // 1/64 + + extern "C" + unsigned long FT_StreamRead(FT_Stream stream, unsigned long offset, unsigned char* buffer, unsigned long count) + { + // http://www.freetype.org/freetype2/docs/reference/ft2-system_interface.html#FT_Stream_IoFunc + NzInputStream& inputStream = *static_cast(stream->descriptor.pointer); + + // La valeur de count indique une opération de lecture ou de positionnement + if (count > 0) + { + // Dans le premier cas, une erreur est symbolisée par un retour nul + if (inputStream.SetCursorPos(offset)) + return static_cast(inputStream.Read(buffer, count)); + else + return 0; + } + else + { + // Dans le second cas, une erreur est symbolisée par un retour non-nul + if (inputStream.SetCursorPos(offset)) + return 0; + else + return 42; // La réponse à la grande question + } + } + + extern "C" + void FT_StreamClose(FT_Stream stream) + { + // http://www.freetype.org/freetype2/docs/reference/ft2-system_interface.html#FT_Stream_CloseFunc + // Les streams dans Nazara ne se ferment pas explicitement + NazaraUnused(stream); + } + + class FreeTypeStream : public NzFontData + { + public: + FreeTypeStream() : + m_face(nullptr), + m_characterSize(0) + { + } + + ~FreeTypeStream() + { + if (m_face) + FT_Done_Face(m_face); + } + + bool Check() + { + // Test d'ouverture (http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Open_Face) + return FT_Open_Face(s_library, &m_args, -1, nullptr) == 0; + } + + bool ExtractGlyph(unsigned int characterSize, char32_t character, bool bold, NzFontGlyph* dst) + { + #ifdef NAZARA_DEBUG + if (!dst) + { + NazaraError("Glyph destination cannot be null"); + return false; + } + #endif + + SetCharacterSize(characterSize); + + if (FT_Load_Char(m_face, character, FT_LOAD_FORCE_AUTOHINT | FT_LOAD_TARGET_NORMAL) != 0) + { + NazaraError("Failed to load character"); + return false; + } + + FT_GlyphSlot& glyph = m_face->glyph; + + const FT_Pos boldStrength = 1 << 6; + + bool outlineFormat = (glyph->format == FT_GLYPH_FORMAT_OUTLINE); + if (outlineFormat && bold) + // http://www.freetype.org/freetype2/docs/reference/ft2-outline_processing.html#FT_Outline_Embolden + FT_Outline_Embolden(&glyph->outline, boldStrength); + + // http://www.freetype.org/freetype2/docs/reference/ft2-glyph_management.html#FT_Glyph_To_Bitmap + // Conversion du glyphe vers le format bitmap + // Cette fonction ne fait rien dans le cas où le glyphe est déjà un bitmap + if (FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL) != 0) + { + NazaraError("Failed to convert glyph to bitmap"); + return false; + } + + // Dans le cas où nous voulons des caractères gras mais que nous n'avons pas pu agir plus tôt + // nous demandons à FreeType d'agir directement sur le bitmap généré + if (!outlineFormat && bold) + { + // http://www.freetype.org/freetype2/docs/reference/ft2-bitmap_handling.html#FT_Bitmap_Embolden + // "If you want to embolden the bitmap owned by a FT_GlyphSlot_Rec, you should call FT_GlyphSlot_Own_Bitmap on the slot first" + FT_GlyphSlot_Own_Bitmap(glyph); + FT_Bitmap_Embolden(s_library, &glyph->bitmap, boldStrength, boldStrength); + } + + dst->advance = glyph->metrics.horiAdvance >> 6; + if (bold) + dst->advance += boldStrength >> 6; + + dst->aabb.x = glyph->metrics.horiBearingX >> 6; + dst->aabb.y = -(glyph->metrics.horiBearingY >> 6); // Inversion du repère + dst->aabb.width = glyph->metrics.width >> 6; + dst->aabb.height = glyph->metrics.height >> 6; + + unsigned int width = glyph->bitmap.width; + unsigned int height = glyph->bitmap.rows; + + if (width > 0 && height > 0) + { + dst->image.Create(nzImageType_2D, nzPixelFormat_A8, width, height); + nzUInt8* pixels = dst->image.GetPixels(); + + const nzUInt8* data = glyph->bitmap.buffer; + + // Selon la documentation FreeType, le glyphe peut être encodé en format A8 (huit bits d'alpha par pixel) + // ou au format A1 (un bit d'alpha par pixel). + // Cependant dans un cas comme dans l'autre, il nous faut gérer le pitch (les données peuvent ne pas être contigues) + // ainsi que le padding dans le cas du format A1 (Chaque ligne prends un nombre fixe d'octets) + if (glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) + { + // Format A1 + for (unsigned int y = 0; y < height; ++y) + { + for (unsigned int x = 0; x < width; ++x) + *pixels++ = (data[x/8] & (1 << (7 - x%8)) ? 255 : 0); + + data += glyph->bitmap.pitch; + } + } + else + { + // Format A8 + if (glyph->bitmap.pitch == static_cast(width*sizeof(nzUInt8))) // Pouvons-nous copier directement ? + dst->image.Update(glyph->bitmap.buffer); + else + { + for (unsigned int y = 0; y < height; ++y) + { + std::memcpy(pixels, data, width*sizeof(nzUInt8)); + data += glyph->bitmap.pitch; + pixels += width*sizeof(nzUInt8); + } + } + } + } + else + dst->image.Destroy(); // On s'assure que l'image ne contient alors rien + + return true; + } + + NzString GetFamilyName() const + { + return m_face->family_name; + } + + NzString GetStyleName() const + { + return m_face->style_name; + } + + bool HasKerning() const + { + return FT_HAS_KERNING(m_face); + } + + bool IsScalable() const + { + return FT_IS_SCALABLE(m_face); + } + + bool Open() + { + return FT_Open_Face(s_library, &m_args, 0, &m_face) == 0; + } + + int QueryKerning(unsigned int characterSize, char32_t first, char32_t second) const + { + if (FT_HAS_KERNING(m_face)) + { + SetCharacterSize(characterSize); + + FT_Vector kerning; + FT_Get_Kerning(m_face, FT_Get_Char_Index(m_face, first), FT_Get_Char_Index(m_face, second), FT_KERNING_DEFAULT, &kerning); + + if (!FT_IS_SCALABLE(m_face)) + return kerning.x; // Taille déjà précisée en pixels dans ce cas + + return kerning.x >> 6; + } + else + return 0; + } + + unsigned int QueryLineHeight(unsigned int characterSize) const + { + SetCharacterSize(characterSize); + + // http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Size_Metrics + return m_face->size->metrics.height >> 6; + } + + float QueryUnderlinePosition(unsigned int characterSize) const + { + if (FT_IS_SCALABLE(m_face)) + { + SetCharacterSize(characterSize); + + // http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_FaceRec + return static_cast(FT_MulFix(m_face->underline_position, m_face->size->metrics.y_scale)) * s_invScaleFactor; + } + else + return characterSize / 10.f; // Joker ? + } + + float QueryUnderlineThickness(unsigned int characterSize) const + { + if (FT_IS_SCALABLE(m_face)) + { + SetCharacterSize(characterSize); + + // http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_FaceRec + return static_cast(FT_MulFix(m_face->underline_thickness, m_face->size->metrics.y_scale)) * s_invScaleFactor; + } + else + return characterSize/15.f; // Joker ? + } + + bool SetFile(const NzString& filePath) + { + if (!m_file.Open(filePath, NzFile::ReadOnly)) + { + NazaraError("Failed to open stream from file: " + NzError::GetLastError()); + return false; + } + + SetStream(m_file); + return true; + } + + void SetStream(NzInputStream& stream) + { + m_stream.base = nullptr; + m_stream.close = FT_StreamClose; + m_stream.descriptor.pointer = &stream; + m_stream.read = FT_StreamRead; + m_stream.pos = 0; + m_stream.size = stream.GetSize(); + + m_args.driver = 0; + m_args.flags = FT_OPEN_STREAM; + m_args.stream = &m_stream; + } + + private: + void SetCharacterSize(unsigned int characterSize) const + { + if (m_characterSize != characterSize) + { + FT_Set_Pixel_Sizes(m_face, 0, characterSize); + m_characterSize = characterSize; + } + } + + FT_Open_Args m_args; + FT_Face m_face; + FT_StreamRec m_stream; + NzFile m_file; + mutable unsigned int m_characterSize; + }; + + bool IsSupported(const NzString& extension) + { + ///FIXME: Je suppose qu'il en manque quelques uns.. + static std::set supportedExtensions = { + "afm", "bdf", "cff", "cid", "dfont", "fnt", "pfa", "pfb", "pfm", "pfr", "sfnt", "tte", "ttf" + }; + + return supportedExtensions.find(extension) != supportedExtensions.end(); + } + + nzTernary Check(NzInputStream& stream, const NzFontParams& parameters) + { + NazaraUnused(parameters); + + FreeTypeStream face; + face.SetStream(stream); + + if (face.Check()) + return nzTernary_True; + else + return nzTernary_False; + } + + bool LoadFile(NzFont* font, const NzString& filePath, const NzFontParams& parameters) + { + NazaraUnused(parameters); + + std::unique_ptr face(new FreeTypeStream); + + if (!face->SetFile(filePath)) + { + NazaraError("Failed to open file"); + return false; + } + + if (!face->Open()) + { + NazaraError("Failed to open face"); + return false; + } + + if (font->Create(face.get())) + { + face.release(); + return true; + } + else + return false; + } + + bool LoadStream(NzFont* font, NzInputStream& stream, const NzFontParams& parameters) + { + NazaraUnused(parameters); + + std::unique_ptr face(new FreeTypeStream); + face->SetStream(stream); + + if (!face->Open()) + { + NazaraError("Failed to open face"); + return false; + } + + if (font->Create(face.get())) + { + face.release(); + return true; + } + else + return false; + } +} + +void NzLoaders_FreeType_Register() +{ + if (FT_Init_FreeType(&s_library) == 0) + NzFontLoader::RegisterLoader(IsSupported, Check, LoadStream, LoadFile); + else + { + s_library = nullptr; // On s'assure que le pointeur ne pointe pas sur n'importe quoi + NazaraWarning("Failed to initialize FreeType library"); + } +} + +void NzLoaders_FreeType_Unregister() +{ + if (s_library) + { + NzFontLoader::UnregisterLoader(IsSupported, Check, LoadStream, LoadFile); + + FT_Done_FreeType(s_library); + s_library = nullptr; + } +} diff --git a/src/Nazara/Utility/Utility.cpp b/src/Nazara/Utility/Utility.cpp index 885e4a578..c12459277 100644 --- a/src/Nazara/Utility/Utility.cpp +++ b/src/Nazara/Utility/Utility.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -70,6 +71,9 @@ bool NzUtility::Initialize() // Il s'agit ici d'une liste LIFO, le dernier loader enregistré possède la priorité /// Loaders génériques + // Font + NzLoaders_FreeType_Register(); + // Image NzLoaders_STB_Register(); // Loader générique (STB) @@ -109,6 +113,7 @@ void NzUtility::Uninitialize() // Libération du module s_moduleReferenceCounter = 0; + NzLoaders_FreeType_Unregister(); NzLoaders_MD2_Unregister(); NzLoaders_MD5Anim_Unregister(); NzLoaders_MD5Mesh_Unregister(); From b3d72ec09407dcb3f17d8bb79cc3951d29bfe511 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 4 Jan 2015 18:16:31 +0100 Subject: [PATCH 115/233] Renamed BufferStorage enum to DataStorage Former-commit-id: 97eede03eb6bb85e506c640d40c9d6e7acb2e099 --- build/codeblocks/CppCheckResults.xml | 15 ++++++++++++++ include/Nazara/Utility/Buffer.hpp | 16 +++++++-------- include/Nazara/Utility/Enums.hpp | 18 ++++++++--------- include/Nazara/Utility/IndexBuffer.hpp | 6 +++--- include/Nazara/Utility/Mesh.hpp | 2 +- include/Nazara/Utility/VertexBuffer.hpp | 6 +++--- .../Graphics/ForwardRenderTechnique.cpp | 4 ++-- src/Nazara/Graphics/SkinningManager.cpp | 2 +- src/Nazara/Graphics/SkyboxBackground.cpp | 4 ++-- src/Nazara/Renderer/DebugDrawer.cpp | 2 +- src/Nazara/Renderer/Renderer.cpp | 6 +++--- src/Nazara/Utility/Buffer.cpp | 20 +++++++++---------- src/Nazara/Utility/IndexBuffer.cpp | 6 +++--- src/Nazara/Utility/Mesh.cpp | 2 +- src/Nazara/Utility/VertexBuffer.cpp | 6 +++--- 15 files changed, 65 insertions(+), 50 deletions(-) create mode 100644 build/codeblocks/CppCheckResults.xml diff --git a/build/codeblocks/CppCheckResults.xml b/build/codeblocks/CppCheckResults.xml new file mode 100644 index 000000000..8bd3586b0 --- /dev/null +++ b/build/codeblocks/CppCheckResults.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/include/Nazara/Utility/Buffer.hpp b/include/Nazara/Utility/Buffer.hpp index be48b34ad..a41e65e98 100644 --- a/include/Nazara/Utility/Buffer.hpp +++ b/include/Nazara/Utility/Buffer.hpp @@ -28,19 +28,19 @@ class NAZARA_API NzBuffer : public NzResource, NzNonCopyable using BufferFunction = NzAbstractBuffer* (*)(NzBuffer* parent, nzBufferType type); NzBuffer(nzBufferType type); - NzBuffer(nzBufferType type, unsigned int size, nzBufferStorage storage = nzBufferStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); + NzBuffer(nzBufferType type, unsigned int size, nzDataStorage storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); ~NzBuffer(); bool CopyContent(const NzBuffer& buffer); - bool Create(unsigned int size, nzBufferStorage storage = nzBufferStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); + bool Create(unsigned int size, nzDataStorage storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); void Destroy(); bool Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard = false); NzAbstractBuffer* GetImpl() const; unsigned int GetSize() const; - nzBufferStorage GetStorage() const; + nzDataStorage GetStorage() const; nzBufferType GetType() const; nzBufferUsage GetUsage() const; @@ -50,24 +50,24 @@ class NAZARA_API NzBuffer : public NzResource, NzNonCopyable void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0); void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0) const; - bool SetStorage(nzBufferStorage storage); + bool SetStorage(nzDataStorage storage); void Unmap() const; - static bool IsSupported(nzBufferStorage storage); - static void SetBufferFunction(nzBufferStorage storage, BufferFunction func); + static bool IsSupported(nzDataStorage storage); + static void SetBufferFunction(nzDataStorage storage, BufferFunction func); private: static bool Initialize(); static void Uninitialize(); - nzBufferStorage m_storage; nzBufferType m_type; nzBufferUsage m_usage; + nzDataStorage m_storage; NzAbstractBuffer* m_impl; unsigned int m_size; - static BufferFunction s_bufferFunctions[nzBufferStorage_Max+1]; + static BufferFunction s_bufferFunctions[nzDataStorage_Max+1]; }; #endif // NAZARA_BUFFER_HPP diff --git a/include/Nazara/Utility/Enums.hpp b/include/Nazara/Utility/Enums.hpp index 06e2a5c2a..6d0ec4f2a 100644 --- a/include/Nazara/Utility/Enums.hpp +++ b/include/Nazara/Utility/Enums.hpp @@ -25,15 +25,6 @@ enum nzBufferAccess nzBufferAccess_Max = nzBufferAccess_WriteOnly }; -enum nzBufferStorage -{ - //nzBufferStorage_Both, ///TODO - nzBufferStorage_Hardware, - nzBufferStorage_Software, - - nzBufferStorage_Max = nzBufferStorage_Software -}; - enum nzBufferType { nzBufferType_Index, @@ -84,6 +75,15 @@ enum nzCubemapFace nzCubemapFace_Max = nzCubemapFace_NegativeZ }; +enum nzDataStorage +{ + nzDataStorage_Both, + nzDataStorage_Hardware, + nzDataStorage_Software, + + nzDataStorage_Max = nzDataStorage_Software +}; + enum nzEventType { nzEventType_GainedFocus, diff --git a/include/Nazara/Utility/IndexBuffer.hpp b/include/Nazara/Utility/IndexBuffer.hpp index 3088a0fd1..3f7eb59d6 100644 --- a/include/Nazara/Utility/IndexBuffer.hpp +++ b/include/Nazara/Utility/IndexBuffer.hpp @@ -23,7 +23,7 @@ class NAZARA_API NzIndexBuffer : public NzResource NzIndexBuffer() = default; NzIndexBuffer(bool largeIndices, NzBuffer* buffer); NzIndexBuffer(bool largeIndices, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset); - NzIndexBuffer(bool largeIndices, unsigned int length, nzBufferStorage storage = nzBufferStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); + NzIndexBuffer(bool largeIndices, unsigned int length, nzDataStorage storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); NzIndexBuffer(const NzIndexBuffer& indexBuffer); NzIndexBuffer(NzIndexBuffer&& indexBuffer) noexcept; ~NzIndexBuffer(); @@ -54,11 +54,11 @@ class NAZARA_API NzIndexBuffer : public NzResource void Reset(); void Reset(bool largeIndices, NzBuffer* buffer); void Reset(bool largeIndices, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset); - void Reset(bool largeIndices, unsigned int length, nzBufferStorage storage = nzBufferStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); + void Reset(bool largeIndices, unsigned int length, nzDataStorage storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); void Reset(const NzIndexBuffer& indexBuffer); void Reset(NzIndexBuffer&& indexBuffer) noexcept; - bool SetStorage(nzBufferStorage storage); + bool SetStorage(nzDataStorage storage); void Unmap() const; diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp index 116bbc3e7..6f4f83c61 100644 --- a/include/Nazara/Utility/Mesh.hpp +++ b/include/Nazara/Utility/Mesh.hpp @@ -25,7 +25,7 @@ struct NAZARA_API NzMeshParams NzMeshParams(); // Vérifie que le storage par défaut est supporté (software autrement) // Si ceci sera le stockage utilisé par les buffers - nzBufferStorage storage = nzBufferStorage_Hardware; + nzDataStorage storage = nzDataStorage_Hardware; // La mise à l'échelle éventuelle que subira le mesh NzVector3f scale = NzVector3f::Unit(); diff --git a/include/Nazara/Utility/VertexBuffer.hpp b/include/Nazara/Utility/VertexBuffer.hpp index 6b009561d..6acada650 100644 --- a/include/Nazara/Utility/VertexBuffer.hpp +++ b/include/Nazara/Utility/VertexBuffer.hpp @@ -24,7 +24,7 @@ class NAZARA_API NzVertexBuffer : public NzResource NzVertexBuffer() = default; NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer); NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset); - NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzBufferStorage storage = nzBufferStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); + NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzDataStorage storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); NzVertexBuffer(const NzVertexBuffer& vertexBuffer); NzVertexBuffer(NzVertexBuffer&& vertexBuffer) noexcept; ~NzVertexBuffer(); @@ -50,11 +50,11 @@ class NAZARA_API NzVertexBuffer : public NzResource void Reset(); void Reset(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer); void Reset(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset); - void Reset(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzBufferStorage storage = nzBufferStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); + void Reset(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzDataStorage storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); void Reset(const NzVertexBuffer& vertexBuffer); void Reset(NzVertexBuffer&& vertexBuffer) noexcept; - bool SetStorage(nzBufferStorage storage); + bool SetStorage(nzDataStorage storage); void SetVertexDeclaration(const NzVertexDeclaration* vertexDeclaration); void Unmap() const; diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index bc962cc19..03cac541c 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -27,7 +27,7 @@ namespace NzIndexBuffer* BuildIndexBuffer() { - std::unique_ptr indexBuffer(new NzIndexBuffer(false, s_maxSprites*6, nzBufferStorage_Hardware, nzBufferUsage_Static)); + std::unique_ptr indexBuffer(new NzIndexBuffer(false, s_maxSprites*6, nzDataStorage_Hardware, nzBufferUsage_Static)); indexBuffer->SetPersistent(false); NzBufferMapper mapper(indexBuffer.get(), nzBufferAccess_WriteOnly); @@ -49,7 +49,7 @@ namespace } NzForwardRenderTechnique::NzForwardRenderTechnique() : -m_spriteBuffer(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Color_UV), s_maxSprites*4, nzBufferStorage_Hardware, nzBufferUsage_Dynamic), +m_spriteBuffer(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Color_UV), s_maxSprites*4, nzDataStorage_Hardware, nzBufferUsage_Dynamic), m_maxLightPassPerObject(3) { if (!s_indexBuffer) diff --git a/src/Nazara/Graphics/SkinningManager.cpp b/src/Nazara/Graphics/SkinningManager.cpp index 9200b1186..2e47fc11e 100644 --- a/src/Nazara/Graphics/SkinningManager.cpp +++ b/src/Nazara/Graphics/SkinningManager.cpp @@ -174,7 +174,7 @@ NzVertexBuffer* NzSkinningManager::GetBuffer(const NzSkeletalMesh* mesh, const N { std::unique_ptr vertexBuffer(new NzVertexBuffer); vertexBuffer->SetPersistent(false); - vertexBuffer->Reset(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Normal_UV_Tangent), mesh->GetVertexCount(), nzBufferStorage_Hardware, nzBufferUsage_Dynamic); + vertexBuffer->Reset(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Normal_UV_Tangent), mesh->GetVertexCount(), nzDataStorage_Hardware, nzBufferUsage_Dynamic); BufferData data({vertexBuffer.get(), true}); meshMap.insert(std::make_pair(mesh, data)); diff --git a/src/Nazara/Graphics/SkyboxBackground.cpp b/src/Nazara/Graphics/SkyboxBackground.cpp index d1d7b8ca3..76cbd7b08 100644 --- a/src/Nazara/Graphics/SkyboxBackground.cpp +++ b/src/Nazara/Graphics/SkyboxBackground.cpp @@ -21,7 +21,7 @@ namespace { NzIndexBuffer* BuildIndexBuffer() { - std::unique_ptr indexBuffer(new NzIndexBuffer(false, 36, nzBufferStorage_Hardware, nzBufferUsage_Static)); + std::unique_ptr indexBuffer(new NzIndexBuffer(false, 36, nzDataStorage_Hardware, nzBufferUsage_Static)); indexBuffer->SetPersistent(false); nzUInt16 indices[6*6] = @@ -155,7 +155,7 @@ namespace NzVertexBuffer* BuildVertexBuffer() { - std::unique_ptr vertexBuffer(new NzVertexBuffer(NzVertexDeclaration::Get(nzVertexLayout_XYZ), 8, nzBufferStorage_Hardware, nzBufferUsage_Static)); + std::unique_ptr vertexBuffer(new NzVertexBuffer(NzVertexDeclaration::Get(nzVertexLayout_XYZ), 8, nzDataStorage_Hardware, nzBufferUsage_Static)); vertexBuffer->SetPersistent(false); float vertices[8*(sizeof(float)*3)] = diff --git a/src/Nazara/Renderer/DebugDrawer.cpp b/src/Nazara/Renderer/DebugDrawer.cpp index 47c4388ef..5f7090a81 100644 --- a/src/Nazara/Renderer/DebugDrawer.cpp +++ b/src/Nazara/Renderer/DebugDrawer.cpp @@ -667,7 +667,7 @@ bool NzDebugDrawer::Initialize() try { NzErrorFlags flags(nzErrorFlag_ThrowException, true); - s_vertexBuffer.Reset(NzVertexDeclaration::Get(nzVertexLayout_XYZ), 65365, nzBufferStorage_Hardware, nzBufferUsage_Dynamic); + s_vertexBuffer.Reset(NzVertexDeclaration::Get(nzVertexLayout_XYZ), 65365, nzDataStorage_Hardware, nzBufferUsage_Dynamic); } catch (const std::exception& e) { diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index 28e0b5288..c96b1de9c 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -692,7 +692,7 @@ bool NzRenderer::Initialize() return false; } - NzBuffer::SetBufferFunction(nzBufferStorage_Hardware, [](NzBuffer* parent, nzBufferType type) -> NzAbstractBuffer* { return new NzHardwareBuffer(parent, type); } ); + NzBuffer::SetBufferFunction(nzDataStorage_Hardware, [](NzBuffer* parent, nzBufferType type) -> NzAbstractBuffer* { return new NzHardwareBuffer(parent, type); } ); for (unsigned int i = 0; i <= nzMatrixType_Max; ++i) { @@ -775,7 +775,7 @@ bool NzRenderer::Initialize() s_updateFlags = Update_Matrices | Update_Shader | Update_VAO; s_vertexBuffer = nullptr; - s_fullscreenQuadBuffer.Reset(NzVertexDeclaration::Get(nzVertexLayout_XY), 4, nzBufferStorage_Hardware, nzBufferUsage_Static); + s_fullscreenQuadBuffer.Reset(NzVertexDeclaration::Get(nzVertexLayout_XY), 4, nzDataStorage_Hardware, nzBufferUsage_Static); float vertices[4*2] = { @@ -796,7 +796,7 @@ bool NzRenderer::Initialize() try { NzErrorFlags errFlags(nzErrorFlag_ThrowException, true); - s_instanceBuffer.Reset(nullptr, NAZARA_RENDERER_INSTANCE_BUFFER_SIZE, nzBufferStorage_Hardware, nzBufferUsage_Dynamic); + s_instanceBuffer.Reset(nullptr, NAZARA_RENDERER_INSTANCE_BUFFER_SIZE, nzDataStorage_Hardware, nzBufferUsage_Dynamic); } catch (const std::exception& e) { diff --git a/src/Nazara/Utility/Buffer.cpp b/src/Nazara/Utility/Buffer.cpp index 18d4e0583..5fd1764b9 100644 --- a/src/Nazara/Utility/Buffer.cpp +++ b/src/Nazara/Utility/Buffer.cpp @@ -29,7 +29,7 @@ m_size(0) { } -NzBuffer::NzBuffer(nzBufferType type, unsigned int size, nzBufferStorage storage, nzBufferUsage usage) : +NzBuffer::NzBuffer(nzBufferType type, unsigned int size, nzDataStorage storage, nzBufferUsage usage) : m_type(type), m_impl(nullptr) { @@ -63,7 +63,7 @@ bool NzBuffer::CopyContent(const NzBuffer& buffer) return Fill(mapper.GetPointer(), 0, buffer.GetSize()); } -bool NzBuffer::Create(unsigned int size, nzBufferStorage storage, nzBufferUsage usage) +bool NzBuffer::Create(unsigned int size, nzDataStorage storage, nzBufferUsage usage) { Destroy(); @@ -131,7 +131,7 @@ unsigned int NzBuffer::GetSize() const return m_size; } -nzBufferStorage NzBuffer::GetStorage() const +nzDataStorage NzBuffer::GetStorage() const { return m_storage; } @@ -148,7 +148,7 @@ nzBufferUsage NzBuffer::GetUsage() const bool NzBuffer::IsHardware() const { - return m_storage == nzBufferStorage_Hardware; + return m_storage == nzDataStorage_Hardware; } bool NzBuffer::IsValid() const @@ -200,7 +200,7 @@ void* NzBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int siz return m_impl->Map(access, offset, (size == 0) ? m_size-offset : size); } -bool NzBuffer::SetStorage(nzBufferStorage storage) +bool NzBuffer::SetStorage(nzDataStorage storage) { #if NAZARA_UTILITY_SAFE if (!m_impl) @@ -272,26 +272,26 @@ void NzBuffer::Unmap() const NazaraWarning("Failed to unmap buffer (it's content is undefined)"); ///TODO: Unexpected ? } -bool NzBuffer::IsSupported(nzBufferStorage storage) +bool NzBuffer::IsSupported(nzDataStorage storage) { return s_bufferFunctions[storage] != nullptr; } -void NzBuffer::SetBufferFunction(nzBufferStorage storage, BufferFunction func) +void NzBuffer::SetBufferFunction(nzDataStorage storage, BufferFunction func) { s_bufferFunctions[storage] = func; } bool NzBuffer::Initialize() { - s_bufferFunctions[nzBufferStorage_Software] = SoftwareBufferFunction; + s_bufferFunctions[nzDataStorage_Software] = SoftwareBufferFunction; return true; } void NzBuffer::Uninitialize() { - std::memset(s_bufferFunctions, 0, (nzBufferStorage_Max+1)*sizeof(NzBuffer::BufferFunction)); + std::memset(s_bufferFunctions, 0, (nzDataStorage_Max+1)*sizeof(NzBuffer::BufferFunction)); } -NzBuffer::BufferFunction NzBuffer::s_bufferFunctions[nzBufferStorage_Max+1] = {0}; +NzBuffer::BufferFunction NzBuffer::s_bufferFunctions[nzDataStorage_Max+1] = {0}; diff --git a/src/Nazara/Utility/IndexBuffer.cpp b/src/Nazara/Utility/IndexBuffer.cpp index f96c220b8..65cc22757 100644 --- a/src/Nazara/Utility/IndexBuffer.cpp +++ b/src/Nazara/Utility/IndexBuffer.cpp @@ -24,7 +24,7 @@ NzIndexBuffer::NzIndexBuffer(bool largeIndices, NzBuffer* buffer, unsigned int s Reset(largeIndices, buffer, startOffset, endOffset); } -NzIndexBuffer::NzIndexBuffer(bool largeIndices, unsigned int length, nzBufferStorage storage, nzBufferUsage usage) +NzIndexBuffer::NzIndexBuffer(bool largeIndices, unsigned int length, nzDataStorage storage, nzBufferUsage usage) { NzErrorFlags(nzErrorFlag_ThrowException, true); Reset(largeIndices, length, storage, usage); @@ -220,7 +220,7 @@ void NzIndexBuffer::Reset(bool largeIndices, NzBuffer* buffer, unsigned int star m_startOffset = startOffset; } -void NzIndexBuffer::Reset(bool largeIndices, unsigned int length, nzBufferStorage storage, nzBufferUsage usage) +void NzIndexBuffer::Reset(bool largeIndices, unsigned int length, nzDataStorage storage, nzBufferUsage usage) { unsigned int stride = (largeIndices) ? sizeof(nzUInt32) : sizeof(nzUInt16); @@ -251,7 +251,7 @@ void NzIndexBuffer::Reset(NzIndexBuffer&& indexBuffer) noexcept m_startOffset = indexBuffer.m_startOffset; } -bool NzIndexBuffer::SetStorage(nzBufferStorage storage) +bool NzIndexBuffer::SetStorage(nzDataStorage storage) { return m_buffer->SetStorage(storage); } diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index 61427fa3d..bb588a7ae 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -26,7 +26,7 @@ NzMeshParams::NzMeshParams() { if (!NzBuffer::IsSupported(storage)) - storage = nzBufferStorage_Software; + storage = nzDataStorage_Software; } bool NzMeshParams::IsValid() const diff --git a/src/Nazara/Utility/VertexBuffer.cpp b/src/Nazara/Utility/VertexBuffer.cpp index 45c572fea..31af8c2e9 100644 --- a/src/Nazara/Utility/VertexBuffer.cpp +++ b/src/Nazara/Utility/VertexBuffer.cpp @@ -20,7 +20,7 @@ NzVertexBuffer::NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, NzB Reset(vertexDeclaration, buffer, startOffset, endOffset); } -NzVertexBuffer::NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzBufferStorage storage, nzBufferUsage usage) +NzVertexBuffer::NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzDataStorage storage, nzBufferUsage usage) { NzErrorFlags(nzErrorFlag_ThrowException, true); Reset(vertexDeclaration, length, storage, usage); @@ -230,7 +230,7 @@ void NzVertexBuffer::Reset(const NzVertexDeclaration* vertexDeclaration, NzBuffe m_vertexDeclaration = vertexDeclaration; } -void NzVertexBuffer::Reset(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzBufferStorage storage, nzBufferUsage usage) +void NzVertexBuffer::Reset(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzDataStorage storage, nzBufferUsage usage) { m_endOffset = length * ((vertexDeclaration) ? vertexDeclaration->GetStride() : 1); m_startOffset = 0; @@ -259,7 +259,7 @@ void NzVertexBuffer::Reset(NzVertexBuffer&& vertexBuffer) noexcept m_vertexDeclaration = std::move(vertexBuffer.m_vertexDeclaration); } -bool NzVertexBuffer::SetStorage(nzBufferStorage storage) +bool NzVertexBuffer::SetStorage(nzDataStorage storage) { return m_buffer->SetStorage(storage); } From d560975e096f9d1e35439c470a29d465c384e402 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 4 Jan 2015 18:23:06 +0100 Subject: [PATCH 116/233] Renamed (Set)BufferFunction to (Set)BufferFactory Former-commit-id: 6165dcd881716461a9886be6ce7fd6bb2b335ef0 --- include/Nazara/Utility/Buffer.hpp | 6 +++--- src/Nazara/Renderer/Renderer.cpp | 5 ++++- src/Nazara/Utility/Buffer.cpp | 23 +++++++++++------------ 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/include/Nazara/Utility/Buffer.hpp b/include/Nazara/Utility/Buffer.hpp index a41e65e98..1a24e4d9a 100644 --- a/include/Nazara/Utility/Buffer.hpp +++ b/include/Nazara/Utility/Buffer.hpp @@ -25,7 +25,7 @@ class NAZARA_API NzBuffer : public NzResource, NzNonCopyable friend class NzUtility; public: - using BufferFunction = NzAbstractBuffer* (*)(NzBuffer* parent, nzBufferType type); + using BufferFactory = NzAbstractBuffer* (*)(NzBuffer* parent, nzBufferType type); NzBuffer(nzBufferType type); NzBuffer(nzBufferType type, unsigned int size, nzDataStorage storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); @@ -55,7 +55,7 @@ class NAZARA_API NzBuffer : public NzResource, NzNonCopyable void Unmap() const; static bool IsSupported(nzDataStorage storage); - static void SetBufferFunction(nzDataStorage storage, BufferFunction func); + static void SetBufferFactory(nzDataStorage storage, BufferFactory func); private: static bool Initialize(); @@ -67,7 +67,7 @@ class NAZARA_API NzBuffer : public NzResource, NzNonCopyable NzAbstractBuffer* m_impl; unsigned int m_size; - static BufferFunction s_bufferFunctions[nzDataStorage_Max+1]; + static BufferFactory s_bufferFactories[nzDataStorage_Max+1]; }; #endif // NAZARA_BUFFER_HPP diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index c96b1de9c..9243f02a0 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -692,7 +692,10 @@ bool NzRenderer::Initialize() return false; } - NzBuffer::SetBufferFunction(nzDataStorage_Hardware, [](NzBuffer* parent, nzBufferType type) -> NzAbstractBuffer* { return new NzHardwareBuffer(parent, type); } ); + NzBuffer::SetBufferFactory(nzDataStorage_Hardware, [](NzBuffer* parent, nzBufferType type) -> NzAbstractBuffer* + { + return new NzHardwareBuffer(parent, type); + }); for (unsigned int i = 0; i <= nzMatrixType_Max; ++i) { diff --git a/src/Nazara/Utility/Buffer.cpp b/src/Nazara/Utility/Buffer.cpp index 5fd1764b9..e05a15db2 100644 --- a/src/Nazara/Utility/Buffer.cpp +++ b/src/Nazara/Utility/Buffer.cpp @@ -16,7 +16,7 @@ namespace { - NzAbstractBuffer* SoftwareBufferFunction(NzBuffer* parent, nzBufferType type) + NzAbstractBuffer* SoftwareBufferFactory(NzBuffer* parent, nzBufferType type) { return new NzSoftwareBuffer(parent, type); } @@ -59,7 +59,6 @@ bool NzBuffer::CopyContent(const NzBuffer& buffer) #endif NzBufferMapper mapper(buffer, nzBufferAccess_ReadOnly); - return Fill(mapper.GetPointer(), 0, buffer.GetSize()); } @@ -68,13 +67,13 @@ bool NzBuffer::Create(unsigned int size, nzDataStorage storage, nzBufferUsage us Destroy(); // Notre buffer est-il supporté ? - if (!s_bufferFunctions[storage]) + if (!IsSupported(storage)) { NazaraError("Buffer storage not supported"); return false; } - std::unique_ptr impl(s_bufferFunctions[storage](this, m_type)); + std::unique_ptr impl(s_bufferFactories[storage](this, m_type)); if (!impl->Create(size, usage)) { NazaraError("Failed to create buffer"); @@ -228,7 +227,7 @@ bool NzBuffer::SetStorage(nzDataStorage storage) return false; } - NzAbstractBuffer* impl = s_bufferFunctions[storage](this, m_type); + NzAbstractBuffer* impl = s_bufferFactories[storage](this, m_type); if (!impl->Create(m_size, m_usage)) { NazaraError("Failed to create buffer"); @@ -269,29 +268,29 @@ void NzBuffer::Unmap() const #endif if (!m_impl->Unmap()) - NazaraWarning("Failed to unmap buffer (it's content is undefined)"); ///TODO: Unexpected ? + NazaraWarning("Failed to unmap buffer (it's content may be undefined)"); ///TODO: Unexpected ? } bool NzBuffer::IsSupported(nzDataStorage storage) { - return s_bufferFunctions[storage] != nullptr; + return s_bufferFactories[storage] != nullptr; } -void NzBuffer::SetBufferFunction(nzDataStorage storage, BufferFunction func) +void NzBuffer::SetBufferFactory(nzDataStorage storage, BufferFactory func) { - s_bufferFunctions[storage] = func; + s_bufferFactories[storage] = func; } bool NzBuffer::Initialize() { - s_bufferFunctions[nzDataStorage_Software] = SoftwareBufferFunction; + s_bufferFactories[nzDataStorage_Software] = SoftwareBufferFactory; return true; } void NzBuffer::Uninitialize() { - std::memset(s_bufferFunctions, 0, (nzDataStorage_Max+1)*sizeof(NzBuffer::BufferFunction)); + std::memset(s_bufferFactories, 0, (nzDataStorage_Max+1)*sizeof(NzBuffer::BufferFactory)); } -NzBuffer::BufferFunction NzBuffer::s_bufferFunctions[nzDataStorage_Max+1] = {0}; +NzBuffer::BufferFactory NzBuffer::s_bufferFactories[nzDataStorage_Max+1] = {0}; From 911e10fa8408d0fedb3aaf1c583f0a97e75a5882 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 4 Jan 2015 18:30:50 +0100 Subject: [PATCH 117/233] Renamed Buffer::IsSupported to IsStorageSupported Former-commit-id: 12309ca590820fd68ab2b15a4c41ffb554832603 --- include/Nazara/Utility/Buffer.hpp | 2 +- src/Nazara/Utility/Buffer.cpp | 8 +++----- src/Nazara/Utility/Mesh.cpp | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/include/Nazara/Utility/Buffer.hpp b/include/Nazara/Utility/Buffer.hpp index 1a24e4d9a..b1b0b64b1 100644 --- a/include/Nazara/Utility/Buffer.hpp +++ b/include/Nazara/Utility/Buffer.hpp @@ -54,7 +54,7 @@ class NAZARA_API NzBuffer : public NzResource, NzNonCopyable void Unmap() const; - static bool IsSupported(nzDataStorage storage); + static bool IsStorageSupported(nzDataStorage storage); static void SetBufferFactory(nzDataStorage storage, BufferFactory func); private: diff --git a/src/Nazara/Utility/Buffer.cpp b/src/Nazara/Utility/Buffer.cpp index e05a15db2..c35f8bf70 100644 --- a/src/Nazara/Utility/Buffer.cpp +++ b/src/Nazara/Utility/Buffer.cpp @@ -67,7 +67,7 @@ bool NzBuffer::Create(unsigned int size, nzDataStorage storage, nzBufferUsage us Destroy(); // Notre buffer est-il supporté ? - if (!IsSupported(storage)) + if (!IsStorageSupported(storage)) { NazaraError("Buffer storage not supported"); return false; @@ -212,13 +212,11 @@ bool NzBuffer::SetStorage(nzDataStorage storage) if (m_storage == storage) return true; - #if NAZARA_UTILITY_SAFE - if (!IsSupported(storage)) + if (!IsStorageSupported(storage)) { NazaraError("Storage not supported"); return false; } - #endif void* ptr = m_impl->Map(nzBufferAccess_ReadOnly, 0, m_size); if (!ptr) @@ -271,7 +269,7 @@ void NzBuffer::Unmap() const NazaraWarning("Failed to unmap buffer (it's content may be undefined)"); ///TODO: Unexpected ? } -bool NzBuffer::IsSupported(nzDataStorage storage) +bool NzBuffer::IsStorageSupported(nzDataStorage storage) { return s_bufferFactories[storage] != nullptr; } diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index bb588a7ae..ee6489dfc 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -25,13 +25,13 @@ NzMeshParams::NzMeshParams() { - if (!NzBuffer::IsSupported(storage)) + if (!NzBuffer::IsStorageSupported(storage)) storage = nzDataStorage_Software; } bool NzMeshParams::IsValid() const { - if (!NzBuffer::IsSupported(storage)) + if (!NzBuffer::IsStorageSupported(storage)) { NazaraError("Storage not supported"); return false; From 0f033eaed974eb3a5b54b1b9ee66a4b572aab38f Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 4 Jan 2015 18:57:01 +0100 Subject: [PATCH 118/233] Added CallOnExit::CallAndReset() Former-commit-id: 045ff61445203999757971deeeafee719fc5506a --- include/Nazara/Core/CallOnExit.hpp | 1 + include/Nazara/Core/CallOnExit.inl | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/include/Nazara/Core/CallOnExit.hpp b/include/Nazara/Core/CallOnExit.hpp index 3f8fc1f2f..45ea2622d 100644 --- a/include/Nazara/Core/CallOnExit.hpp +++ b/include/Nazara/Core/CallOnExit.hpp @@ -19,6 +19,7 @@ class NzCallOnExit : NzNonCopyable NzCallOnExit(Func func = nullptr); ~NzCallOnExit(); + void CallAndReset(Func func = nullptr); void Reset(Func func = nullptr); private: diff --git a/include/Nazara/Core/CallOnExit.inl b/include/Nazara/Core/CallOnExit.inl index 00960f3ac..fd7f4de80 100644 --- a/include/Nazara/Core/CallOnExit.inl +++ b/include/Nazara/Core/CallOnExit.inl @@ -2,6 +2,7 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include inline NzCallOnExit::NzCallOnExit(Func func) : @@ -15,6 +16,14 @@ inline NzCallOnExit::~NzCallOnExit() m_func(); } +inline void NzCallOnExit::CallAndReset(Func func) +{ + if (m_func) + m_func(); + + Reset(func); +} + inline void NzCallOnExit::Reset(Func func) { m_func = func; From 0d143a64a2f3c108fef9f0c4b25e8cd81eb4d8f7 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 4 Jan 2015 19:02:35 +0100 Subject: [PATCH 119/233] Made Buffer::SetStorage exception-safe Former-commit-id: 46e9f9416aa3bd93e130f784a42d23533ec60dea --- src/Nazara/Utility/Buffer.cpp | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/Nazara/Utility/Buffer.cpp b/src/Nazara/Utility/Buffer.cpp index c35f8bf70..71b568f5b 100644 --- a/src/Nazara/Utility/Buffer.cpp +++ b/src/Nazara/Utility/Buffer.cpp @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include #include @@ -225,31 +226,36 @@ bool NzBuffer::SetStorage(nzDataStorage storage) return false; } - NzAbstractBuffer* impl = s_bufferFactories[storage](this, m_type); + NzCallOnExit unmapMyImpl([this]() + { + m_impl->Unmap(); + }); + + std::unique_ptr impl(s_bufferFactories[storage](this, m_type)); if (!impl->Create(m_size, m_usage)) { NazaraError("Failed to create buffer"); - delete impl; - m_impl->Unmap(); - return false; } + NzCallOnExit destroyImpl([&impl]() + { + impl->Destroy(); + }); + if (!impl->Fill(ptr, 0, m_size)) { NazaraError("Failed to fill buffer"); - impl->Destroy(); - delete impl; - m_impl->Unmap(); - return false; } - m_impl->Unmap(); + destroyImpl.Reset(); + + unmapMyImpl.CallAndReset(); m_impl->Destroy(); delete m_impl; - m_impl = impl; + m_impl = impl.release(); m_storage = storage; return true; From 5daf09e41b81039ece23fe6ba9010dc1e6ce5985 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 5 Jan 2015 02:32:57 +0100 Subject: [PATCH 120/233] Added OpenGL-like Vector constructors Former-commit-id: 302389b6a915d66a0a0fb4cc9a748ed5266ae98c --- include/Nazara/Math/Vector2.hpp | 7 ++++ include/Nazara/Math/Vector2.inl | 30 +++++++++++++ include/Nazara/Math/Vector3.hpp | 11 ++++- include/Nazara/Math/Vector3.inl | 32 ++++++++++++++ include/Nazara/Math/Vector4.hpp | 17 ++++++-- include/Nazara/Math/Vector4.inl | 74 +++++++++++++++++++++++++++++++-- 6 files changed, 163 insertions(+), 8 deletions(-) diff --git a/include/Nazara/Math/Vector2.hpp b/include/Nazara/Math/Vector2.hpp index 357babaa5..53850c631 100644 --- a/include/Nazara/Math/Vector2.hpp +++ b/include/Nazara/Math/Vector2.hpp @@ -9,6 +9,9 @@ #include +template class NzVector3; +template class NzVector4; + template class NzVector2 { @@ -19,6 +22,8 @@ class NzVector2 NzVector2(const T vec[2]); template explicit NzVector2(const NzVector2& vec); NzVector2(const NzVector2& vec) = default; + explicit NzVector2(const NzVector3& vec); + explicit NzVector2(const NzVector4& vec); ~NzVector2() = default; T AbsDotProduct(const NzVector2& vec) const; @@ -48,6 +53,8 @@ class NzVector2 NzVector2& Set(T scale); NzVector2& Set(const T vec[2]); NzVector2& Set(const NzVector2& vec); + NzVector2& Set(const NzVector3& vec); + NzVector2& Set(const NzVector4& vec); template NzVector2& Set(const NzVector2& vec); T SquaredDistance(const NzVector2& vec) const; diff --git a/include/Nazara/Math/Vector2.inl b/include/Nazara/Math/Vector2.inl index 227d95425..f97786610 100644 --- a/include/Nazara/Math/Vector2.inl +++ b/include/Nazara/Math/Vector2.inl @@ -36,6 +36,18 @@ NzVector2::NzVector2(const NzVector2& vec) Set(vec); } +template +NzVector2::NzVector2(const NzVector3& vec) +{ + Set(vec); +} + +template +NzVector2::NzVector2(const NzVector4& vec) +{ + Set(vec); +} + template T NzVector2::AbsDotProduct(const NzVector2& vec) const { @@ -208,6 +220,24 @@ NzVector2& NzVector2::Set(const NzVector2& vec) return *this; } +template +NzVector2& NzVector2::Set(const NzVector3& vec) +{ + x = vec.x; + y = vec.y; + + return *this; +} + +template +NzVector2& NzVector2::Set(const NzVector4& vec) +{ + x = vec.x; + y = vec.y; + + return *this; +} + template T NzVector2::SquaredDistance(const NzVector2& vec) const { diff --git a/include/Nazara/Math/Vector3.hpp b/include/Nazara/Math/Vector3.hpp index 875662270..e8fe8f7d0 100644 --- a/include/Nazara/Math/Vector3.hpp +++ b/include/Nazara/Math/Vector3.hpp @@ -8,18 +8,23 @@ #define NAZARA_VECTOR3_HPP #include -#include -template class NzVector3 +template class NzVector2; +template class NzVector4; + +template +class NzVector3 { public: NzVector3() = default; NzVector3(T X, T Y, T Z); + NzVector3(T X, const NzVector2& vec); explicit NzVector3(T scale); NzVector3(const T vec[3]); NzVector3(const NzVector2& vec, T Z = 0.0); template explicit NzVector3(const NzVector3& vec); NzVector3(const NzVector3& vec) = default; + explicit NzVector3(const NzVector4& vec); ~NzVector3() = default; T AbsDotProduct(const NzVector3& vec) const; @@ -56,11 +61,13 @@ template class NzVector3 NzVector3& Normalize(T* length = nullptr); NzVector3& Set(T X, T Y, T Z); + NzVector3& Set(T X, const NzVector2& vec); NzVector3& Set(T scale); NzVector3& Set(const T vec[3]); NzVector3& Set(const NzVector2& vec, T Z = 0.0); NzVector3& Set(const NzVector3& vec); template NzVector3& Set(const NzVector3& vec); + NzVector3& Set(const NzVector4& vec); T SquaredDistance(const NzVector3& vec) const; diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index f300330b8..fb395a748 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -17,6 +17,12 @@ NzVector3::NzVector3(T X, T Y, T Z) Set(X, Y, Z); } +template +NzVector3::NzVector3(T X, const NzVector2& vec) +{ + Set(X, vec); +} + template NzVector3::NzVector3(T scale) { @@ -42,6 +48,12 @@ NzVector3::NzVector3(const NzVector3& vec) Set(vec); } +template +NzVector3::NzVector3(const NzVector4& vec) +{ + Set(vec); +} + template T NzVector3::AbsDotProduct(const NzVector3& vec) const { @@ -255,6 +267,16 @@ NzVector3& NzVector3::Set(T X, T Y, T Z) return *this; } +template +NzVector3& NzVector3::Set(T X, const NzVector2& vec) +{ + x = X; + y = vec.x; + z = vec.y; + + return *this; +} + template NzVector3& NzVector3::Set(T scale) { @@ -302,6 +324,16 @@ NzVector3& NzVector3::Set(const NzVector3& vec) return *this; } +template +NzVector3& NzVector3::Set(const NzVector4& vec) +{ + x = vec.x; + y = vec.y; + z = vec.z; + + return *this; +} + template T NzVector3::SquaredDistance(const NzVector3& vec) const { diff --git a/include/Nazara/Math/Vector4.hpp b/include/Nazara/Math/Vector4.hpp index 5b71081d8..7bad9b918 100644 --- a/include/Nazara/Math/Vector4.hpp +++ b/include/Nazara/Math/Vector4.hpp @@ -8,16 +8,23 @@ #define NAZARA_VECTOR4_HPP #include -#include -template class NzVector4 +template class NzVector2; +template class NzVector3; + +template +class NzVector4 { public: NzVector4() = default; NzVector4(T X, T Y, T Z, T W = 1.0); + NzVector4(T X, T Y, const NzVector2& vec); + NzVector4(T X, const NzVector2& vec, T W); + NzVector4(T X, const NzVector3& vec); explicit NzVector4(T scale); NzVector4(const T vec[4]); - NzVector4(const NzVector3& vec, T W = 1.0); + NzVector4(const NzVector2& vec, T Z = 0.0, T W = 1.0); + NzVector4(const NzVector3& vec, T W = 0.0); template explicit NzVector4(const NzVector4& vec); NzVector4(const NzVector4& vec) = default; ~NzVector4() = default; @@ -39,8 +46,12 @@ template class NzVector4 NzVector4& Normalize(T* length = nullptr); NzVector4& Set(T X, T Y, T Z, T W = 1.0); + NzVector4& Set(T X, T Y, const NzVector2& vec); + NzVector4& Set(T X, const NzVector2& vec, T W); + NzVector4& Set(T X, const NzVector3& vec); NzVector4& Set(T scale); NzVector4& Set(const T vec[4]); + NzVector4& Set(const NzVector2& vec, T Z = 0.0, T W = 1.0); NzVector4& Set(const NzVector3& vec, T W = 1.0); NzVector4& Set(const NzVector4& vec); template NzVector4& Set(const NzVector4& vec); diff --git a/include/Nazara/Math/Vector4.inl b/include/Nazara/Math/Vector4.inl index 2f6002fbc..c1d7f4d1c 100644 --- a/include/Nazara/Math/Vector4.inl +++ b/include/Nazara/Math/Vector4.inl @@ -18,6 +18,24 @@ NzVector4::NzVector4(T X, T Y, T Z, T W) Set(X, Y, Z, W); } +template +NzVector4::NzVector4(T X, T Y, const NzVector2& vec) +{ + Set(X, Y, vec); +} + +template +NzVector4::NzVector4(T X, const NzVector2& vec, T W) +{ + Set(X, vec, W); +} + +template +NzVector4::NzVector4(T X, const NzVector3& vec) +{ + Set(X, vec); +} + template NzVector4::NzVector4(T scale) { @@ -30,6 +48,12 @@ NzVector4::NzVector4(const T vec[4]) Set(vec); } +template +NzVector4::NzVector4(const NzVector2& vec, T Z, T W) +{ + Set(vec, Z, W); +} + template NzVector4::NzVector4(const NzVector3& vec, T W) { @@ -155,10 +179,43 @@ NzVector4& NzVector4::Normalize(T* length) template NzVector4& NzVector4::Set(T X, T Y, T Z, T W) { - w = W; x = X; y = Y; z = Z; + w = W; + + return *this; +} + +template +NzVector4& NzVector4::Set(T X, T Y, const NzVector2& vec) +{ + x = X; + y = Y; + z = vec.x; + w = vec.y; + + return *this; +} + +template +NzVector4& NzVector4::Set(T X, const NzVector2& vec, T W) +{ + x = X; + y = vec.x; + z = vec.y; + w = W; + + return *this; +} + +template +NzVector4& NzVector4::Set(T X, const NzVector3& vec) +{ + x = X; + y = vec.x; + z = vec.y; + w = vec.z; return *this; } @@ -166,10 +223,10 @@ NzVector4& NzVector4::Set(T X, T Y, T Z, T W) template NzVector4& NzVector4::Set(T scale) { - w = scale; x = scale; y = scale; z = scale; + w = scale; return *this; } @@ -182,6 +239,17 @@ NzVector4& NzVector4::Set(const T vec[4]) return *this; } +template +NzVector4& NzVector4::Set(const NzVector2& vec, T Z, T W) +{ + x = vec.x; + y = vec.y; + z = Z; + w = W; + + return *this; +} + template NzVector4& NzVector4::Set(const NzVector3& vec, T W) { @@ -205,10 +273,10 @@ template template NzVector4& NzVector4::Set(const NzVector4& vec) { - w = F(vec.w); x = F(vec.x); y = F(vec.y); z = F(vec.z); + w = F(vec.w); return *this; } From b2b18a9f5124f0971ae3024132cbbfb8098e71dd Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 5 Jan 2015 13:41:56 +0100 Subject: [PATCH 121/233] Added Image::GetSize (returning the image's dimensions) Renamed original Image::GetSize to GetMemoryImage Former-commit-id: a2b54f171353b8197639b5f2b3911e4b3f2a8db2 --- include/Nazara/Utility/Image.hpp | 5 +- src/Nazara/Utility/Image.cpp | 83 ++++++++++++++++++-------------- 2 files changed, 51 insertions(+), 37 deletions(-) diff --git a/include/Nazara/Utility/Image.hpp b/include/Nazara/Utility/Image.hpp index 21cefa6b3..f59811d40 100644 --- a/include/Nazara/Utility/Image.hpp +++ b/include/Nazara/Utility/Image.hpp @@ -75,10 +75,11 @@ class NAZARA_API NzImage : public NzResource unsigned int GetHeight(nzUInt8 level = 0) const; nzUInt8 GetLevelCount() const; nzUInt8 GetMaxLevel() const; + unsigned int GetMemoryUsage() const; + unsigned int GetMemoryUsage(nzUInt8 level) const; NzColor GetPixelColor(unsigned int x, unsigned int y = 0, unsigned int z = 0) const; nzUInt8* GetPixels(unsigned int x = 0, unsigned int y = 0, unsigned int z = 0, nzUInt8 level = 0); - unsigned int GetSize() const; - unsigned int GetSize(nzUInt8 level) const; + NzVector3ui GetSize(nzUInt8 level = 0) const; nzImageType GetType() const; unsigned int GetWidth(nzUInt8 level = 0) const; diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index 7dc412dc8..4f7aabc9a 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -680,6 +680,49 @@ nzUInt8 NzImage::GetMaxLevel() const return GetMaxLevel(m_sharedImage->type, m_sharedImage->width, m_sharedImage->height, m_sharedImage->depth); } +unsigned int NzImage::GetMemoryUsage() const +{ + unsigned int width = m_sharedImage->width; + unsigned int height = m_sharedImage->height; + unsigned int depth = m_sharedImage->depth; + + unsigned int size = 0; + for (unsigned int i = 0; i < m_sharedImage->levelCount; ++i) + { + size += width * height * depth; + + if (width > 1) + width >>= 1; + + if (height > 1) + height >>= 1; + + if (depth > 1) + depth >>= 1; + } + + if (m_sharedImage->type == nzImageType_Cubemap) + size *= 6; + + return size * NzPixelFormat::GetBytesPerPixel(m_sharedImage->format); +} + +unsigned int NzImage::GetMemoryUsage(nzUInt8 level) const +{ + #if NAZARA_UTILITY_SAFE + if (level >= m_sharedImage->levelCount) + { + NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')'); + return 0; + } + #endif + + return (GetLevelSize(m_sharedImage->width, level)) * + (GetLevelSize(m_sharedImage->height, level)) * + ((m_sharedImage->type == nzImageType_Cubemap) ? 6 : GetLevelSize(m_sharedImage->depth, level)) * + NzPixelFormat::GetBytesPerPixel(m_sharedImage->format); +} + NzColor NzImage::GetPixelColor(unsigned int x, unsigned int y, unsigned int z) const { #if NAZARA_UTILITY_SAFE @@ -776,34 +819,7 @@ nzUInt8* NzImage::GetPixels(unsigned int x, unsigned int y, unsigned int z, nzUI return GetPixelPtr(m_sharedImage->pixels[level], NzPixelFormat::GetBytesPerPixel(m_sharedImage->format), x, y, z, width, height); } -unsigned int NzImage::GetSize() const -{ - unsigned int width = m_sharedImage->width; - unsigned int height = m_sharedImage->height; - unsigned int depth = m_sharedImage->depth; - - unsigned int size = 0; - for (unsigned int i = 0; i < m_sharedImage->levelCount; ++i) - { - size += width * height * depth; - - if (width > 1) - width >>= 1; - - if (height > 1) - height >>= 1; - - if (depth > 1) - depth >>= 1; - } - - if (m_sharedImage->type == nzImageType_Cubemap) - size *= 6; - - return size * NzPixelFormat::GetBytesPerPixel(m_sharedImage->format); -} - -unsigned int NzImage::GetSize(nzUInt8 level) const +NzVector3ui NzImage::GetSize(nzUInt8 level) const { #if NAZARA_UTILITY_SAFE if (level >= m_sharedImage->levelCount) @@ -813,10 +829,7 @@ unsigned int NzImage::GetSize(nzUInt8 level) const } #endif - return (GetLevelSize(m_sharedImage->width, level)) * - (GetLevelSize(m_sharedImage->height, level)) * - ((m_sharedImage->type == nzImageType_Cubemap) ? 6 : GetLevelSize(m_sharedImage->depth, level)) * - NzPixelFormat::GetBytesPerPixel(m_sharedImage->format); + return NzVector3ui(GetLevelSize(m_sharedImage->width, level), GetLevelSize(m_sharedImage->height, level), GetLevelSize(m_sharedImage->depth, level)); } nzImageType NzImage::GetType() const @@ -1122,7 +1135,7 @@ void NzImage::SetLevelCount(nzUInt8 levelCount) nzUInt8 oldLevelCount = m_sharedImage->levelCount; nzUInt8 maxLevelCount = std::max(levelCount, oldLevelCount); - m_sharedImage->levelCount = levelCount; // Pour faire fonctionner GetSize + m_sharedImage->levelCount = levelCount; // Pour faire fonctionner GetMemoryUsage nzUInt8** pixels = new nzUInt8*[levelCount]; for (unsigned int i = 0; i < maxLevelCount; ++i) @@ -1130,7 +1143,7 @@ void NzImage::SetLevelCount(nzUInt8 levelCount) if (i < oldLevelCount) pixels[i] = m_sharedImage->pixels[i]; else if (i < levelCount) - pixels[i] = new nzUInt8[GetSize(i)]; + pixels[i] = new nzUInt8[GetMemoryUsage(i)]; else delete[] m_sharedImage->pixels[i]; } @@ -1434,7 +1447,7 @@ void NzImage::EnsureOwnership() nzUInt8** pixels = new nzUInt8*[m_sharedImage->levelCount]; for (unsigned int i = 0; i < m_sharedImage->levelCount; ++i) { - unsigned int size = GetSize(i); + unsigned int size = GetMemoryUsage(i); pixels[i] = new nzUInt8[size]; std::memcpy(pixels[i], m_sharedImage->pixels[i], size); } From d13ab1a0506a466dc5790c1c01544b29e1f51298 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 5 Jan 2015 13:51:46 +0100 Subject: [PATCH 122/233] (Texture) Reflected Image interface (size getters) Former-commit-id: 4d979671c7b49191fb44b5fae7e9bfb266cd1417 --- include/Nazara/Renderer/Texture.hpp | 8 +++--- src/Nazara/Renderer/Texture.cpp | 43 +++++++++++++++++------------ 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/include/Nazara/Renderer/Texture.hpp b/include/Nazara/Renderer/Texture.hpp index f78feb490..816c6b1e5 100644 --- a/include/Nazara/Renderer/Texture.hpp +++ b/include/Nazara/Renderer/Texture.hpp @@ -43,12 +43,12 @@ class NAZARA_API NzTexture : public NzResource, NzNonCopyable void EnsureMipmapsUpdate() const; nzUInt8 GetBytesPerPixel() const; - unsigned int GetDepth() const; + unsigned int GetDepth(nzUInt8 level = 0) const; nzPixelFormat GetFormat() const; - unsigned int GetHeight() const; - NzVector2ui GetSize() const; + unsigned int GetHeight(nzUInt8 level = 0) const; + NzVector3ui GetSize(nzUInt8 level = 0) const; nzImageType GetType() const; - unsigned int GetWidth() const; + unsigned int GetWidth(nzUInt8 level = 0) const; bool HasMipmaps() const; diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index 9605244c4..e080bab0a 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -29,6 +29,12 @@ struct NzTextureImpl namespace { + inline unsigned int GetLevelSize(unsigned int size, nzUInt8 level) + { + // Contrairement à la classe Image, un appel à GetLevelSize(0, level) n'est pas possible + return std::max(size >> level, 1U); + } + inline void SetUnpackAlignement(nzUInt8 bpp) { if (bpp % 8 == 0) @@ -113,7 +119,7 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt if (depth > 1) { - NazaraError("1D textures must be 1 depth"); + NazaraError("1D textures must be 1 deep"); return false; } break; @@ -122,7 +128,7 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt case nzImageType_2D: if (depth > 1) { - NazaraError("2D textures must be 1 depth"); + NazaraError("2D textures must be 1 deep"); return false; } break; @@ -134,7 +140,7 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt case nzImageType_Cubemap: if (depth > 1) { - NazaraError("Cubemaps must be 1 depth"); + NazaraError("Cubemaps must be 1 deep"); return false; } @@ -320,7 +326,7 @@ nzUInt8 NzTexture::GetBytesPerPixel() const return NzPixelFormat::GetBytesPerPixel(m_impl->format); } -unsigned int NzTexture::GetDepth() const +unsigned int NzTexture::GetDepth(nzUInt8 level) const { #if NAZARA_RENDERER_SAFE if (!m_impl) @@ -330,7 +336,7 @@ unsigned int NzTexture::GetDepth() const } #endif - return m_impl->depth; + return GetLevelSize(m_impl->depth, level); } nzPixelFormat NzTexture::GetFormat() const @@ -346,7 +352,7 @@ nzPixelFormat NzTexture::GetFormat() const return m_impl->format; } -unsigned int NzTexture::GetHeight() const +unsigned int NzTexture::GetHeight(nzUInt8 level) const { #if NAZARA_RENDERER_SAFE if (!m_impl) @@ -356,20 +362,20 @@ unsigned int NzTexture::GetHeight() const } #endif - return m_impl->height; + return GetLevelSize(m_impl->height, level); } -NzVector2ui NzTexture::GetSize() const +NzVector3ui NzTexture::GetSize(nzUInt8 level) const { #if NAZARA_RENDERER_SAFE if (!m_impl) { NazaraError("Texture must be valid"); - return NzVector2ui(0, 0); + return NzVector3ui(0, 0, 0); } #endif - return NzVector2ui(m_impl->width, m_impl->height); + return NzVector3ui(GetLevelSize(m_impl->width, level), GetLevelSize(m_impl->height, level), GetLevelSize(m_impl->depth, level)); } nzImageType NzTexture::GetType() const @@ -385,7 +391,7 @@ nzImageType NzTexture::GetType() const return m_impl->type; } -unsigned int NzTexture::GetWidth() const +unsigned int NzTexture::GetWidth(nzUInt8 level) const { #if NAZARA_RENDERER_SAFE if (!m_impl) @@ -395,7 +401,7 @@ unsigned int NzTexture::GetWidth() const } #endif - return m_impl->width; + return GetLevelSize(m_impl->width, level); } bool NzTexture::HasMipmaps() const @@ -470,6 +476,7 @@ bool NzTexture::LoadFromImage(const NzImage& image, bool generateMipmaps) nzPixelFormat format = newImage.GetFormat(); if (!IsFormatSupported(format)) { + ///TODO: Sélectionner le format le plus adapté selon les composantes présentes dans le premier format nzPixelFormat newFormat = (NzPixelFormat::HasAlpha(format)) ? nzPixelFormat_BGRA8 : nzPixelFormat_BGR8; NazaraWarning("Format " + NzPixelFormat::ToString(format) + " not supported, trying to convert it to " + NzPixelFormat::ToString(newFormat) + "..."); @@ -889,7 +896,7 @@ bool NzTexture::Update(const nzUInt8* pixels, unsigned int srcWidth, unsigned in } #endif - return Update(pixels, NzBoxui(std::max(m_impl->width >> level, 1U), std::max(m_impl->height >> level, 1U), std::max(m_impl->depth >> level, 1U)), srcWidth, srcHeight, level); + return Update(pixels, NzBoxui(GetLevelSize(m_impl->width, level), GetLevelSize(m_impl->height, level), GetLevelSize(m_impl->depth, level)), srcWidth, srcHeight, level); } bool NzTexture::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int srcWidth, unsigned int srcHeight, nzUInt8 level) @@ -920,12 +927,12 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int s } #endif - unsigned int height = std::max(m_impl->height >> level, 1U); + unsigned int height = GetLevelSize(m_impl->height, level); #if NAZARA_RENDERER_SAFE - if (box.x+box.width > std::max(m_impl->width >> level, 1U) || + if (box.x+box.width > GetLevelSize(m_impl->width, level) || box.y+box.height > height || - box.z+box.depth > std::max(m_impl->depth >> level, 1U)) + box.z+box.depth > GetLevelSize(m_impl->depth, level)) { NazaraError("Cube dimensions are out of bounds"); return false; @@ -1058,10 +1065,10 @@ bool NzTexture::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRe } #endif - unsigned int height = std::max(m_impl->height >> level, 1U); + unsigned int height = GetLevelSize(m_impl->height, level); #if NAZARA_RENDERER_SAFE - if (rect.x+rect.width > std::max(m_impl->width >> level, 1U) || rect.y+rect.height > height) + if (rect.x+rect.width > GetLevelSize(m_impl->width, level) || rect.y+rect.height > height) { NazaraError("Rectangle dimensions are out of bounds"); return false; From 1c168fed21680fcb1232729afed909f23687eac3 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 5 Jan 2015 14:31:28 +0100 Subject: [PATCH 123/233] Fixed Image::Update(UInt*, const Boxui&, ...) not working well with cubemaps Former-commit-id: 6f8c83c6a4ace3006543646df9bb2e2838c6cac0 --- src/Nazara/Utility/Image.cpp | 61 +++--------------------------------- 1 file changed, 4 insertions(+), 57 deletions(-) diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index 4f7aabc9a..70bdd5da9 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -1263,9 +1263,9 @@ void NzImage::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int src return; } - // Nous n'autorisons pas de modifier plus d'une face du cubemap à la fois (Nous prenons donc la profondeur de base) - ///FIXME: Ce code n'autorise même pas la modification d'une autre face du cubemap Oo - if (box.x+box.width > width || box.y+box.height > height || box.z+box.depth > GetLevelSize(m_sharedImage->depth, level)) + unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : GetLevelSize(m_sharedImage->depth, level); + if (box.x+box.width > width || box.y+box.height > height || box.z+box.depth > depth || + (m_sharedImage->type == nzImageType_Cubemap && box.depth > 1)) // Nous n'autorisons pas de modifier plus d'une face du cubemap à la fois { NazaraError("Box dimensions are out of bounds"); return; @@ -1285,60 +1285,7 @@ void NzImage::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int src void NzImage::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z, unsigned int srcWidth, unsigned int srcHeight, nzUInt8 level) { - ///FIXME: Cette surcharge possède-t-elle la moindre utilité ? (Update(pixels, NzBoxui(rect.x, rect.y, z, rect.width, rect.height, 1), srcWidth, ..) devrait donner le même résultat - #if NAZARA_UTILITY_SAFE - if (m_sharedImage == &emptyImage) - { - NazaraError("Image must be valid"); - return; - } - - if (!pixels) - { - NazaraError("Invalid pixel source"); - return; - } - - if (!rect.IsValid()) - { - NazaraError("Invalid rectangle"); - return; - } - - if (level >= m_sharedImage->levelCount) - { - NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')'); - return; - } - #endif - - unsigned int width = GetLevelSize(m_sharedImage->width, level); - unsigned int height = GetLevelSize(m_sharedImage->height, level); - - #if NAZARA_UTILITY_SAFE - if (rect.x+rect.width > width || rect.y+rect.height > height) - { - NazaraError("Rectangle dimensions are out of bounds"); - return; - } - - unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : GetLevelSize(m_sharedImage->depth, level); - if (z >= depth) - { - NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= " + NzString::Number(depth) + ')'); - return; - } - #endif - - EnsureOwnership(); - - nzUInt8 bpp = NzPixelFormat::GetBytesPerPixel(m_sharedImage->format); - nzUInt8* dstPixels = GetPixelPtr(m_sharedImage->pixels[level], bpp, rect.x, rect.y, z, width, height); - - Copy(dstPixels, pixels, bpp, - rect.width, rect.height, 1, - width, height, - srcWidth, srcHeight); + return Update(pixels, NzBoxui(rect.x, rect.y, z, rect.width, rect.height, 1), srcWidth, srcHeight, level); } NzImage& NzImage::operator=(const NzImage& image) From 304b4d13cceadb51e784fb0e681f1db39b1d5d53 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 5 Jan 2015 14:32:34 +0100 Subject: [PATCH 124/233] Removed Texture::UpdateFace Texture::Update is now able to update cubemaps faces (one at a time) Former-commit-id: 7468761d1f08fc9477af8da5a38722508c044917 --- include/Nazara/Renderer/Texture.hpp | 4 - src/Nazara/Renderer/Texture.cpp | 148 +++------------------------- 2 files changed, 16 insertions(+), 136 deletions(-) diff --git a/include/Nazara/Renderer/Texture.hpp b/include/Nazara/Renderer/Texture.hpp index 816c6b1e5..f433a8d7d 100644 --- a/include/Nazara/Renderer/Texture.hpp +++ b/include/Nazara/Renderer/Texture.hpp @@ -87,10 +87,6 @@ class NAZARA_API NzTexture : public NzResource, NzNonCopyable bool Update(const nzUInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0); bool Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0); bool Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0); - bool UpdateFace(nzCubemapFace face, const NzImage& image, nzUInt8 level = 0); - bool UpdateFace(nzCubemapFace face, const NzImage& image, const NzRectui& rect, nzUInt8 level = 0); - bool UpdateFace(nzCubemapFace face, const nzUInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0); - bool UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRectui& rect, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0); // Fonctions OpenGL unsigned int GetOpenGLID() const; diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index e080bab0a..148d06031 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -12,8 +12,6 @@ #include #include -///TODO: Virer les méthodes faisant référence aux faces et gérer ces dernières comme de simples niveaux de profondeurs (malgré OpenGL) - struct NzTextureImpl { GLuint id; @@ -508,17 +506,20 @@ bool NzTexture::LoadFromImage(const NzImage& image, bool generateMipmaps) return false; } + NzCallOnExit destroyOnExit([this]() + { + Destroy(); + }); + if (type == nzImageType_Cubemap) { for (nzUInt8 level = 0; level < levelCount; ++level) { for (unsigned int i = 0; i <= nzCubemapFace_Max; ++i) { - if (!UpdateFace(static_cast(i), newImage.GetConstPixels(0, 0, i, level), level)) + if (!Update(newImage.GetConstPixels(0, 0, i, level), NzRectui(0, 0, newImage.GetWidth(level), newImage.GetHeight(level)), i, level)) { NazaraError("Failed to update texture"); - Destroy(); - return false; } } @@ -531,13 +532,13 @@ bool NzTexture::LoadFromImage(const NzImage& image, bool generateMipmaps) if (!Update(newImage.GetConstPixels(0, 0, 0, level), level)) { NazaraError("Failed to update texture"); - Destroy(); - return false; } } } + destroyOnExit.Reset(); + return true; } @@ -697,7 +698,7 @@ bool NzTexture::LoadFaceFromFile(nzCubemapFace face, const NzString& filePath, c return false; } - return UpdateFace(face, image); + return Update(image, NzRectui(0, 0, faceSize, faceSize), face); } bool NzTexture::LoadFaceFromMemory(nzCubemapFace face, const void* data, std::size_t size, const NzImageParams& params) @@ -736,7 +737,7 @@ bool NzTexture::LoadFaceFromMemory(nzCubemapFace face, const void* data, std::si return false; } - return UpdateFace(face, image); + return Update(image, NzRectui(0, 0, faceSize, faceSize), face); } bool NzTexture::LoadFaceFromStream(nzCubemapFace face, NzInputStream& stream, const NzImageParams& params) @@ -776,7 +777,7 @@ bool NzTexture::LoadFaceFromStream(nzCubemapFace face, NzInputStream& stream, co return false; } - return UpdateFace(face, image); + return Update(image, NzRectui(0, 0, faceSize, faceSize), face); } bool NzTexture::SetMipmapRange(nzUInt8 minLevel, nzUInt8 maxLevel) @@ -908,12 +909,6 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int s return false; } - if (m_impl->type == nzImageType_Cubemap) - { - NazaraError("Update is not designed for cubemaps, use UpdateFace instead"); - return false; - } - if (!pixels) { NazaraError("Invalid pixel source"); @@ -930,9 +925,10 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int s unsigned int height = GetLevelSize(m_impl->height, level); #if NAZARA_RENDERER_SAFE - if (box.x+box.width > GetLevelSize(m_impl->width, level) || - box.y+box.height > height || - box.z+box.depth > GetLevelSize(m_impl->depth, level)) + unsigned int width = GetLevelSize(m_impl->width, level); + unsigned int depth = (m_impl->type == nzImageType_Cubemap) ? 6 : GetLevelSize(m_impl->depth, level); + if (box.x+box.width > width || box.y+box.height > height || box.z+box.depth > depth || + (m_impl->type == nzImageType_Cubemap && box.depth > 1)) // Nous n'autorisons pas de modifier plus d'une face du cubemap à la fois { NazaraError("Cube dimensions are out of bounds"); return false; @@ -974,7 +970,7 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int s break; case nzImageType_Cubemap: - NazaraError("Update used on a cubemap texture, please enable safe mode"); + glTexSubImage2D(NzOpenGL::CubemapFace[box.z], level, box.x, height-box.height-box.y, box.width, box.height, format.dataFormat, format.dataType, pixels); break; } @@ -986,118 +982,6 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int return Update(pixels, NzBoxui(rect.x, rect.y, z, rect.width, rect.height, 1), srcWidth, srcHeight, level); } -bool NzTexture::UpdateFace(nzCubemapFace face, const NzImage& image, nzUInt8 level) -{ - #if NAZARA_RENDERER_SAFE - if (!image.IsValid()) - { - NazaraError("Image must be valid"); - return false; - } - - if (image.GetFormat() != m_impl->format) - { - NazaraError("Image format does not match texture format"); - return false; - } - #endif - - return UpdateFace(face, image.GetConstPixels(0, 0, 0, level), NzRectui(0, 0, image.GetWidth(level), image.GetHeight(level)), 0, 0, level); -} - -bool NzTexture::UpdateFace(nzCubemapFace face, const NzImage& image, const NzRectui& rect, nzUInt8 level) -{ - #if NAZARA_RENDERER_SAFE - if (!image.IsValid()) - { - NazaraError("Image must be valid"); - return false; - } - - if (image.GetFormat() != m_impl->format) - { - NazaraError("Image format does not match texture format"); - return false; - } - #endif - - return UpdateFace(face, image.GetConstPixels(0, 0, 0, level), rect, image.GetWidth(level), image.GetHeight(level), level); -} - -bool NzTexture::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, unsigned int srcWidth, unsigned int srcHeight, nzUInt8 level) -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return false; - } - #endif - - return UpdateFace(face, pixels, NzRectui(0, 0, m_impl->width, m_impl->height), srcWidth, srcHeight, level); -} - -bool NzTexture::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRectui& rect, unsigned int srcWidth, unsigned int srcHeight, nzUInt8 level) -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return false; - } - - if (m_impl->type != nzImageType_Cubemap) - { - NazaraError("UpdateFace is designed for cubemaps, use Update instead"); - return false; - } - - if (!pixels) - { - NazaraError("Invalid pixel source"); - return false; - } - - if (!rect.IsValid()) - { - NazaraError("Invalid rectangle"); - return false; - } - #endif - - unsigned int height = GetLevelSize(m_impl->height, level); - - #if NAZARA_RENDERER_SAFE - if (rect.x+rect.width > GetLevelSize(m_impl->width, level) || rect.y+rect.height > height) - { - NazaraError("Rectangle dimensions are out of bounds"); - return false; - } - - if (level >= m_impl->levelCount) - { - NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_impl->levelCount) + ')'); - return false; - } - #endif - - NzOpenGL::Format format; - if (!NzOpenGL::TranslateFormat(m_impl->format, &format, NzOpenGL::FormatType_Texture)) - { - NazaraError("Failed to get OpenGL format"); - return false; - } - - SetUnpackAlignement(NzPixelFormat::GetBytesPerPixel(m_impl->format)); - glPixelStorei(GL_UNPACK_ROW_LENGTH, srcWidth); - glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, srcHeight); - - NzOpenGL::BindTexture(m_impl->type, m_impl->id); - glTexSubImage2D(NzOpenGL::CubemapFace[face], level, rect.x, height-rect.height-rect.y, rect.width, rect.height, format.dataFormat, format.dataType, pixels); - - return true; -} - unsigned int NzTexture::GetOpenGLID() const { #if NAZARA_RENDERER_SAFE From e3f7644831fb910e81c8f3925adbd513427876bf Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 5 Jan 2015 15:08:29 +0100 Subject: [PATCH 125/233] Added class AbstractImage, inherited by Image and Texture Former-commit-id: 16e5db4937a145ac244d6c70e4c74662622f86d9 --- include/Nazara/Renderer/Texture.hpp | 11 +- include/Nazara/Utility/AbstractImage.hpp | 42 ++++++++ include/Nazara/Utility/Image.hpp | 17 +--- src/Nazara/Renderer/RenderTexture.cpp | 1 + src/Nazara/Renderer/Texture.cpp | 123 ++++++++++++++++------- src/Nazara/Utility/AbstractImage.cpp | 24 +++++ src/Nazara/Utility/Image.cpp | 42 +++----- 7 files changed, 178 insertions(+), 82 deletions(-) create mode 100644 include/Nazara/Utility/AbstractImage.hpp create mode 100644 src/Nazara/Utility/AbstractImage.cpp diff --git a/include/Nazara/Renderer/Texture.hpp b/include/Nazara/Renderer/Texture.hpp index f433a8d7d..52abbe3fc 100644 --- a/include/Nazara/Renderer/Texture.hpp +++ b/include/Nazara/Renderer/Texture.hpp @@ -12,9 +12,9 @@ #include #include #include +#include #include #include -#include class NzTexture; @@ -23,7 +23,7 @@ using NzTextureRef = NzResourceRef; struct NzTextureImpl; -class NAZARA_API NzTexture : public NzResource, NzNonCopyable +class NAZARA_API NzTexture : public NzAbstractImage, public NzResource, NzNonCopyable { friend class NzRenderer; friend class NzRenderTexture; @@ -42,18 +42,19 @@ class NAZARA_API NzTexture : public NzResource, NzNonCopyable void EnsureMipmapsUpdate() const; - nzUInt8 GetBytesPerPixel() const; unsigned int GetDepth(nzUInt8 level = 0) const; nzPixelFormat GetFormat() const; unsigned int GetHeight(nzUInt8 level = 0) const; + nzUInt8 GetLevelCount() const; + nzUInt8 GetMaxLevel() const; + unsigned int GetMemoryUsage() const; + unsigned int GetMemoryUsage(nzUInt8 level) const; NzVector3ui GetSize(nzUInt8 level = 0) const; nzImageType GetType() const; unsigned int GetWidth(nzUInt8 level = 0) const; bool HasMipmaps() const; - bool IsCompressed() const; - bool IsCubemap() const; bool IsValid() const; // Load diff --git a/include/Nazara/Utility/AbstractImage.hpp b/include/Nazara/Utility/AbstractImage.hpp new file mode 100644 index 000000000..345868890 --- /dev/null +++ b/include/Nazara/Utility/AbstractImage.hpp @@ -0,0 +1,42 @@ +// 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_ABSTRACTIMAGE_HPP +#define NAZARA_ABSTRACTIMAGE_HPP + +#include +#include +#include +#include +#include + +class NAZARA_API NzAbstractImage +{ + public: + NzAbstractImage() = default; + ~NzAbstractImage(); + + nzUInt8 GetBytesPerPixel() const; + virtual unsigned int GetDepth(nzUInt8 level = 0) const = 0; + virtual nzPixelFormat GetFormat() const = 0; + virtual unsigned int GetHeight(nzUInt8 level = 0) const = 0; + virtual nzUInt8 GetLevelCount() const = 0; + virtual nzUInt8 GetMaxLevel() const = 0; + virtual unsigned int GetMemoryUsage() const = 0; + virtual unsigned int GetMemoryUsage(nzUInt8 level) const = 0; + virtual NzVector3ui GetSize(nzUInt8 level = 0) const = 0; + virtual nzImageType GetType() const = 0; + virtual unsigned int GetWidth(nzUInt8 level = 0) const = 0; + + bool IsCompressed() const; + bool IsCubemap() const; + + virtual bool Update(const nzUInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0) = 0; + virtual bool Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0) = 0; + virtual bool Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0) = 0; +}; + +#endif // NAZARA_IMAGE_HPP diff --git a/include/Nazara/Utility/Image.hpp b/include/Nazara/Utility/Image.hpp index f59811d40..d94177bbe 100644 --- a/include/Nazara/Utility/Image.hpp +++ b/include/Nazara/Utility/Image.hpp @@ -13,12 +13,8 @@ #include #include #include -#include -#include -#include +#include #include -#include -#include #include ///TODO: Filtres @@ -40,7 +36,7 @@ using NzImageConstRef = NzResourceRef; using NzImageLoader = NzResourceLoader; using NzImageRef = NzResourceRef; -class NAZARA_API NzImage : public NzResource +class NAZARA_API NzImage : public NzAbstractImage, public NzResource { friend NzImageLoader; @@ -68,7 +64,6 @@ class NAZARA_API NzImage : public NzResource bool FlipHorizontally(); bool FlipVertically(); - nzUInt8 GetBytesPerPixel() const; const nzUInt8* GetConstPixels(unsigned int x = 0, unsigned int y = 0, unsigned int z = 0, nzUInt8 level = 0) const; unsigned int GetDepth(nzUInt8 level = 0) const; nzPixelFormat GetFormat() const; @@ -83,8 +78,6 @@ class NAZARA_API NzImage : public NzResource nzImageType GetType() const; unsigned int GetWidth(nzUInt8 level = 0) const; - bool IsCompressed() const; - bool IsCubemap() const; bool IsValid() const; // Load @@ -107,9 +100,9 @@ class NAZARA_API NzImage : public NzResource void SetLevelCount(nzUInt8 levelCount); bool SetPixelColor(const NzColor& color, unsigned int x, unsigned int y = 0, unsigned int z = 0); - void Update(const nzUInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0); - void Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0); - void Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0); + bool Update(const nzUInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0); + bool Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0); + bool Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0); NzImage& operator=(const NzImage& image); NzImage& operator=(NzImage&& image) noexcept; diff --git a/src/Nazara/Renderer/RenderTexture.cpp b/src/Nazara/Renderer/RenderTexture.cpp index 5c5ae4cdf..ee53e0ed0 100644 --- a/src/Nazara/Renderer/RenderTexture.cpp +++ b/src/Nazara/Renderer/RenderTexture.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index 148d06031..855a70e2f 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -311,19 +312,6 @@ void NzTexture::EnsureMipmapsUpdate() const } } -nzUInt8 NzTexture::GetBytesPerPixel() const -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return 0; - } - #endif - - return NzPixelFormat::GetBytesPerPixel(m_impl->format); -} - unsigned int NzTexture::GetDepth(nzUInt8 level) const { #if NAZARA_RENDERER_SAFE @@ -363,6 +351,89 @@ unsigned int NzTexture::GetHeight(nzUInt8 level) const return GetLevelSize(m_impl->height, level); } +nzUInt8 NzTexture::GetLevelCount() const +{ + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return 0; + } + #endif + + return m_impl->levelCount; +} + +nzUInt8 NzTexture::GetMaxLevel() const +{ + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return 0; + } + #endif + + return NzImage::GetMaxLevel(m_impl->type, m_impl->width, m_impl->height, m_impl->depth); +} + +unsigned int NzTexture::GetMemoryUsage() const +{ + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return 0; + } + #endif + + unsigned int width = m_impl->width; + unsigned int height = m_impl->height; + unsigned int depth = m_impl->depth; + + unsigned int size = 0; + for (unsigned int i = 0; i < m_impl->levelCount; ++i) + { + size += width * height * depth; + + if (width > 1) + width >>= 1; + + if (height > 1) + height >>= 1; + + if (depth > 1) + depth >>= 1; + } + + if (m_impl->type == nzImageType_Cubemap) + size *= 6; + + return size * NzPixelFormat::GetBytesPerPixel(m_impl->format); +} + +unsigned int NzTexture::GetMemoryUsage(nzUInt8 level) const +{ + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return 0; + } + + if (level >= m_impl->levelCount) + { + NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_impl->levelCount) + ')'); + return 0; + } + #endif + + return (GetLevelSize(m_impl->width, level)) * + (GetLevelSize(m_impl->height, level)) * + ((m_impl->type == nzImageType_Cubemap) ? 6 : GetLevelSize(m_impl->depth, level)) * + NzPixelFormat::GetBytesPerPixel(m_impl->format); +} + NzVector3ui NzTexture::GetSize(nzUInt8 level) const { #if NAZARA_RENDERER_SAFE @@ -415,32 +486,6 @@ bool NzTexture::HasMipmaps() const return m_impl->levelCount > 1; } -bool NzTexture::IsCompressed() const -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return false; - } - #endif - - return NzPixelFormat::IsCompressed(m_impl->format); -} - -bool NzTexture::IsCubemap() const -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return false; - } - #endif - - return m_impl->type == nzImageType_Cubemap; -} - bool NzTexture::IsValid() const { return m_impl != nullptr; diff --git a/src/Nazara/Utility/AbstractImage.cpp b/src/Nazara/Utility/AbstractImage.cpp new file mode 100644 index 000000000..9e5ea28a0 --- /dev/null +++ b/src/Nazara/Utility/AbstractImage.cpp @@ -0,0 +1,24 @@ +// 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 + +#include +#include +#include + +NzAbstractImage::~NzAbstractImage() = default; + +nzUInt8 NzAbstractImage::GetBytesPerPixel() const +{ + return NzPixelFormat::GetBytesPerPixel(GetFormat()); +} + +bool NzAbstractImage::IsCompressed() const +{ + return NzPixelFormat::IsCompressed(GetFormat()); +} + +bool NzAbstractImage::IsCubemap() const +{ + return GetType() == nzImageType_Cubemap; +} diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index 70bdd5da9..0532294bb 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -590,11 +591,6 @@ bool NzImage::FlipVertically() return true; } -nzUInt8 NzImage::GetBytesPerPixel() const -{ - return NzPixelFormat::GetBytesPerPixel(m_sharedImage->format); -} - const nzUInt8* NzImage::GetConstPixels(unsigned int x, unsigned int y, unsigned int z, nzUInt8 level) const { #if NAZARA_UTILITY_SAFE @@ -850,16 +846,6 @@ unsigned int NzImage::GetWidth(nzUInt8 level) const return GetLevelSize(m_sharedImage->width, level); } -bool NzImage::IsCompressed() const -{ - return NzPixelFormat::IsCompressed(m_sharedImage->format); -} - -bool NzImage::IsCubemap() const -{ - return m_sharedImage->type == nzImageType_Cubemap; -} - bool NzImage::IsValid() const { return m_sharedImage != &emptyImage; @@ -1199,25 +1185,25 @@ bool NzImage::SetPixelColor(const NzColor& color, unsigned int x, unsigned int y return true; } -void NzImage::Update(const nzUInt8* pixels, unsigned int srcWidth, unsigned int srcHeight, nzUInt8 level) +bool NzImage::Update(const nzUInt8* pixels, unsigned int srcWidth, unsigned int srcHeight, nzUInt8 level) { #if NAZARA_UTILITY_SAFE if (m_sharedImage == &emptyImage) { NazaraError("Image must be valid"); - return; + return false; } if (!pixels) { NazaraError("Invalid pixel source"); - return; + return false; } if (level >= m_sharedImage->levelCount) { NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')'); - return; + return false; } #endif @@ -1229,27 +1215,29 @@ void NzImage::Update(const nzUInt8* pixels, unsigned int srcWidth, unsigned int GetLevelSize(m_sharedImage->depth, level), 0, 0, srcWidth, srcHeight); + + return true; } -void NzImage::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int srcWidth, unsigned int srcHeight, nzUInt8 level) +bool NzImage::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int srcWidth, unsigned int srcHeight, nzUInt8 level) { #if NAZARA_UTILITY_SAFE if (m_sharedImage == &emptyImage) { NazaraError("Image must be valid"); - return; + return false; } if (!pixels) { NazaraError("Invalid pixel source"); - return; + return false; } if (level >= m_sharedImage->levelCount) { NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')'); - return; + return false; } #endif @@ -1260,7 +1248,7 @@ void NzImage::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int src if (!box.IsValid()) { NazaraError("Invalid box"); - return; + return false; } unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : GetLevelSize(m_sharedImage->depth, level); @@ -1268,7 +1256,7 @@ void NzImage::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int src (m_sharedImage->type == nzImageType_Cubemap && box.depth > 1)) // Nous n'autorisons pas de modifier plus d'une face du cubemap à la fois { NazaraError("Box dimensions are out of bounds"); - return; + return false; } #endif @@ -1281,9 +1269,11 @@ void NzImage::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int src box.width, box.height, box.depth, width, height, srcWidth, srcHeight); + + return true; } -void NzImage::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z, unsigned int srcWidth, unsigned int srcHeight, nzUInt8 level) +bool NzImage::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z, unsigned int srcWidth, unsigned int srcHeight, nzUInt8 level) { return Update(pixels, NzBoxui(rect.x, rect.y, z, rect.width, rect.height, 1), srcWidth, srcHeight, level); } From fc1e75d379637e801407f9f957d70e0f366ffb64 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 5 Jan 2015 15:12:07 +0100 Subject: [PATCH 126/233] Fixed compilation error (from 683866baee26a12cf63b20914fff338cc872a4c8 [formerly a885b69881c30dcad29f87c3ffee41808761b6c9]) Former-commit-id: 8d96d5dee5666bbce41f406bcbabe269e101fafb --- src/Nazara/Graphics/Sprite.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index b6dcf5ae0..3d7a6d48e 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -128,7 +128,7 @@ void NzSprite::SetMaterial(NzMaterial* material, bool resizeSprite) NzTexture* diffuseMap = m_material->GetDiffuseMap(); if (resizeSprite && diffuseMap && diffuseMap->IsValid()) - SetSize(NzVector2f(diffuseMap->GetSize())); + SetSize(NzVector2f(NzVector2ui(diffuseMap->GetSize()))); } void NzSprite::SetSize(const NzVector2f& size) From 5cbdd8832c86be469d13810c16f8e9f081e86c43 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 6 Jan 2015 13:36:58 +0100 Subject: [PATCH 127/233] Turned DataStorage enum into flags Allowing for example hybrid buffer implementation Former-commit-id: 74af1ba5b11b945abdfa6b46d0c11d600eca6d7c --- include/Nazara/Utility/Buffer.hpp | 14 +++++++------- include/Nazara/Utility/Enums.hpp | 11 ++++++----- include/Nazara/Utility/IndexBuffer.hpp | 6 +++--- include/Nazara/Utility/Mesh.hpp | 6 +++--- include/Nazara/Utility/VertexBuffer.hpp | 6 +++--- src/Nazara/Utility/Buffer.cpp | 14 +++++++------- src/Nazara/Utility/IndexBuffer.cpp | 6 +++--- src/Nazara/Utility/VertexBuffer.cpp | 6 +++--- 8 files changed, 35 insertions(+), 34 deletions(-) diff --git a/include/Nazara/Utility/Buffer.hpp b/include/Nazara/Utility/Buffer.hpp index b1b0b64b1..b7a81e094 100644 --- a/include/Nazara/Utility/Buffer.hpp +++ b/include/Nazara/Utility/Buffer.hpp @@ -28,19 +28,19 @@ class NAZARA_API NzBuffer : public NzResource, NzNonCopyable using BufferFactory = NzAbstractBuffer* (*)(NzBuffer* parent, nzBufferType type); NzBuffer(nzBufferType type); - NzBuffer(nzBufferType type, unsigned int size, nzDataStorage storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); + NzBuffer(nzBufferType type, unsigned int size, nzUInt32 storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); ~NzBuffer(); bool CopyContent(const NzBuffer& buffer); - bool Create(unsigned int size, nzDataStorage storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); + bool Create(unsigned int size, nzUInt32 storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); void Destroy(); bool Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard = false); NzAbstractBuffer* GetImpl() const; unsigned int GetSize() const; - nzDataStorage GetStorage() const; + nzUInt32 GetStorage() const; nzBufferType GetType() const; nzBufferUsage GetUsage() const; @@ -50,12 +50,12 @@ class NAZARA_API NzBuffer : public NzResource, NzNonCopyable void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0); void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0) const; - bool SetStorage(nzDataStorage storage); + bool SetStorage(nzUInt32 storage); void Unmap() const; - static bool IsStorageSupported(nzDataStorage storage); - static void SetBufferFactory(nzDataStorage storage, BufferFactory func); + static bool IsStorageSupported(nzUInt32 storage); + static void SetBufferFactory(nzUInt32 storage, BufferFactory func); private: static bool Initialize(); @@ -63,7 +63,7 @@ class NAZARA_API NzBuffer : public NzResource, NzNonCopyable nzBufferType m_type; nzBufferUsage m_usage; - nzDataStorage m_storage; + nzUInt32 m_storage; NzAbstractBuffer* m_impl; unsigned int m_size; diff --git a/include/Nazara/Utility/Enums.hpp b/include/Nazara/Utility/Enums.hpp index 6d0ec4f2a..4c00fdad6 100644 --- a/include/Nazara/Utility/Enums.hpp +++ b/include/Nazara/Utility/Enums.hpp @@ -75,13 +75,14 @@ enum nzCubemapFace nzCubemapFace_Max = nzCubemapFace_NegativeZ }; -enum nzDataStorage +enum nzDataStorageFlags { - nzDataStorage_Both, - nzDataStorage_Hardware, - nzDataStorage_Software, + nzDataStorage_Hardware = 0x1, + nzDataStorage_Software = 0x2, - nzDataStorage_Max = nzDataStorage_Software + nzDataStorage_Both = nzDataStorage_Hardware | nzDataStorage_Software, + + nzDataStorage_Max = nzDataStorage_Software*2-1 }; enum nzEventType diff --git a/include/Nazara/Utility/IndexBuffer.hpp b/include/Nazara/Utility/IndexBuffer.hpp index 3f7eb59d6..cd1860199 100644 --- a/include/Nazara/Utility/IndexBuffer.hpp +++ b/include/Nazara/Utility/IndexBuffer.hpp @@ -23,7 +23,7 @@ class NAZARA_API NzIndexBuffer : public NzResource NzIndexBuffer() = default; NzIndexBuffer(bool largeIndices, NzBuffer* buffer); NzIndexBuffer(bool largeIndices, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset); - NzIndexBuffer(bool largeIndices, unsigned int length, nzDataStorage storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); + NzIndexBuffer(bool largeIndices, unsigned int length, nzUInt32 storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); NzIndexBuffer(const NzIndexBuffer& indexBuffer); NzIndexBuffer(NzIndexBuffer&& indexBuffer) noexcept; ~NzIndexBuffer(); @@ -54,11 +54,11 @@ class NAZARA_API NzIndexBuffer : public NzResource void Reset(); void Reset(bool largeIndices, NzBuffer* buffer); void Reset(bool largeIndices, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset); - void Reset(bool largeIndices, unsigned int length, nzDataStorage storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); + void Reset(bool largeIndices, unsigned int length, nzUInt32 storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); void Reset(const NzIndexBuffer& indexBuffer); void Reset(NzIndexBuffer&& indexBuffer) noexcept; - bool SetStorage(nzDataStorage storage); + bool SetStorage(nzUInt32 storage); void Unmap() const; diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp index 6f4f83c61..296d72f7c 100644 --- a/include/Nazara/Utility/Mesh.hpp +++ b/include/Nazara/Utility/Mesh.hpp @@ -24,12 +24,12 @@ struct NAZARA_API NzMeshParams { NzMeshParams(); // Vérifie que le storage par défaut est supporté (software autrement) - // Si ceci sera le stockage utilisé par les buffers - nzDataStorage storage = nzDataStorage_Hardware; - // La mise à l'échelle éventuelle que subira le mesh NzVector3f scale = NzVector3f::Unit(); + // Si ceci sera le stockage utilisé par les buffers + nzUInt32 storage = nzDataStorage_Hardware; + // Charger une version animée du mesh si possible ? bool animated = true; diff --git a/include/Nazara/Utility/VertexBuffer.hpp b/include/Nazara/Utility/VertexBuffer.hpp index 6acada650..feb09ae16 100644 --- a/include/Nazara/Utility/VertexBuffer.hpp +++ b/include/Nazara/Utility/VertexBuffer.hpp @@ -24,7 +24,7 @@ class NAZARA_API NzVertexBuffer : public NzResource NzVertexBuffer() = default; NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer); NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset); - NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzDataStorage storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); + NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzUInt32 storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); NzVertexBuffer(const NzVertexBuffer& vertexBuffer); NzVertexBuffer(NzVertexBuffer&& vertexBuffer) noexcept; ~NzVertexBuffer(); @@ -50,11 +50,11 @@ class NAZARA_API NzVertexBuffer : public NzResource void Reset(); void Reset(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer); void Reset(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset); - void Reset(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzDataStorage storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); + void Reset(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzUInt32 storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); void Reset(const NzVertexBuffer& vertexBuffer); void Reset(NzVertexBuffer&& vertexBuffer) noexcept; - bool SetStorage(nzDataStorage storage); + bool SetStorage(nzUInt32 storage); void SetVertexDeclaration(const NzVertexDeclaration* vertexDeclaration); void Unmap() const; diff --git a/src/Nazara/Utility/Buffer.cpp b/src/Nazara/Utility/Buffer.cpp index 71b568f5b..1a631e990 100644 --- a/src/Nazara/Utility/Buffer.cpp +++ b/src/Nazara/Utility/Buffer.cpp @@ -30,7 +30,7 @@ m_size(0) { } -NzBuffer::NzBuffer(nzBufferType type, unsigned int size, nzDataStorage storage, nzBufferUsage usage) : +NzBuffer::NzBuffer(nzBufferType type, unsigned int size, nzUInt32 storage, nzBufferUsage usage) : m_type(type), m_impl(nullptr) { @@ -63,7 +63,7 @@ bool NzBuffer::CopyContent(const NzBuffer& buffer) return Fill(mapper.GetPointer(), 0, buffer.GetSize()); } -bool NzBuffer::Create(unsigned int size, nzDataStorage storage, nzBufferUsage usage) +bool NzBuffer::Create(unsigned int size, nzUInt32 storage, nzBufferUsage usage) { Destroy(); @@ -131,7 +131,7 @@ unsigned int NzBuffer::GetSize() const return m_size; } -nzDataStorage NzBuffer::GetStorage() const +nzUInt32 NzBuffer::GetStorage() const { return m_storage; } @@ -148,7 +148,7 @@ nzBufferUsage NzBuffer::GetUsage() const bool NzBuffer::IsHardware() const { - return m_storage == nzDataStorage_Hardware; + return m_storage & nzDataStorage_Hardware; } bool NzBuffer::IsValid() const @@ -200,7 +200,7 @@ void* NzBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int siz return m_impl->Map(access, offset, (size == 0) ? m_size-offset : size); } -bool NzBuffer::SetStorage(nzDataStorage storage) +bool NzBuffer::SetStorage(nzUInt32 storage) { #if NAZARA_UTILITY_SAFE if (!m_impl) @@ -275,12 +275,12 @@ void NzBuffer::Unmap() const NazaraWarning("Failed to unmap buffer (it's content may be undefined)"); ///TODO: Unexpected ? } -bool NzBuffer::IsStorageSupported(nzDataStorage storage) +bool NzBuffer::IsStorageSupported(nzUInt32 storage) { return s_bufferFactories[storage] != nullptr; } -void NzBuffer::SetBufferFactory(nzDataStorage storage, BufferFactory func) +void NzBuffer::SetBufferFactory(nzUInt32 storage, BufferFactory func) { s_bufferFactories[storage] = func; } diff --git a/src/Nazara/Utility/IndexBuffer.cpp b/src/Nazara/Utility/IndexBuffer.cpp index 65cc22757..5a4f5007a 100644 --- a/src/Nazara/Utility/IndexBuffer.cpp +++ b/src/Nazara/Utility/IndexBuffer.cpp @@ -24,7 +24,7 @@ NzIndexBuffer::NzIndexBuffer(bool largeIndices, NzBuffer* buffer, unsigned int s Reset(largeIndices, buffer, startOffset, endOffset); } -NzIndexBuffer::NzIndexBuffer(bool largeIndices, unsigned int length, nzDataStorage storage, nzBufferUsage usage) +NzIndexBuffer::NzIndexBuffer(bool largeIndices, unsigned int length, nzUInt32 storage, nzBufferUsage usage) { NzErrorFlags(nzErrorFlag_ThrowException, true); Reset(largeIndices, length, storage, usage); @@ -220,7 +220,7 @@ void NzIndexBuffer::Reset(bool largeIndices, NzBuffer* buffer, unsigned int star m_startOffset = startOffset; } -void NzIndexBuffer::Reset(bool largeIndices, unsigned int length, nzDataStorage storage, nzBufferUsage usage) +void NzIndexBuffer::Reset(bool largeIndices, unsigned int length, nzUInt32 storage, nzBufferUsage usage) { unsigned int stride = (largeIndices) ? sizeof(nzUInt32) : sizeof(nzUInt16); @@ -251,7 +251,7 @@ void NzIndexBuffer::Reset(NzIndexBuffer&& indexBuffer) noexcept m_startOffset = indexBuffer.m_startOffset; } -bool NzIndexBuffer::SetStorage(nzDataStorage storage) +bool NzIndexBuffer::SetStorage(nzUInt32 storage) { return m_buffer->SetStorage(storage); } diff --git a/src/Nazara/Utility/VertexBuffer.cpp b/src/Nazara/Utility/VertexBuffer.cpp index 31af8c2e9..12f72051f 100644 --- a/src/Nazara/Utility/VertexBuffer.cpp +++ b/src/Nazara/Utility/VertexBuffer.cpp @@ -20,7 +20,7 @@ NzVertexBuffer::NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, NzB Reset(vertexDeclaration, buffer, startOffset, endOffset); } -NzVertexBuffer::NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzDataStorage storage, nzBufferUsage usage) +NzVertexBuffer::NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzUInt32 storage, nzBufferUsage usage) { NzErrorFlags(nzErrorFlag_ThrowException, true); Reset(vertexDeclaration, length, storage, usage); @@ -230,7 +230,7 @@ void NzVertexBuffer::Reset(const NzVertexDeclaration* vertexDeclaration, NzBuffe m_vertexDeclaration = vertexDeclaration; } -void NzVertexBuffer::Reset(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzDataStorage storage, nzBufferUsage usage) +void NzVertexBuffer::Reset(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzUInt32 storage, nzBufferUsage usage) { m_endOffset = length * ((vertexDeclaration) ? vertexDeclaration->GetStride() : 1); m_startOffset = 0; @@ -259,7 +259,7 @@ void NzVertexBuffer::Reset(NzVertexBuffer&& vertexBuffer) noexcept m_vertexDeclaration = std::move(vertexBuffer.m_vertexDeclaration); } -bool NzVertexBuffer::SetStorage(nzDataStorage storage) +bool NzVertexBuffer::SetStorage(nzUInt32 storage) { return m_buffer->SetStorage(storage); } From 72a24c4d7c4914271034b1ad23d0cfdb285c7878 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 6 Jan 2015 19:03:39 +0100 Subject: [PATCH 128/233] Aded Renderer::GetMaxTextureSize() + minor changes Former-commit-id: 6b80280d018c323ceb393c58aab96d68a15f3ff2 --- include/Nazara/Renderer/Renderer.hpp | 1 + src/Nazara/Renderer/Renderer.cpp | 37 ++++++++++++++++++---------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/include/Nazara/Renderer/Renderer.hpp b/include/Nazara/Renderer/Renderer.hpp index aff9101fa..42832c661 100644 --- a/include/Nazara/Renderer/Renderer.hpp +++ b/include/Nazara/Renderer/Renderer.hpp @@ -57,6 +57,7 @@ class NAZARA_API NzRenderer static nzUInt8 GetMaxAnisotropyLevel(); static unsigned int GetMaxColorAttachments(); static unsigned int GetMaxRenderTargets(); + static unsigned int GetMaxTextureSize(); static unsigned int GetMaxTextureUnits(); static unsigned int GetMaxVertexAttribs(); static float GetPointSize(); diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index 9243f02a0..0e5b42855 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -92,6 +92,7 @@ namespace bool s_useVertexArrayObjects; unsigned int s_maxColorAttachments; unsigned int s_maxRenderTarget; + unsigned int s_maxTextureSize; unsigned int s_maxTextureUnit; unsigned int s_maxVertexAttribs; @@ -612,6 +613,11 @@ unsigned int NzRenderer::GetMaxRenderTargets() return s_maxRenderTarget; } +unsigned int NzRenderer::GetMaxTextureSize() +{ + return s_maxTextureSize; +} + unsigned int NzRenderer::GetMaxTextureUnits() { return s_maxTextureUnit; @@ -706,19 +712,19 @@ bool NzRenderer::Initialize() } // Récupération des capacités d'OpenGL - s_capabilities[nzRendererCap_AnisotropicFilter] = NzOpenGL::IsSupported(nzOpenGLExtension_AnisotropicFilter); - s_capabilities[nzRendererCap_ConditionalRendering] = NzOpenGL::IsSupported(nzOpenGLExtension_ConditionalRender); - s_capabilities[nzRendererCap_FP64] = NzOpenGL::IsSupported(nzOpenGLExtension_FP64); - s_capabilities[nzRendererCap_HardwareBuffer] = true; // Natif depuis OpenGL 1.5 - s_capabilities[nzRendererCap_Instancing] = NzOpenGL::IsSupported(nzOpenGLExtension_DrawInstanced) && NzOpenGL::IsSupported(nzOpenGLExtension_InstancedArray); + s_capabilities[nzRendererCap_AnisotropicFilter] = NzOpenGL::IsSupported(nzOpenGLExtension_AnisotropicFilter); + s_capabilities[nzRendererCap_ConditionalRendering] = NzOpenGL::IsSupported(nzOpenGLExtension_ConditionalRender); + s_capabilities[nzRendererCap_FP64] = NzOpenGL::IsSupported(nzOpenGLExtension_FP64); + s_capabilities[nzRendererCap_HardwareBuffer] = true; // Natif depuis OpenGL 1.5 + s_capabilities[nzRendererCap_Instancing] = NzOpenGL::IsSupported(nzOpenGLExtension_DrawInstanced) && NzOpenGL::IsSupported(nzOpenGLExtension_InstancedArray); s_capabilities[nzRendererCap_MultipleRenderTargets] = (glBindFragDataLocation != nullptr); // Natif depuis OpenGL 2.0 mais inutile sans glBindFragDataLocation - s_capabilities[nzRendererCap_OcclusionQuery] = true; // Natif depuis OpenGL 1.5 - s_capabilities[nzRendererCap_PixelBufferObject] = NzOpenGL::IsSupported(nzOpenGLExtension_PixelBufferObject); - s_capabilities[nzRendererCap_RenderTexture] = NzOpenGL::IsSupported(nzOpenGLExtension_FrameBufferObject); - s_capabilities[nzRendererCap_Texture3D] = true; // Natif depuis OpenGL 1.2 - s_capabilities[nzRendererCap_TextureCubemap] = true; // Natif depuis OpenGL 1.3 - s_capabilities[nzRendererCap_TextureMulti] = true; // Natif depuis OpenGL 1.3 - s_capabilities[nzRendererCap_TextureNPOT] = true; // Natif depuis OpenGL 2.0 + s_capabilities[nzRendererCap_OcclusionQuery] = true; // Natif depuis OpenGL 1.5 + s_capabilities[nzRendererCap_PixelBufferObject] = NzOpenGL::IsSupported(nzOpenGLExtension_PixelBufferObject); + s_capabilities[nzRendererCap_RenderTexture] = NzOpenGL::IsSupported(nzOpenGLExtension_FrameBufferObject); + s_capabilities[nzRendererCap_Texture3D] = true; // Natif depuis OpenGL 1.2 + s_capabilities[nzRendererCap_TextureCubemap] = true; // Natif depuis OpenGL 1.3 + s_capabilities[nzRendererCap_TextureMulti] = true; // Natif depuis OpenGL 1.3 + s_capabilities[nzRendererCap_TextureNPOT] = true; // Natif depuis OpenGL 2.0 NzContext::EnsureContext(); @@ -762,6 +768,10 @@ bool NzRenderer::Initialize() else s_maxTextureUnit = 1; + GLint maxTextureSize; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); + s_maxTextureSize = maxTextureSize; + GLint maxVertexAttribs; glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs); s_maxVertexAttribs = static_cast(maxVertexAttribs); @@ -1966,7 +1976,8 @@ void NzRenderer::OnTextureReleased(const NzTexture* texture) { if (unit.texture == texture) unit.texture = nullptr; - // Inutile de changer le flag pour une texture désactivée + + // Inutile de changer le flag pour une texture désactivée } } From 6c4f8e7396570daf565c4d3366366b0701884411 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 7 Jan 2015 19:19:53 +0100 Subject: [PATCH 129/233] Added SparsePtr::operator[+|-](unsigned int) overload Let's hope it will be enough to stop GCC from barking at me Former-commit-id: 0bcdf37acdc2e49a4ddd310dcdeb5bd6c66225a1 --- include/Nazara/Core/SparsePtr.hpp | 2 ++ include/Nazara/Core/SparsePtr.inl | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/include/Nazara/Core/SparsePtr.hpp b/include/Nazara/Core/SparsePtr.hpp index 8d104827c..b077b6d56 100644 --- a/include/Nazara/Core/SparsePtr.hpp +++ b/include/Nazara/Core/SparsePtr.hpp @@ -46,7 +46,9 @@ class NzSparsePtr T& operator[](int index) const; NzSparsePtr operator+(int count) const; + NzSparsePtr operator+(unsigned int count) const; NzSparsePtr operator-(int count) const; + NzSparsePtr operator-(unsigned int count) const; std::ptrdiff_t operator-(const NzSparsePtr& ptr) const; NzSparsePtr& operator+=(int count); diff --git a/include/Nazara/Core/SparsePtr.inl b/include/Nazara/Core/SparsePtr.inl index eb6c988ae..188996d4b 100644 --- a/include/Nazara/Core/SparsePtr.inl +++ b/include/Nazara/Core/SparsePtr.inl @@ -127,12 +127,24 @@ NzSparsePtr NzSparsePtr::operator+(int count) const return NzSparsePtr(m_ptr + count*m_stride, m_stride); } +template +NzSparsePtr NzSparsePtr::operator+(unsigned int count) const +{ + return NzSparsePtr(m_ptr + count*m_stride, m_stride); +} + template NzSparsePtr NzSparsePtr::operator-(int count) const { return NzSparsePtr(m_ptr - count*m_stride, m_stride); } +template +NzSparsePtr NzSparsePtr::operator-(unsigned int count) const +{ + return NzSparsePtr(m_ptr - count*m_stride, m_stride); +} + template std::ptrdiff_t NzSparsePtr::operator-(const NzSparsePtr& ptr) const { From 9293022e71fc0e622c21a0d2764ffdba21e461f7 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 7 Jan 2015 19:27:15 +0100 Subject: [PATCH 130/233] Added sprite overlay rendering Former-commit-id: 1e25a7d85f06f4a4bc3ed0ead76df01db440671d --- .../Nazara/Graphics/AbstractRenderQueue.hpp | 3 +- .../Nazara/Graphics/DeferredRenderQueue.hpp | 2 +- include/Nazara/Graphics/Enums.hpp | 7 +- .../Nazara/Graphics/ForwardRenderQueue.hpp | 5 +- .../Graphics/ForwardRenderTechnique.hpp | 18 +- include/Nazara/Renderer/Enums.hpp | 1 + src/Nazara/Graphics/DeferredRenderQueue.cpp | 4 +- src/Nazara/Graphics/ForwardRenderQueue.cpp | 55 +++++- .../Graphics/ForwardRenderTechnique.cpp | 183 ++++++++++-------- src/Nazara/Graphics/Material.cpp | 8 +- .../Resources/Shaders/Basic/core.frag | 7 +- .../Resources/Shaders/Basic/core.frag.h | 2 +- .../Resources/Shaders/PhongLighting/core.frag | 6 + .../Shaders/PhongLighting/core.frag.h | 2 +- 14 files changed, 192 insertions(+), 111 deletions(-) diff --git a/include/Nazara/Graphics/AbstractRenderQueue.hpp b/include/Nazara/Graphics/AbstractRenderQueue.hpp index 5159a8fce..d10685882 100644 --- a/include/Nazara/Graphics/AbstractRenderQueue.hpp +++ b/include/Nazara/Graphics/AbstractRenderQueue.hpp @@ -18,6 +18,7 @@ class NzDrawable; class NzLight; class NzMaterial; class NzSprite; +class NzTexture; struct NzMeshData; class NAZARA_API NzAbstractRenderQueue : NzNonCopyable @@ -29,7 +30,7 @@ class NAZARA_API NzAbstractRenderQueue : NzNonCopyable virtual void AddDrawable(const NzDrawable* drawable) = 0; virtual void AddLight(const NzLight* light) = 0; virtual void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) = 0; - virtual void AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount) = 0; + virtual void AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay = nullptr) = 0; virtual void Clear(bool fully) = 0; }; diff --git a/include/Nazara/Graphics/DeferredRenderQueue.hpp b/include/Nazara/Graphics/DeferredRenderQueue.hpp index 8020dffd7..8ad147042 100644 --- a/include/Nazara/Graphics/DeferredRenderQueue.hpp +++ b/include/Nazara/Graphics/DeferredRenderQueue.hpp @@ -31,7 +31,7 @@ class NAZARA_API NzDeferredRenderQueue : public NzAbstractRenderQueue, NzResourc void AddDrawable(const NzDrawable* drawable) override; void AddLight(const NzLight* light) 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) override; + void AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay = nullptr) override; void Clear(bool fully); diff --git a/include/Nazara/Graphics/Enums.hpp b/include/Nazara/Graphics/Enums.hpp index 60b05238d..4f4cb1472 100644 --- a/include/Nazara/Graphics/Enums.hpp +++ b/include/Nazara/Graphics/Enums.hpp @@ -85,9 +85,10 @@ enum nzShaderFlags { nzShaderFlags_None = 0, - nzShaderFlags_Deferred = 0x1, - nzShaderFlags_Instancing = 0x2, - nzShaderFlags_VertexColor = 0x4, + nzShaderFlags_Deferred = 0x1, + nzShaderFlags_Instancing = 0x2, + nzShaderFlags_TextureOverlay = 0x4, + nzShaderFlags_VertexColor = 0x8, nzShaderFlags_Max = nzShaderFlags_VertexColor*2-1 }; diff --git a/include/Nazara/Graphics/ForwardRenderQueue.hpp b/include/Nazara/Graphics/ForwardRenderQueue.hpp index e7c7c3087..a7571a848 100644 --- a/include/Nazara/Graphics/ForwardRenderQueue.hpp +++ b/include/Nazara/Graphics/ForwardRenderQueue.hpp @@ -33,7 +33,7 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResource void AddDrawable(const NzDrawable* drawable) override; void AddLight(const NzLight* light) 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) override; + void AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay = nullptr) override; void Clear(bool fully); @@ -74,7 +74,8 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResource typedef std::map>, MeshDataComparator> MeshInstanceContainer; typedef std::map, BatchedModelMaterialComparator> ModelBatches; - typedef std::map> BasicSpriteBatches; + typedef std::map> BasicSpriteOverlayContainer; + typedef std::map BasicSpriteBatches; typedef std::vector LightContainer; typedef std::vector TransparentModelContainer; diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.hpp b/include/Nazara/Graphics/ForwardRenderTechnique.hpp index 18caea522..6aa2da571 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.hpp +++ b/include/Nazara/Graphics/ForwardRenderTechnique.hpp @@ -32,23 +32,27 @@ class NAZARA_API NzForwardRenderTechnique : public NzAbstractRenderTechnique, Nz void SetMaxLightPassPerObject(unsigned int passCount); private: - struct LightUniforms; + struct ShaderUniforms; void DrawBasicSprites(const NzScene* scene) const; void DrawOpaqueModels(const NzScene* scene) const; void DrawTransparentModels(const NzScene* scene) const; - const LightUniforms* GetLightUniforms(const NzShader* shader) const; + const ShaderUniforms* GetShaderUniforms(const NzShader* shader) const; - struct LightUniforms + struct ShaderUniforms { - NzLightUniforms uniforms; - bool exists; - int offset; // "Distance" entre Lights[0].type et Lights[1].type + 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 textureOverlay; }; - mutable std::unordered_map m_lightUniforms; + mutable std::unordered_map m_shaderUniforms; mutable NzForwardRenderQueue m_renderQueue; NzIndexBufferRef m_indexBuffer; mutable NzLightManager m_directionalLights; diff --git a/include/Nazara/Renderer/Enums.hpp b/include/Nazara/Renderer/Enums.hpp index fa9fc9a3d..0065f55b2 100644 --- a/include/Nazara/Renderer/Enums.hpp +++ b/include/Nazara/Renderer/Enums.hpp @@ -187,6 +187,7 @@ enum nzSamplerWrap enum nzShaderUniform { + ///FIXME: Virer EyePosition, SceneAmbient et TargetSize de l'énumération (ils n'ont rien à faire dans le module de rendu) nzShaderUniform_EyePosition, nzShaderUniform_InvProjMatrix, nzShaderUniform_InvTargetSize, diff --git a/src/Nazara/Graphics/DeferredRenderQueue.cpp b/src/Nazara/Graphics/DeferredRenderQueue.cpp index 4c3d0cd35..821e92d86 100644 --- a/src/Nazara/Graphics/DeferredRenderQueue.cpp +++ b/src/Nazara/Graphics/DeferredRenderQueue.cpp @@ -103,7 +103,7 @@ void NzDeferredRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData } } -void NzDeferredRenderQueue::AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount) +void NzDeferredRenderQueue::AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay) { /*NzMaterial* material = sprite->GetMaterial(); if (!material->IsLightingEnabled() || material->IsEnabled(nzRendererParameter_Blend)) @@ -111,7 +111,7 @@ void NzDeferredRenderQueue::AddSprites(const NzMaterial* material, const NzVerte else sprites[material].push_back(sprite);*/ - m_forwardQueue->AddSprites(material, vertices, spriteCount); + m_forwardQueue->AddSprites(material, vertices, spriteCount, overlay); } void NzDeferredRenderQueue::Clear(bool fully) diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index b0d1be9d6..254194e87 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -20,6 +20,7 @@ namespace { ResourceType_IndexBuffer, ResourceType_Material, + ResourceType_Texture, ResourceType_VertexBuffer }; } @@ -123,16 +124,25 @@ void NzForwardRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& } } -void NzForwardRenderQueue::AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount) +void NzForwardRenderQueue::AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay) { - BasicSpriteBatches::iterator it = basicSprites.find(material); - if (it == basicSprites.end()) + auto matIt = basicSprites.find(material); + if (matIt == basicSprites.end()) { - it = basicSprites.insert(std::make_pair(material, BasicSpriteBatches::mapped_type())).first; + matIt = basicSprites.insert(std::make_pair(material, BasicSpriteBatches::mapped_type())).first; material->AddResourceListener(this, ResourceType_Material); } - auto& spriteVector = it->second; + auto& overlayMap = matIt->second; + auto overlayIt = overlayMap.find(overlay); + if (overlayIt == overlayMap.end()) + { + overlayIt = overlayMap.insert(std::make_pair(overlay, BasicSpriteOverlayContainer::mapped_type())).first; + if (overlay) + overlay->AddResourceListener(this, ResourceType_Texture); + } + + auto& spriteVector = overlayIt->second; spriteVector.push_back(SpriteChain_XYZ_Color_UV({vertices, spriteCount})); } @@ -146,19 +156,26 @@ void NzForwardRenderQueue::Clear(bool fully) if (fully) { - for (auto& matIt : basicSprites) + for (auto& matPair : basicSprites) { - const NzMaterial* material = matIt.first; + const NzMaterial* material = matPair.first; material->RemoveResourceListener(this); + + auto& overlayMap = matPair.second; + for (auto& overlayPair : overlayMap) + { + const NzTexture* overlay = overlayPair.first; + overlay->RemoveResourceListener(this); + } } basicSprites.clear(); - for (auto& matIt : opaqueModels) + for (auto& matPair : opaqueModels) { - const NzMaterial* material = matIt.first; + const NzMaterial* material = matPair.first; material->RemoveResourceListener(this); - MeshInstanceContainer& instances = std::get<2>(matIt.second); + MeshInstanceContainer& instances = std::get<2>(matPair.second); for (auto& instanceIt : instances) { const NzMeshData& renderData = instanceIt.first; @@ -284,6 +301,24 @@ void NzForwardRenderQueue::OnResourceReleased(const NzResource* resource, int in break; } + case ResourceType_Texture: + { + for (auto matIt = basicSprites.begin(); matIt != basicSprites.end(); ++matIt) + { + auto& overlayMap = matIt->second; + for (auto overlayIt = overlayMap.begin(); overlayIt != overlayMap.end(); ++overlayIt) + { + if (overlayIt->first == resource) + { + overlayMap.erase(overlayIt); + break; + } + } + } + + break; + } + case ResourceType_VertexBuffer: { for (auto& modelPair : opaqueModels) diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 03cac541c..6764c271a 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -166,6 +166,7 @@ void NzForwardRenderTechnique::DrawBasicSprites(const NzScene* scene) const { NzAbstractViewer* viewer = scene->GetViewer(); const NzShader* lastShader = nullptr; + const ShaderUniforms* shaderUniforms = nullptr; NzRenderer::SetIndexBuffer(m_indexBuffer); NzRenderer::SetMatrix(nzMatrixType_World, NzMatrix4f::Identity()); @@ -174,61 +175,84 @@ void NzForwardRenderTechnique::DrawBasicSprites(const NzScene* scene) const for (auto& matIt : m_renderQueue.basicSprites) { const NzMaterial* material = matIt.first; - auto& spriteChainVector = matIt.second; + auto& overlayMap = matIt.second; - unsigned int spriteChainCount = spriteChainVector.size(); - if (spriteChainCount > 0) + for (auto& overlayIt : overlayMap) { - // On commence par appliquer du matériau (et récupérer le shader ainsi activé) - const NzShader* shader = material->Apply(nzShaderFlags_VertexColor); + const NzTexture* overlay = overlayIt.first; + auto& spriteChainVector = overlayIt.second; - // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas - if (shader != lastShader) + unsigned int spriteChainCount = spriteChainVector.size(); + if (spriteChainCount > 0) { - // Couleur ambiante de la scène - shader->SendColor(shader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); - // Position de la caméra - shader->SendVector(shader->GetUniformLocation(nzShaderUniform_EyePosition), viewer->GetEyePosition()); + // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + nzUInt32 flags = nzShaderFlags_VertexColor; + if (overlay) + flags |= nzShaderFlags_TextureOverlay; - lastShader = shader; - } + nzUInt8 overlayUnit; + const NzShader* shader = material->Apply(flags, 0, &overlayUnit); - 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; + if (overlay) { - NzForwardRenderQueue::SpriteChain_XYZ_Color_UV& currentChain = spriteChainVector[spriteChain]; - unsigned int count = std::min(s_maxSprites - 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; - } + overlayUnit++; + NzRenderer::SetTexture(overlayUnit, overlay); + NzRenderer::SetTextureSampler(overlayUnit, material->GetDiffuseSampler()); } - while (spriteCount < s_maxSprites && spriteChain < spriteChainCount); - vertexMapper.Unmap(); + // 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); - NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, spriteCount*6); + // Couleur ambiante de la scène + shader->SendColor(shader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); + // Overlay + shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); + // Position de la caméra + shader->SendVector(shader->GetUniformLocation(nzShaderUniform_EyePosition), 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 + NzBufferMapper vertexMapper(m_spriteBuffer, nzBufferAccess_DiscardAndWrite); + NzVertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(vertexMapper.GetPointer()); + + unsigned int spriteCount = 0; + { + NzForwardRenderQueue::SpriteChain_XYZ_Color_UV& currentChain = spriteChainVector[spriteChain]; + unsigned int count = std::min(s_maxSprites - 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 < s_maxSprites && spriteChain < spriteChainCount); + + vertexMapper.Unmap(); + + NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, spriteCount*6); + } + while (spriteChain < spriteChainCount); + + spriteChainVector.clear(); } - while (spriteChain < spriteChainCount); - - spriteChainVector.clear(); } } } @@ -236,8 +260,8 @@ void NzForwardRenderTechnique::DrawBasicSprites(const NzScene* scene) const void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const { NzAbstractViewer* viewer = scene->GetViewer(); - const LightUniforms* lightUniforms = nullptr; const NzShader* lastShader = nullptr; + const ShaderUniforms* shaderUniforms = nullptr; for (auto& matIt : m_renderQueue.opaqueModels) { @@ -262,14 +286,14 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const // 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(shader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); // Position de la caméra shader->SendVector(shader->GetUniformLocation(nzShaderUniform_EyePosition), viewer->GetEyePosition()); - // Index des uniformes d'éclairage dans le shader - lightUniforms = GetLightUniforms(shader); - lastShader = shader; } @@ -321,7 +345,7 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const unsigned int passCount = (lightCount == 0) ? 1 : (lightCount-1)/NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS + 1; for (unsigned int pass = 0; pass < passCount; ++pass) { - if (lightUniforms->exists) + if (shaderUniforms->hasLightUniforms) { unsigned int renderedLightCount = std::min(lightCount, NazaraSuffixMacro(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS, U)); lightCount -= renderedLightCount; @@ -338,10 +362,10 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const } for (unsigned int i = 0; i < renderedLightCount; ++i) - m_directionalLights.GetLight(lightIndex++)->Enable(shader, lightUniforms->uniforms, lightUniforms->offset*i); + m_directionalLights.GetLight(lightIndex++)->Enable(shader, shaderUniforms->lightUniforms, shaderUniforms->lightOffset*i); for (unsigned int i = renderedLightCount; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) - NzLight::Disable(shader, lightUniforms->uniforms, lightUniforms->offset*i); + NzLight::Disable(shader, shaderUniforms->lightUniforms, shaderUniforms->lightOffset*i); } const NzMatrix4f* instanceMatrices = &instances[0]; @@ -369,7 +393,7 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const } else { - if (lightUniforms->exists) + if (shaderUniforms->hasLightUniforms) { for (const NzMatrix4f& matrix : instances) { @@ -403,14 +427,14 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const for (unsigned int i = 0; i < renderedLightCount; ++i) { if (directionalLightIndex >= directionalLightCount) - m_lights.GetResult(otherLightIndex++)->Enable(shader, lightUniforms->uniforms, lightUniforms->offset*i); + m_lights.GetResult(otherLightIndex++)->Enable(shader, shaderUniforms->lightUniforms, shaderUniforms->lightOffset*i); else - m_directionalLights.GetLight(directionalLightIndex++)->Enable(shader, lightUniforms->uniforms, lightUniforms->offset*i); + m_directionalLights.GetLight(directionalLightIndex++)->Enable(shader, shaderUniforms->lightUniforms, shaderUniforms->lightOffset*i); } // On désactive l'éventuel surplus for (unsigned int i = renderedLightCount; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) - NzLight::Disable(shader, lightUniforms->uniforms, lightUniforms->offset*i); + NzLight::Disable(shader, shaderUniforms->lightUniforms, shaderUniforms->lightOffset*i); // Et on passe à l'affichage DrawFunc(meshData.primitiveMode, 0, indexCount); @@ -438,8 +462,8 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const } // Et on remet à zéro les données - renderQueueInstancing = false; used = false; + renderQueueInstancing = false; } } } @@ -447,8 +471,8 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const void NzForwardRenderTechnique::DrawTransparentModels(const NzScene* scene) const { NzAbstractViewer* viewer = scene->GetViewer(); - const LightUniforms* lightUniforms = nullptr; const NzShader* lastShader = nullptr; + const ShaderUniforms* shaderUniforms = nullptr; unsigned int lightCount = 0; for (unsigned int index : m_renderQueue.transparentModels) @@ -464,18 +488,18 @@ void NzForwardRenderTechnique::DrawTransparentModels(const NzScene* scene) const // 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(shader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); // Position de la caméra shader->SendVector(shader->GetUniformLocation(nzShaderUniform_EyePosition), viewer->GetEyePosition()); - // Index des uniformes d'éclairage dans le shader - lightUniforms = GetLightUniforms(shader); - // On envoie les lumières directionnelles s'il y a (Les mêmes pour tous) lightCount = std::min(m_directionalLights.GetLightCount(), NazaraSuffixMacro(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS, U)); for (unsigned int i = 0; i < lightCount; ++i) - m_directionalLights.GetLight(i)->Enable(shader, lightUniforms->uniforms, lightUniforms->offset*i); + m_directionalLights.GetLight(i)->Enable(shader, shaderUniforms->lightUniforms, shaderUniforms->lightOffset*i); lastShader = shader; } @@ -510,45 +534,46 @@ void NzForwardRenderTechnique::DrawTransparentModels(const NzScene* scene) const { unsigned int count = std::min(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS - lightCount, m_lights.ComputeClosestLights(matrix.GetTranslation() + modelData.boundingSphere.GetPosition(), modelData.boundingSphere.radius, NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS)); for (unsigned int i = 0; i < count; ++i) - m_lights.GetResult(i)->Enable(shader, lightUniforms->uniforms, lightUniforms->offset*(lightCount++)); + m_lights.GetResult(i)->Enable(shader, shaderUniforms->lightUniforms, shaderUniforms->lightOffset*(lightCount++)); } for (unsigned int i = lightCount; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) - NzLight::Disable(shader, lightUniforms->uniforms, lightUniforms->offset*i); + NzLight::Disable(shader, shaderUniforms->lightUniforms, shaderUniforms->lightOffset*i); NzRenderer::SetMatrix(nzMatrixType_World, matrix); DrawFunc(meshData.primitiveMode, 0, indexCount); } } -const NzForwardRenderTechnique::LightUniforms* NzForwardRenderTechnique::GetLightUniforms(const NzShader* shader) const +const NzForwardRenderTechnique::ShaderUniforms* NzForwardRenderTechnique::GetShaderUniforms(const NzShader* shader) const { - auto it = m_lightUniforms.find(shader); - if (it != m_lightUniforms.end()) + auto it = m_shaderUniforms.find(shader); + if (it != m_shaderUniforms.end()) return &(it->second); else { + ShaderUniforms uniforms; + uniforms.textureOverlay = shader->GetUniformLocation("TextureOverlay"); + int type0Location = shader->GetUniformLocation("Lights[0].type"); int type1Location = shader->GetUniformLocation("Lights[1].type"); - LightUniforms lightUniforms; - if (type0Location > 0 && type1Location > 0) { - lightUniforms.exists = true; - lightUniforms.offset = type1Location - type0Location; - lightUniforms.uniforms.ubo = false; - lightUniforms.uniforms.locations.type = type0Location; - lightUniforms.uniforms.locations.color = shader->GetUniformLocation("Lights[0].color"); - lightUniforms.uniforms.locations.factors = shader->GetUniformLocation("Lights[0].factors"); - lightUniforms.uniforms.locations.parameters1 = shader->GetUniformLocation("Lights[0].parameters1"); - lightUniforms.uniforms.locations.parameters2 = shader->GetUniformLocation("Lights[0].parameters2"); - lightUniforms.uniforms.locations.parameters3 = shader->GetUniformLocation("Lights[0].parameters3"); + uniforms.hasLightUniforms = true; + uniforms.lightOffset = type1Location - type0Location; + uniforms.lightUniforms.ubo = false; + 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.parameters1 = shader->GetUniformLocation("Lights[0].parameters1"); + uniforms.lightUniforms.locations.parameters2 = shader->GetUniformLocation("Lights[0].parameters2"); + uniforms.lightUniforms.locations.parameters3 = shader->GetUniformLocation("Lights[0].parameters3"); } else - lightUniforms.exists = false; + uniforms.hasLightUniforms = false; - auto pair = m_lightUniforms.emplace(shader, lightUniforms); + auto pair = m_shaderUniforms.emplace(shader, uniforms); return &(pair.first->second); } } diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 2774b42fa..24e26613d 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -687,11 +687,13 @@ void NzMaterial::GenerateShader(nzUInt32 flags) const list.SetParameter("PARALLAX_MAPPING", m_heightMap.IsValid()); 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()); + m_normalMap.IsValid() || m_heightMap.IsValid() || m_specularMap.IsValid() || + flags & nzShaderFlags_TextureOverlay); list.SetParameter("TRANSFORM", m_transformEnabled); list.SetParameter("FLAG_DEFERRED", static_cast((flags & nzShaderFlags_Deferred) != 0)); list.SetParameter("FLAG_INSTANCING", static_cast((flags & nzShaderFlags_Instancing) != 0)); + list.SetParameter("FLAG_TEXTUREOVERLAY", static_cast((flags & nzShaderFlags_TextureOverlay) != 0)); list.SetParameter("FLAG_VERTEXCOLOR", static_cast((flags & nzShaderFlags_VertexColor) != 0)); ShaderInstance& instance = m_shaders[flags]; @@ -759,7 +761,7 @@ bool NzMaterial::Initialize() vertexShader.Set(reinterpret_cast(compatibilityVertexShader), sizeof(compatibilityVertexShader)); } - uberShader->SetShader(nzShaderStage_Fragment, fragmentShader, "ALPHA_MAPPING ALPHA_TEST AUTO_TEXCOORDS DIFFUSE_MAPPING"); + uberShader->SetShader(nzShaderStage_Fragment, fragmentShader, "FLAG_TEXTUREOVERLAY ALPHA_MAPPING ALPHA_TEST AUTO_TEXCOORDS DIFFUSE_MAPPING"); uberShader->SetShader(nzShaderStage_Vertex, vertexShader, "FLAG_INSTANCING FLAG_VERTEXCOLOR TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); NzUberShaderLibrary::Register("Basic", uberShader.get()); @@ -800,7 +802,7 @@ bool NzMaterial::Initialize() vertexShader.Set(reinterpret_cast(compatibilityVertexShader), sizeof(compatibilityVertexShader)); } - uberShader->SetShader(nzShaderStage_Fragment, fragmentShader, "FLAG_DEFERRED ALPHA_MAPPING ALPHA_TEST DIFFUSE_MAPPING EMISSIVE_MAPPING LIGHTING NORMAL_MAPPING PARALLAX_MAPPING SPECULAR_MAPPING"); + uberShader->SetShader(nzShaderStage_Fragment, fragmentShader, "FLAG_DEFERRED FLAG_TEXTUREOVERLAY ALPHA_MAPPING ALPHA_TEST DIFFUSE_MAPPING EMISSIVE_MAPPING LIGHTING NORMAL_MAPPING PARALLAX_MAPPING SPECULAR_MAPPING"); uberShader->SetShader(nzShaderStage_Vertex, vertexShader, "FLAG_DEFERRED FLAG_INSTANCING FLAG_VERTEXCOLOR COMPUTE_TBNMATRIX LIGHTING PARALLAX_MAPPING TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); NzUberShaderLibrary::Register("PhongLighting", uberShader.get()); diff --git a/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag b/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag index 57068325d..53844cbc6 100644 --- a/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag +++ b/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag @@ -10,11 +10,12 @@ in vec2 vTexCoord; out vec4 RenderTarget0; /********************Uniformes********************/ +uniform vec2 InvTargetSize; uniform sampler2D MaterialAlphaMap; uniform float MaterialAlphaThreshold; uniform vec4 MaterialDiffuse; uniform sampler2D MaterialDiffuseMap; -uniform vec2 InvTargetSize; +uniform sampler2D TextureOverlay; /********************Fonctions********************/ void main() @@ -35,6 +36,10 @@ void main() fragmentColor.a *= texture(MaterialAlphaMap, texCoord).r; #endif +#if FLAG_TEXTUREOVERLAY + fragmentColor *= texture(TextureOverlay, texCoord); +#endif + #if ALPHA_TEST if (fragmentColor.a < MaterialAlphaThreshold) discard; diff --git a/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag.h b/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag.h index 319917ab6..c6eff909e 100644 --- a/src/Nazara/Graphics/Resources/Shaders/Basic/core.frag.h +++ b/src/Nazara/Graphics/Resources/Shaders/Basic/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,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,50,32,118,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,82,101,110,100,101,114,84,97,114,103,101,116,48,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,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,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,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,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,9,118,101,99,52,32,102,114,97,103,109,101,110,116,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,68,73,70,70,85,83,69,95,77,65,80,80,73,78,71,13,10,9,102,114,97,103,109,101,110,116,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,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,102,114,97,103,109,101,110,116,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,35,101,110,100,105,102,13,10,13,10,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,105,102,32,40,102,114,97,103,109,101,110,116,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,35,101,110,100,105,102,13,10,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,125, \ 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,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,50,32,118,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,82,101,110,100,101,114,84,97,114,103,101,116,48,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,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,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,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,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,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,118,101,99,52,32,102,114,97,103,109,101,110,116,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,68,73,70,70,85,83,69,95,77,65,80,80,73,78,71,13,10,9,102,114,97,103,109,101,110,116,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,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,102,114,97,103,109,101,110,116,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,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,102,114,97,103,109,101,110,116,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,65,76,80,72,65,95,84,69,83,84,13,10,9,105,102,32,40,102,114,97,103,109,101,110,116,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,35,101,110,100,105,102,13,10,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,125, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag index cf0f596da..b60249edf 100644 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag +++ b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag @@ -50,6 +50,8 @@ uniform float ParallaxBias = -0.03; uniform float ParallaxScale = 0.02; uniform vec4 SceneAmbient; +uniform sampler2D TextureOverlay; + /********************Fonctions********************/ vec3 FloatToColor(float f) { @@ -91,6 +93,10 @@ void main() diffuseColor *= texture(MaterialDiffuseMap, texCoord); #endif +#if FLAG_TEXTUREOVERLAY + diffuseColor *= texture(TextureOverlay, texCoord); +#endif + #if FLAG_DEFERRED #if ALPHA_TEST #if ALPHA_MAPPING // Inutile de faire de l'alpha-mapping sans alpha-test en Deferred (l'alpha n'est pas sauvegardé) diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/core.frag.h index 60271acaf..bd6058130 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,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,76,105,103,104,116,32,76,105,103,104,116,115,91,51,93,59,13,10,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,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,52,32,83,99,101,110,101,65,109,98,105,101,110,116,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,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,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,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,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,32,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,41,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,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,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,76,105,103,104,116,32,76,105,103,104,116,115,91,51,93,59,13,10,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,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,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,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,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,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,32,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,41,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 From 904319ee90e6e562535143b648086839b7349e3e Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 7 Jan 2015 21:03:29 +0100 Subject: [PATCH 131/233] Improved/Fixed Texture class Allowed move constructor/operator Fixed Texture::Download/Texture::Update Made InvalidateMipmaps public Former-commit-id: b8b6a54bc5d6250f640fed6582dc694df6405f73 --- include/Nazara/Renderer/Texture.hpp | 7 +++- src/Nazara/Renderer/Texture.cpp | 59 +++++++++++++++-------------- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/include/Nazara/Renderer/Texture.hpp b/include/Nazara/Renderer/Texture.hpp index 52abbe3fc..5c082cc2e 100644 --- a/include/Nazara/Renderer/Texture.hpp +++ b/include/Nazara/Renderer/Texture.hpp @@ -26,11 +26,12 @@ struct NzTextureImpl; class NAZARA_API NzTexture : public NzAbstractImage, public NzResource, NzNonCopyable { friend class NzRenderer; - friend class NzRenderTexture; public: NzTexture() = default; + NzTexture(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth = 1, nzUInt8 levelCount = 1); explicit NzTexture(const NzImage& image); + NzTexture(NzTexture&& texture); ~NzTexture(); bool Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth = 1, nzUInt8 levelCount = 1); @@ -55,6 +56,7 @@ class NAZARA_API NzTexture : public NzAbstractImage, public NzResource, NzNonCop bool HasMipmaps() const; + void InvalidateMipmaps(); bool IsValid() const; // Load @@ -92,6 +94,8 @@ class NAZARA_API NzTexture : public NzAbstractImage, public NzResource, NzNonCop // Fonctions OpenGL unsigned int GetOpenGLID() const; + NzTexture& operator=(NzTexture&& texture); + static unsigned int GetValidSize(unsigned int size); static bool IsFormatSupported(nzPixelFormat format); static bool IsMipmappingSupported(); @@ -99,7 +103,6 @@ class NAZARA_API NzTexture : public NzAbstractImage, public NzResource, NzNonCop private: bool CreateTexture(bool proxy); - void InvalidateMipmaps(); NzTextureImpl* m_impl = nullptr; }; diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index 855a70e2f..6861a8e69 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -47,17 +48,22 @@ namespace } } +NzTexture::NzTexture(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth, nzUInt8 levelCount) +{ + NzErrorFlags flags(nzErrorFlag_ThrowException); + Create(type, format, width, height, depth, levelCount); +} + NzTexture::NzTexture(const NzImage& image) { + NzErrorFlags flags(nzErrorFlag_ThrowException); LoadFromImage(image); +} - #ifdef NAZARA_DEBUG - if (!m_impl) - { - NazaraError("Failed to create texture"); - throw std::runtime_error("Constructor failed"); - } - #endif +NzTexture::NzTexture(NzTexture&& texture) : +m_impl(texture.m_impl) +{ + texture.m_impl = nullptr; } NzTexture::~NzTexture() @@ -248,30 +254,11 @@ bool NzTexture::Download(NzImage* image) const return false; } - unsigned int width = m_impl->width; - unsigned int height = m_impl->height; - unsigned int depth = m_impl->depth; - // Téléchargement... NzOpenGL::BindTexture(m_impl->type, m_impl->id); for (nzUInt8 level = 0; level < m_impl->levelCount; ++level) - { glGetTexImage(NzOpenGL::TextureTarget[m_impl->type], level, format.dataFormat, format.dataType, image->GetPixels(level)); - if (width > 1) - width >>= 1; - - if (height > 1) - height >>= 1; - - if (depth > 1) - depth >>= 1; - } - - // Inversion de la texture pour le repère d'OpenGL - if (!image->FlipVertically()) - NazaraWarning("Failed to flip image"); - return true; } @@ -292,7 +279,11 @@ bool NzTexture::EnableMipmapping(bool enable) } if (m_impl->levelCount == 1) // Transformation d'une texture sans mipmaps vers une texture avec mipmaps + { + ///FIXME: Est-ce que cette opération est seulement possible ? m_impl->levelCount = NzImage::GetMaxLevel(m_impl->width, m_impl->height, m_impl->depth); + SetMipmapRange(0, m_impl->levelCount-1); + } if (!m_impl->mipmapping && enable) m_impl->mipmapsUpdated = false; @@ -1006,16 +997,16 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int s case nzImageType_1D_Array: case nzImageType_2D: - glTexSubImage2D(NzOpenGL::TextureTarget[m_impl->type], level, box.x, height-box.height-box.y, box.width, box.height, format.dataFormat, format.dataType, pixels); + glTexSubImage2D(NzOpenGL::TextureTarget[m_impl->type], level, box.x, box.y, box.width, box.height, format.dataFormat, format.dataType, pixels); break; case nzImageType_2D_Array: case nzImageType_3D: - glTexSubImage3D(NzOpenGL::TextureTarget[m_impl->type], level, box.x, height-box.height-box.y, box.z, box.width, box.height, box.depth, format.dataFormat, format.dataType, pixels); + glTexSubImage3D(NzOpenGL::TextureTarget[m_impl->type], level, box.x, box.y, box.z, box.width, box.height, box.depth, format.dataFormat, format.dataType, pixels); break; case nzImageType_Cubemap: - glTexSubImage2D(NzOpenGL::CubemapFace[box.z], level, box.x, height-box.height-box.y, box.width, box.height, format.dataFormat, format.dataType, pixels); + glTexSubImage2D(NzOpenGL::CubemapFace[box.z], level, box.x, box.y, box.width, box.height, format.dataFormat, format.dataType, pixels); break; } @@ -1040,6 +1031,16 @@ unsigned int NzTexture::GetOpenGLID() const return m_impl->id; } +NzTexture& NzTexture::operator=(NzTexture&& texture) +{ + Destroy(); + + m_impl = texture.m_impl; + texture.m_impl = nullptr; + + return *this; +} + unsigned int NzTexture::GetValidSize(unsigned int size) { if (NzRenderer::HasCapability(nzRendererCap_TextureNPOT)) From 586aac534bee7b5e79a7bfb05ac0c0b4b411ff2a Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 7 Jan 2015 21:03:57 +0100 Subject: [PATCH 132/233] Improved Image error on construction handling Former-commit-id: 5b40aab103d90bb29baedf65d481b2495717af8d --- src/Nazara/Utility/Image.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index 0532294bb..4cc9297d2 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -44,15 +45,8 @@ m_sharedImage(&emptyImage) NzImage::NzImage(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth, nzUInt8 levelCount) : m_sharedImage(&emptyImage) { + NzErrorFlags flags(nzErrorFlag_ThrowException); Create(type, format, width, height, depth, levelCount); - - #ifdef NAZARA_DEBUG - if (!m_sharedImage) - { - NazaraError("Failed to create image"); - throw std::runtime_error("Constructor failed"); - } - #endif } NzImage::NzImage(const NzImage& image) : From 09856d42e3e8676c07501c061e235f60cdf2eb6c Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 7 Jan 2015 23:42:07 +0100 Subject: [PATCH 133/233] Fixed Texture::Download with mipmaps Former-commit-id: 1c2f6bd9fdd580e3fd5a6425bfa49251766676d2 --- src/Nazara/Renderer/Texture.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index 6861a8e69..80b580312 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -257,7 +257,7 @@ bool NzTexture::Download(NzImage* image) const // Téléchargement... NzOpenGL::BindTexture(m_impl->type, m_impl->id); for (nzUInt8 level = 0; level < m_impl->levelCount; ++level) - glGetTexImage(NzOpenGL::TextureTarget[m_impl->type], level, format.dataFormat, format.dataType, image->GetPixels(level)); + glGetTexImage(NzOpenGL::TextureTarget[m_impl->type], level, format.dataFormat, format.dataType, image->GetPixels(0, 0, 0, level)); return true; } From b61ff3a0d17e196151cb85d883a5a8738b3d9eb4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 7 Jan 2015 23:42:45 +0100 Subject: [PATCH 134/233] (FreeType) Made Bold more strong Former-commit-id: 9bee352eb567fc51d9d34e73a16fe9340de49d82 --- src/Nazara/Utility/Loaders/FreeType/Loader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Utility/Loaders/FreeType/Loader.cpp b/src/Nazara/Utility/Loaders/FreeType/Loader.cpp index 71269d9da..46b91ffe8 100644 --- a/src/Nazara/Utility/Loaders/FreeType/Loader.cpp +++ b/src/Nazara/Utility/Loaders/FreeType/Loader.cpp @@ -95,7 +95,7 @@ namespace FT_GlyphSlot& glyph = m_face->glyph; - const FT_Pos boldStrength = 1 << 6; + const FT_Pos boldStrength = 2 << 6; bool outlineFormat = (glyph->format == FT_GLYPH_FORMAT_OUTLINE); if (outlineFormat && bold) From b6c5668232624bd1cd144ea5f5ec3ab9c9c11c0e Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 7 Jan 2015 23:46:26 +0100 Subject: [PATCH 135/233] Separated atlases from Font class First use of shared_ptr, yay! Former-commit-id: 4c22341fba5674746d5299cf0e8dbf6dc31d5362 --- .../Graphics/GuillotineTextureAtlas.hpp | 24 ++ include/Nazara/Utility/AbstractFontAtlas.hpp | 40 +++ include/Nazara/Utility/Font.hpp | 77 +++-- .../Nazara/Utility/GuillotineImageAtlas.hpp | 68 +++++ .../Graphics/GuillotineTextureAtlas.cpp | 57 ++++ src/Nazara/Utility/Font.cpp | 265 ++++-------------- src/Nazara/Utility/GuillotineImageAtlas.cpp | 244 ++++++++++++++++ 7 files changed, 522 insertions(+), 253 deletions(-) create mode 100644 include/Nazara/Graphics/GuillotineTextureAtlas.hpp create mode 100644 include/Nazara/Utility/AbstractFontAtlas.hpp create mode 100644 include/Nazara/Utility/GuillotineImageAtlas.hpp create mode 100644 src/Nazara/Graphics/GuillotineTextureAtlas.cpp create mode 100644 src/Nazara/Utility/GuillotineImageAtlas.cpp diff --git a/include/Nazara/Graphics/GuillotineTextureAtlas.hpp b/include/Nazara/Graphics/GuillotineTextureAtlas.hpp new file mode 100644 index 000000000..3eb14dd68 --- /dev/null +++ b/include/Nazara/Graphics/GuillotineTextureAtlas.hpp @@ -0,0 +1,24 @@ +// 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_GUILLOTINETEXTUREATLAS_HPP +#define NAZARA_GUILLOTINETEXTUREATLAS_HPP + +#include +#include + +class NAZARA_API NzGuillotineTextureAtlas : public NzGuillotineImageAtlas +{ + public: + NzGuillotineTextureAtlas() = default; + ~NzGuillotineTextureAtlas() = default; + + private: + unsigned int GetMaxAtlasSize() const override; + bool ResizeImage(Layer& layer, const NzVector2ui& size) const override; +}; + +#endif // NAZARA_GUILLOTINETEXTUREATLAS_HPP diff --git a/include/Nazara/Utility/AbstractFontAtlas.hpp b/include/Nazara/Utility/AbstractFontAtlas.hpp new file mode 100644 index 000000000..f3f06346a --- /dev/null +++ b/include/Nazara/Utility/AbstractFontAtlas.hpp @@ -0,0 +1,40 @@ +// 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_ABSTRACTFONTATLAS_HPP +#define NAZARA_ABSTRACTFONTATLAS_HPP + +#include +#include +#include +#include + +class NzAbstractImage; +class NzFont; +class NzImage; + +class NAZARA_API NzAbstractFontAtlas +{ + public: + NzAbstractFontAtlas() = default; + virtual ~NzAbstractFontAtlas(); + + virtual void Clear() = 0; + virtual void Free(NzSparsePtr rects, NzSparsePtr layers, unsigned int count) = 0; + virtual NzAbstractImage* GetLayer(unsigned int layerIndex) const = 0; + virtual unsigned int GetLayerCount() const = 0; + virtual bool Insert(const NzImage& image, NzRectui* rect, bool* flipped, unsigned int* layerIndex) = 0; + void RegisterFont(NzFont* font); + void UnregisterFont(NzFont* font); + + protected: + void NotifyCleared(); + + private: + std::set m_registredFonts; +}; + +#endif // NAZARA_ABSTRACTFONTATLAS_HPP diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index 190d3c716..2264b7604 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -8,11 +8,10 @@ #define NAZARA_FONT_HPP #include -#include #include #include #include -#include +#include #include #include @@ -24,7 +23,7 @@ struct NAZARA_API NzFontParams class NzFont; class NzFontData; -struct NzFontGlyph; // TEMP +struct NzFontGlyph; using NzFontConstRef = NzResourceRef; using NzFontLoader = NzResourceLoader; @@ -32,31 +31,12 @@ using NzFontRef = NzResourceRef; class NAZARA_API NzFont : public NzResource, NzNonCopyable { + friend NzAbstractFontAtlas; friend NzFontLoader; public: - struct Atlas - { - NzGuillotineBinPack binPack; - NzImage image; - }; - - struct Glyph - { - NzRecti aabb; - NzRectui atlasRect; - bool flipped; - bool valid; - int advance; - unsigned int atlasIndex; - }; - - struct SizeInfo - { - unsigned int lineHeight; - float underlinePosition; - float underlineThickness; - }; + struct Glyph; + struct SizeInfo; NzFont(); NzFont(NzFont&& font) = default; @@ -71,14 +51,12 @@ class NAZARA_API NzFont : public NzResource, NzNonCopyable bool ExtractGlyph(unsigned int characterSize, char32_t character, nzUInt32 style, NzFontGlyph* glyph) const; - const Atlas& GetAtlas(unsigned int atlasIndex) const; - unsigned int GetAtlasCount() const; + const NzAbstractFontAtlas* GetAtlas() const; unsigned int GetCachedGlyphCount(unsigned int characterSize, nzUInt32 style) const; unsigned int GetCachedGlyphCount() const; NzString GetFamilyName() const; int GetKerning(unsigned int characterSize, char32_t first, char32_t second) const; const Glyph& GetGlyph(unsigned int characterSize, nzUInt32 style, char32_t character) const; - unsigned int GetMaxAtlasSize() const; unsigned int GetMinimumStepSize() const; const SizeInfo& GetSizeInfo(unsigned int characterSize) const; NzString GetStyleName() const; @@ -93,41 +71,50 @@ class NAZARA_API NzFont : public NzResource, NzNonCopyable bool OpenFromMemory(const void* data, std::size_t size, const NzFontParams& params = NzFontParams()); bool OpenFromStream(NzInputStream& stream, const NzFontParams& params = NzFontParams()); - void SetMaxAtlasSize(unsigned int maxAtlasSize); + void SetAtlas(std::shared_ptr atlas); void SetMinimumStepSize(unsigned int minimumSizeStep); NzFont& operator=(NzFont&& font) = default; - static unsigned int GetDefaultMaxAtlasSize(); - static void SetDefaultMaxAtlasSize(unsigned int maxAtlasSize); + enum ModicationCode + { + ModificationCode_GlyphCacheCleared, + ModificationCode_KerningCacheCleared, + ModificationCode_SizeInfoCacheCleared + }; + + struct Glyph + { + NzRecti aabb; + NzRectui atlasRect; + bool flipped; + bool valid; + int advance; + unsigned int layerIndex; + }; + + struct SizeInfo + { + unsigned int lineHeight; + float underlinePosition; + float underlineThickness; + }; private: using GlyphMap = std::unordered_map; - struct QueuedGlyph - { - char32_t codepoint; - NzImage image; - GlyphMap* map; - }; - nzUInt64 ComputeKey(unsigned int characterSize, nzUInt32 style) const; - unsigned int GetRealMaxAtlasSize() const; - unsigned int InsertRect(NzRectui* rect, bool* flipped) const; + void OnAtlasCleared(); const Glyph& PrecacheGlyph(GlyphMap& glyphMap, unsigned int characterSize, bool bold, char32_t character) const; - void ProcessGlyphQueue() const; + std::shared_ptr m_atlas; std::unique_ptr m_data; mutable std::unordered_map> m_kerningCache; mutable std::unordered_map m_glyphes; mutable std::unordered_map m_sizeInfoCache; - mutable std::vector m_atlases; - mutable std::vector m_glyphQueue; - unsigned int m_maxAtlasSize; unsigned int m_minimumSizeStep; static NzFontLoader::LoaderList s_loaders; - static unsigned int s_maxAtlasSize; }; #endif // NAZARA_FONT_HPP diff --git a/include/Nazara/Utility/GuillotineImageAtlas.hpp b/include/Nazara/Utility/GuillotineImageAtlas.hpp new file mode 100644 index 000000000..dc1542560 --- /dev/null +++ b/include/Nazara/Utility/GuillotineImageAtlas.hpp @@ -0,0 +1,68 @@ +// 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_GUILLOTINEIMAGEATLAS_HPP +#define NAZARA_GUILLOTINEIMAGEATLAS_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +class NAZARA_API NzGuillotineImageAtlas : public NzAbstractFontAtlas +{ + public: + NzGuillotineImageAtlas(); + virtual ~NzGuillotineImageAtlas(); + + void Clear(); + void Free(NzSparsePtr rects, NzSparsePtr layers, unsigned int count); + + NzGuillotineBinPack::FreeRectChoiceHeuristic GetRectChoiceHeuristic() const; + NzGuillotineBinPack::GuillotineSplitHeuristic GetRectSplitHeuristic() const; + NzAbstractImage* GetLayer(unsigned int layerIndex) const; + unsigned int GetLayerCount() const; + + bool Insert(const NzImage& image, NzRectui* rect, bool* flipped, unsigned int* layerIndex); + + void SetRectChoiceHeuristic(NzGuillotineBinPack::FreeRectChoiceHeuristic heuristic); + void SetRectSplitHeuristic(NzGuillotineBinPack::GuillotineSplitHeuristic heuristic); + + protected: + struct Layer; + + virtual unsigned int GetMaxAtlasSize() const; + virtual bool ResizeImage(Layer& layer, const NzVector2ui& size) const; + + struct QueuedGlyph + { + NzImage image; + NzRectui rect; + bool flipped; + }; + + struct Layer + { + std::vector queuedGlyphs; + std::unique_ptr image; + NzGuillotineBinPack binPack; + unsigned int freedRectangles = 0; + }; + + private: + void ProcessGlyphQueue(Layer& layer) const; + + std::set m_fonts; + mutable std::vector m_layers; + NzGuillotineBinPack::FreeRectChoiceHeuristic m_rectChoiceHeuristic; + NzGuillotineBinPack::GuillotineSplitHeuristic m_rectSplitHeuristic; +}; + +#endif // NAZARA_GUILLOTINEIMAGEATLAS_HPP diff --git a/src/Nazara/Graphics/GuillotineTextureAtlas.cpp b/src/Nazara/Graphics/GuillotineTextureAtlas.cpp new file mode 100644 index 000000000..7ff8bfa0c --- /dev/null +++ b/src/Nazara/Graphics/GuillotineTextureAtlas.cpp @@ -0,0 +1,57 @@ +// 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 + +bool NzGuillotineTextureAtlas::ResizeImage(Layer& layer, const NzVector2ui& size) const +{ + NzTexture newTexture; + if (newTexture.Create(nzImageType_2D, nzPixelFormat_A8, size.x, size.y, 1, 0xFF)) + { + newTexture.EnableMipmapping(true); + + if (layer.image) + { + NzTexture& texture = *static_cast(layer.image.get()); + + // Copie des anciennes données + ///TODO: Copie de texture à texture + NzImage image; + if (!texture.Download(&image)) + { + NazaraError("Failed to download old texture"); + return false; + } + + if (!newTexture.Update(image, NzRectui(0, 0, image.GetWidth(), image.GetHeight()))) + { + NazaraError("Failed to update texture"); + return false; + } + + texture = std::move(newTexture); + } + else + layer.image.reset(new NzTexture(std::move(newTexture))); + + return true; + } + else + { + NazaraError("Failed to create texture"); + return false; + } +} + +unsigned int NzGuillotineTextureAtlas::GetMaxAtlasSize() const +{ + ///FIXME: D'après la documentation OpenGL, cette valeur n'est qu'une approximation et les texture proxies sont une meilleure solution + /// Cependant le test ne se fait pas au même moment, penser à adapter le code pour gérer ce cas ? + /// (Cela permettrait au passage de gérer le cas où une image ne peut être allouée car il n'y a pas assez de mémoire contigüe pour la contenir) + + return NzRenderer::GetMaxTextureSize(); +} diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index c6a888929..e41d6b755 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -8,18 +8,12 @@ #include #include -namespace -{ - const unsigned int s_atlasStartSize = 512; -} - bool NzFontParams::IsValid() const { return true; // Rien à tester } NzFont::NzFont() : -m_maxAtlasSize(0), m_minimumSizeStep(1) { } @@ -31,25 +25,39 @@ NzFont::~NzFont() void NzFont::ClearGlyphCache() { - // Destruction des atlas et glyphes mémorisés - m_atlases.clear(); - m_glyphes.clear(); - m_glyphQueue.clear(); + if (m_atlas) + { + if (m_atlas.use_count() > 1) // Au moins une autre police utilise cet atlas, on vire nos glyphes + { + for (auto mapIt = m_glyphes.begin(); mapIt != m_glyphes.end(); ++mapIt) + { + GlyphMap& glyphMap = mapIt->second; + for (auto glyphIt = glyphMap.begin(); glyphIt != glyphMap.end(); ++glyphIt) + { + Glyph& glyph = glyphIt->second; + m_atlas->Free(&glyph.atlasRect, &glyph.layerIndex, 1); + } + } - // Création du premier atlas - m_atlases.resize(1); - Atlas& atlas = m_atlases.back(); - atlas.binPack.Reset(s_atlasStartSize, s_atlasStartSize); + // Destruction des glyphes mémorisés + m_glyphes.clear(); + NotifyModified(ModificationCode_GlyphCacheCleared); + } + else + m_atlas->Clear(); + } } void NzFont::ClearKerningCache() { m_kerningCache.clear(); + NotifyModified(ModificationCode_KerningCacheCleared); } void NzFont::ClearSizeInfoCache() { m_sizeInfoCache.clear(); + NotifyModified(ModificationCode_SizeInfoCacheCleared); } bool NzFont::Create(NzFontData* data) @@ -66,18 +74,15 @@ bool NzFont::Create(NzFontData* data) m_data.reset(data); - ClearGlyphCache(); // Création du premier atlas en mémoire - return true; } void NzFont::Destroy() { - m_atlases.clear(); + ClearGlyphCache(); + m_data.reset(); m_kerningCache.clear(); - m_glyphes.clear(); - m_glyphQueue.clear(); m_sizeInfoCache.clear(); } @@ -94,17 +99,9 @@ bool NzFont::ExtractGlyph(unsigned int characterSize, char32_t character, nzUInt return m_data->ExtractGlyph(characterSize, character, style & nzTextStyle_Bold, glyph); } -const NzFont::Atlas& NzFont::GetAtlas(unsigned int atlasIndex) const +const NzAbstractFontAtlas* NzFont::GetAtlas() const { - if (!m_glyphQueue.empty()) - ProcessGlyphQueue(); - - return m_atlases.at(atlasIndex); -} - -unsigned int NzFont::GetAtlasCount() const -{ - return m_atlases.size(); + return m_atlas.get(); } unsigned int NzFont::GetCachedGlyphCount(unsigned int characterSize, nzUInt32 style) const @@ -173,11 +170,6 @@ const NzFont::Glyph& NzFont::GetGlyph(unsigned int characterSize, nzUInt32 style return PrecacheGlyph(m_glyphes[key], characterSize, style, character); } -unsigned int NzFont::GetMaxAtlasSize() const -{ - return m_maxAtlasSize; -} - unsigned int NzFont::GetMinimumStepSize() const { return m_minimumSizeStep; @@ -266,26 +258,11 @@ bool NzFont::OpenFromStream(NzInputStream& stream, const NzFontParams& params) return NzFontLoader::LoadFromStream(this, stream, params); } -void NzFont::SetMaxAtlasSize(unsigned int maxAtlasSize) +void NzFont::SetAtlas(std::shared_ptr atlas) { - unsigned int oldMaxAtlasSize = GetRealMaxAtlasSize(); - m_maxAtlasSize = maxAtlasSize; + ClearGlyphCache(); - // Si l'un de nos atlas dépasse la nouvelle taille, on doit vider le cache - maxAtlasSize = GetRealMaxAtlasSize(); - if (maxAtlasSize < oldMaxAtlasSize) - { - for (Atlas& atlas : m_atlases) - { - unsigned int atlasSize = atlas.binPack.GetWidth(); - if (atlasSize > maxAtlasSize) - { - NazaraWarning("At least one atlas was over new max atlas size (" + NzString::Number(atlasSize) + " > " + NzString::Number(maxAtlasSize) + "), clearing glyph cache..."); - ClearGlyphCache(); - return; - } - } - } + m_atlas = atlas; } void NzFont::SetMinimumStepSize(unsigned int minimumStepSize) @@ -299,16 +276,7 @@ void NzFont::SetMinimumStepSize(unsigned int minimumStepSize) #endif m_minimumSizeStep = minimumStepSize; -} - -unsigned int NzFont::GetDefaultMaxAtlasSize() -{ - return s_maxAtlasSize; -} - -void NzFont::SetDefaultMaxAtlasSize(unsigned int maxAtlasSize) -{ - s_maxAtlasSize = maxAtlasSize; + ClearGlyphCache(); } nzUInt64 NzFont::ComputeKey(unsigned int characterSize, nzUInt32 style) const @@ -326,58 +294,12 @@ nzUInt64 NzFont::ComputeKey(unsigned int characterSize, nzUInt32 style) const return (stylePart << 32) | sizePart; } -unsigned int NzFont::GetRealMaxAtlasSize() const +void NzFont::OnAtlasCleared() { - unsigned int maxAtlasSize = (m_maxAtlasSize == 0) ? s_maxAtlasSize : m_maxAtlasSize; - if (maxAtlasSize == 0) - maxAtlasSize = std::numeric_limits::max(); + // Notre atlas vient d'être vidé, détruisons le cache de glyphe + m_glyphes.clear(); - return maxAtlasSize; -} - -unsigned int NzFont::InsertRect(NzRectui* rect, bool* flipped) const -{ - ///DOC: Tous les pointeurs doivent être valides - // Précondition: Un rectangle ne peut pas être plus grand dans une dimension que la taille maximale de l'atlas - - unsigned int maxAtlasSize = GetRealMaxAtlasSize(); - - // Cette fonction ne fait qu'insérer un rectangle de façon virtuelle, l'insertion des images se fait après - for (unsigned int i = 0; i < m_atlases.size(); ++i) - { - Atlas& atlas = m_atlases[i]; - if (atlas.binPack.Insert(rect, flipped, 1, false, NzGuillotineBinPack::RectBestAreaFit, NzGuillotineBinPack::SplitMinimizeArea)) - // Insertion réussie dans l'un des atlas, pas de question à se poser - return i; - else if (i == m_atlases.size() - 1) // Dernière itération ? - { - // Dernier atlas, et le glyphe ne rentre pas, peut-on agrandir la taille de l'atlas ? - unsigned int size = atlas.binPack.GetWidth(); // l'atlas étant carré, on ne teste qu'une dimension - if (size < maxAtlasSize) - { - // On peut encore agrandir l'atlas - size = std::min(size*2, maxAtlasSize); - atlas.binPack.Expand(size, size); - - // On relance la boucle sur le dernier atlas - i--; - } - else - { - // On ne peut plus agrandir le dernier atlas, il est temps d'en créer un nouveau - m_atlases.resize(m_atlases.size() + 1); - Atlas& newAtlas = m_atlases.back(); - - newAtlas.binPack.Reset(s_atlasStartSize, s_atlasStartSize); - - // On laisse la boucle insérer toute seule le rectangle à la prochaine itération - } - } - } - - // Si nous arrivons ici, c'est qu'une erreur a eu lieu en amont - NazaraInternalError("This shouldn't happen"); - return std::numeric_limits::max(); + NotifyModified(ModificationCode_GlyphCacheCleared); } const NzFont::Glyph& NzFont::PrecacheGlyph(GlyphMap& glyphMap, unsigned int characterSize, bool bold, char32_t character) const @@ -386,7 +308,7 @@ const NzFont::Glyph& NzFont::PrecacheGlyph(GlyphMap& glyphMap, unsigned int char if (it != glyphMap.end()) // Si le glyphe n'est pas déjà chargé return it->second; - Glyph glyph; + Glyph& glyph = glyphMap[character]; // Insertion du glyphe glyph.valid = false; // On extrait le glyphe depuis la police @@ -396,112 +318,39 @@ const NzFont::Glyph& NzFont::PrecacheGlyph(GlyphMap& glyphMap, unsigned int char glyph.atlasRect.width = fontGlyph.image.GetWidth(); glyph.atlasRect.height = fontGlyph.image.GetHeight(); - unsigned int maxAtlasSize = GetRealMaxAtlasSize(); - if (glyph.atlasRect.width <= maxAtlasSize && glyph.atlasRect.height <= maxAtlasSize) + // Insertion du rectangle dans l'un des atlas + if (glyph.atlasRect.width > 0 && glyph.atlasRect.height > 0) // Si l'image contient quelque chose { - // Insertion du rectangle dans l'un des atlas - glyph.aabb = fontGlyph.aabb; - glyph.advance = fontGlyph.advance; - glyph.valid = true; + // Padding (pour éviter le débordement lors du filtrage) + const unsigned int padding = 1; // Un pixel de contour - if (glyph.atlasRect.width > 0 && glyph.atlasRect.height > 0) // Si l'image contient quelque chose + glyph.atlasRect.width += padding*2; + glyph.atlasRect.height += padding*2; + + // Insertion du rectangle dans l'atlas virtuel + if (!m_atlas->Insert(fontGlyph.image, &glyph.atlasRect, &glyph.flipped, &glyph.layerIndex)) { - // Padding (pour éviter le débordement lors du filtrage) - const unsigned int padding = 1; // Un pixel entre chaque glyphe - - glyph.atlasRect.width += padding; - glyph.atlasRect.height += padding; - - // Insertion du rectangle dans l'atlas virtuel - glyph.atlasIndex = InsertRect(&glyph.atlasRect, &glyph.flipped); - - glyph.atlasRect.width -= padding; - glyph.atlasRect.height -= padding; - - // Mise en queue pour insertion dans l'atlas réel - m_glyphQueue.resize(m_glyphQueue.size()+1); - QueuedGlyph& queuedGlyph = m_glyphQueue.back(); - queuedGlyph.codepoint = character; - queuedGlyph.image = std::move(fontGlyph.image); - queuedGlyph.map = &glyphMap; + NazaraError("Failed to insert glyph into atlas"); + return glyph; } + + // Compensation du contour (centrage du glyphe) + glyph.atlasRect.x += padding; + glyph.atlasRect.y += padding; + glyph.atlasRect.width -= padding*2; + glyph.atlasRect.height -= padding*2; } - else - { - NazaraWarning("Glyph \"" + NzString::Unicode(character) + "\" is bigger than max atlas size"); - } + + glyph.aabb = fontGlyph.aabb; + glyph.advance = fontGlyph.advance; + glyph.valid = true; } else { NazaraWarning("Failed to extract glyph \"" + NzString::Unicode(character) + "\""); } - return glyphMap.insert(std::make_pair(character, std::move(glyph))).first->second; -} - -void NzFont::ProcessGlyphQueue() const -{ - for (QueuedGlyph& queuedGlyph : m_glyphQueue) - { - GlyphMap& glyphMap = *queuedGlyph.map; - auto glyphIt = glyphMap.find(queuedGlyph.codepoint); - if (glyphIt == glyphMap.end()) - continue; // Le glyphe a certainement été supprimé du cache avant la mise à jour de l'atlas - - Glyph& glyph = glyphIt->second; - Atlas& atlas = m_atlases[glyph.atlasIndex]; - - // On s'assure que l'atlas est de la bonne taille - NzVector2ui atlasSize(atlas.image.GetWidth(), atlas.image.GetHeight()); - NzVector2ui binPackSize = atlas.binPack.GetSize(); - if (atlasSize != binPackSize) - { - // Création d'une nouvelle image - NzImage newAtlas(nzImageType_2D, nzPixelFormat_A8, binPackSize.x, binPackSize.y); - if (atlas.image.IsValid()) - { - newAtlas.Copy(atlas.image, NzRectui(atlasSize), NzVector2ui(0, 0)); // On copie les anciennes données - - // On initialise les nouvelles régions - newAtlas.Fill(NzColor(255, 255, 255, 0), NzRectui(0, atlasSize.y, binPackSize.x, binPackSize.y - atlasSize.y)); - newAtlas.Fill(NzColor(255, 255, 255, 0), NzRectui(atlasSize.x, 0, binPackSize.x - atlasSize.x, atlasSize.y)); - } - else - newAtlas.Fill(NzColor(255, 255, 255, 0)); // On initialise les pixels - - atlas.image = std::move(newAtlas); // On déplace la nouvelle image vers l'atlas - } - - unsigned int glyphWidth = queuedGlyph.image.GetWidth(); - unsigned int glyphHeight = queuedGlyph.image.GetHeight(); - - // On copie le glyphe dans l'atlas - if (glyph.flipped) - { - // On tourne le glyphe pour qu'il rentre dans le rectangle - const nzUInt8* src = queuedGlyph.image.GetConstPixels(); - nzUInt8* ptr = atlas.image.GetPixels(glyph.atlasRect.x, glyph.atlasRect.y + glyphWidth - 1); - - unsigned int lineStride = atlas.image.GetWidth(); // BPP = 1 - for (unsigned int y = 0; y < glyphHeight; ++y) - { - for (unsigned int x = 0; x < glyphWidth; ++x) - { - *ptr = *src++; // On copie et on avance dans le glyphe - ptr -= lineStride; // On remonte d'une ligne - } - - ptr += lineStride*glyphWidth + 1; - } - } - else - atlas.image.Copy(queuedGlyph.image, NzRectui(glyphWidth, glyphHeight), glyph.atlasRect.GetPosition()); - - queuedGlyph.image.Destroy(); // On libère l'image dès que possible (pour réduire la consommation) - } - - m_glyphQueue.clear(); + return glyph; } NzFontLoader::LoaderList NzFont::s_loaders; -unsigned int NzFont::s_maxAtlasSize = 8192; // Valeur totalement arbitraire diff --git a/src/Nazara/Utility/GuillotineImageAtlas.cpp b/src/Nazara/Utility/GuillotineImageAtlas.cpp new file mode 100644 index 000000000..a04eed25a --- /dev/null +++ b/src/Nazara/Utility/GuillotineImageAtlas.cpp @@ -0,0 +1,244 @@ +// 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 + +#include +#include +#include + +namespace +{ + const unsigned int s_atlasStartSize = 512; +} + +NzGuillotineImageAtlas::NzGuillotineImageAtlas() : +m_rectChoiceHeuristic(NzGuillotineBinPack::RectBestAreaFit), +m_rectSplitHeuristic(NzGuillotineBinPack::SplitMinimizeArea) +{ +} + +NzGuillotineImageAtlas::~NzGuillotineImageAtlas() = default; + +void NzGuillotineImageAtlas::Clear() +{ + m_layers.clear(); + NotifyCleared(); +} + +void NzGuillotineImageAtlas::Free(NzSparsePtr rects, NzSparsePtr layers, unsigned int count) +{ + for (unsigned int i = 0; i < count; ++i) + { + #ifdef NAZARA_DEBUG + if (layers[i] >= m_layers.size()) + { + NazaraWarning("Rectangle #" + NzString::Number(i) + " belong to an out-of-bounds layer (" + NzString::Number(i) + " >= " + NzString::Number(m_layers.size()) + ")"); + continue; + } + #endif + + m_layers[layers[i]].binPack.FreeRectangle(rects[i]); + m_layers[layers[i]].freedRectangles++; + } +} + +NzGuillotineBinPack::FreeRectChoiceHeuristic NzGuillotineImageAtlas::GetRectChoiceHeuristic() const +{ + return m_rectChoiceHeuristic; +} + +NzGuillotineBinPack::GuillotineSplitHeuristic NzGuillotineImageAtlas::GetRectSplitHeuristic() const +{ + return m_rectSplitHeuristic; +} + +NzAbstractImage* NzGuillotineImageAtlas::GetLayer(unsigned int layerIndex) const +{ + #if NAZARA_UTILITY_SAFE + if (layerIndex >= m_layers.size()) + { + NazaraError("Layer index out of range (" + NzString::Number(layerIndex) + " >= " + NzString::Number(m_layers.size()) + ')'); + return nullptr; + } + #endif + + Layer& layer = m_layers[layerIndex]; + ProcessGlyphQueue(layer); + + return layer.image.get(); +} + +unsigned int NzGuillotineImageAtlas::GetLayerCount() const +{ + return m_layers.size(); +} + +bool NzGuillotineImageAtlas::Insert(const NzImage& image, NzRectui* rect, bool* flipped, unsigned int* layerIndex) +{ + unsigned int maxAtlasSize = GetMaxAtlasSize(); + + if (m_layers.empty()) + { + // On créé une première couche s'il n'y en a pas + m_layers.resize(1); + Layer& layer = m_layers.back(); + layer.binPack.Reset(s_atlasStartSize, s_atlasStartSize); + } + + // Cette fonction ne fait qu'insérer un rectangle de façon virtuelle, l'insertion des images se fait après + for (unsigned int i = 0; i < m_layers.size(); ++i) + { + Layer& layer = m_layers[i]; + + // Une fois qu'un certain nombre de rectangles ont étés libérés d'une couche, on fusionne les rectangles libres + if (layer.freedRectangles > 10) // Valeur totalement arbitraire + { + while (layer.binPack.MergeFreeRectangles()); // Tant qu'une fusion est possible + layer.freedRectangles = 0; // Et on repart de zéro + } + + if (layer.binPack.Insert(rect, flipped, 1, false, m_rectChoiceHeuristic, m_rectSplitHeuristic)) + { + // Insertion réussie dans l'une des couches, on place le glyphe en file d'attente + layer.queuedGlyphs.resize(layer.queuedGlyphs.size()+1); + QueuedGlyph& glyph = layer.queuedGlyphs.back(); + glyph.flipped = *flipped; + glyph.image = image; // Merci le Copy-On-Write + glyph.rect = *rect; + + *layerIndex = i; + return true; + } + else if (i == m_layers.size() - 1) // Dernière itération ? + { + // Dernière couche, et le glyphe ne rentre pas, peut-on agrandir la taille de l'image ? + unsigned int size = layer.binPack.GetWidth(); // l'image étant carrée, on ne teste qu'une dimension + if (size < maxAtlasSize) + { + // On peut encore agrandir la couche + size = std::min(size*2, maxAtlasSize); + layer.binPack.Expand(size, size); + + // On relance la boucle sur la nouvelle dernière couche + i--; + } + else + { + // On ne peut plus agrandir la dernière couche, il est temps d'en créer une nouvelle + m_layers.resize(m_layers.size() + 1); + Layer& newLayer = m_layers.back(); + + newLayer.binPack.Reset(s_atlasStartSize, s_atlasStartSize); + + // On laisse la boucle insérer toute seule le rectangle à la prochaine itération + } + } + } + + return false; // Normalement impossible +} + +void NzGuillotineImageAtlas::SetRectChoiceHeuristic(NzGuillotineBinPack::FreeRectChoiceHeuristic heuristic) +{ + m_rectChoiceHeuristic = heuristic; +} + +void NzGuillotineImageAtlas::SetRectSplitHeuristic(NzGuillotineBinPack::GuillotineSplitHeuristic heuristic) +{ + m_rectSplitHeuristic = heuristic; +} + +unsigned int NzGuillotineImageAtlas::GetMaxAtlasSize() const +{ + return 8192; // Valeur totalement arbitraire +} + +void NzGuillotineImageAtlas::ProcessGlyphQueue(Layer& layer) const +{ + std::vector pixelBuffer; + + // On s'assure que l'image est de la bonne taille + NzVector2ui binPackSize(layer.binPack.GetSize()); + NzVector2ui imageSize((layer.image) ? layer.image->GetSize() : NzVector3ui(0U)); + if (binPackSize != imageSize) + ResizeImage(layer, binPackSize); + + for (QueuedGlyph& glyph : layer.queuedGlyphs) + { + unsigned int glyphWidth = glyph.image.GetWidth(); + unsigned int glyphHeight = glyph.image.GetHeight(); + + // Calcul de l'éventuel padding (pixels de contour) + unsigned int paddingX; + unsigned int paddingY; + if (glyph.flipped) + { + paddingX = (glyph.rect.height - glyphWidth)/2; + paddingY = (glyph.rect.width - glyphHeight)/2; + } + else + { + paddingX = (glyph.rect.width - glyphWidth)/2; + paddingY = (glyph.rect.height - glyphHeight)/2; + } + + if (paddingX > 0 || paddingY > 0) + { + // On remplit les contours + pixelBuffer.resize(glyph.rect.width * glyph.rect.height); + std::memset(pixelBuffer.data(), 0, glyph.rect.width*glyph.rect.height*sizeof(nzUInt8)); + + layer.image->Update(pixelBuffer.data(), glyph.rect); + } + + const nzUInt8* pixels; + // On copie le glyphe dans l'atlas + if (glyph.flipped) + { + pixelBuffer.resize(glyphHeight * glyphWidth); + + // On tourne le glyphe pour qu'il rentre dans le rectangle + const nzUInt8* src = glyph.image.GetConstPixels(); + nzUInt8* ptr = pixelBuffer.data(); + + unsigned int lineStride = glyphWidth*sizeof(nzUInt8); // BPP = 1 + src += lineStride-1; // Départ en haut à droite + for (unsigned int x = 0; x < glyphWidth; ++x) + { + for (unsigned int y = 0; y < glyphHeight; ++y) + { + *ptr++ = *src; + src += lineStride; + } + + src -= glyphHeight*lineStride + 1; + } + + pixels = pixelBuffer.data(); + std::swap(glyphWidth, glyphHeight); + } + else + pixels = glyph.image.GetConstPixels(); + + layer.image->Update(pixels, NzRectui(glyph.rect.x + paddingX, glyph.rect.y + paddingY, glyphWidth, glyphHeight), 0, glyphWidth, glyphHeight); + glyph.image.Destroy(); // On libère l'image dès que possible (pour réduire la consommation) + } + + layer.queuedGlyphs.clear(); +} + +bool NzGuillotineImageAtlas::ResizeImage(Layer& layer, const NzVector2ui& size) const +{ + NzImage newImage(nzImageType_2D, nzPixelFormat_A8, size.x, size.y); + if (layer.image) + { + NzImage& image = *static_cast(layer.image.get()); + newImage.Copy(image, NzRectui(size), NzVector2ui(0, 0)); // Copie des anciennes données + + image = std::move(newImage); + } + else + layer.image.reset(new NzImage(std::move(newImage))); + + return true; +} From 88af94b9877f7e00870b5c09a3501537e4b58117 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 7 Jan 2015 23:47:09 +0100 Subject: [PATCH 136/233] Added ResourceConstListener I don't know yet if it's a good idea but at least it's an idea Former-commit-id: b034a787d8d8ccce0804f1276958b32c9e149147 --- include/Nazara/Core/Resource.hpp | 6 ++ include/Nazara/Core/ResourceConstListener.hpp | 26 ++++++++ src/Nazara/Core/Resource.cpp | 63 +++++++++++++++++++ src/Nazara/Core/ResourceConstListener.cpp | 39 ++++++++++++ 4 files changed, 134 insertions(+) create mode 100644 include/Nazara/Core/ResourceConstListener.hpp create mode 100644 src/Nazara/Core/ResourceConstListener.cpp diff --git a/include/Nazara/Core/Resource.hpp b/include/Nazara/Core/Resource.hpp index adf0eace2..e82b33fad 100644 --- a/include/Nazara/Core/Resource.hpp +++ b/include/Nazara/Core/Resource.hpp @@ -17,6 +17,7 @@ #include #endif +class NzResourceConstListener; class NzResourceListener; class NAZARA_API NzResource @@ -25,6 +26,7 @@ class NAZARA_API NzResource NzResource(bool persistent = true); virtual ~NzResource(); + void AddResourceConstListener(const NzResourceConstListener* listener, int index = 0) const; void AddResourceListener(NzResourceListener* listener, int index = 0) const; void AddResourceReference() const; @@ -32,6 +34,7 @@ class NAZARA_API NzResource bool IsPersistent() const; + void RemoveResourceConstListener(const NzResourceConstListener* listener) const; void RemoveResourceListener(NzResourceListener* listener) const; bool RemoveResourceReference() const; @@ -43,13 +46,16 @@ class NAZARA_API NzResource void NotifyModified(unsigned int code); private: + using ResourceConstListenerMap = std::unordered_map>; using ResourceListenerMap = std::unordered_map>; + void RemoveResourceConstListenerIterator(ResourceConstListenerMap::iterator iterator) const; void RemoveResourceListenerIterator(ResourceListenerMap::iterator iterator) const; NazaraMutexAttrib(m_mutex, mutable) // Je fais précéder le nom par 'resource' pour éviter les éventuels conflits de noms + mutable ResourceConstListenerMap m_resourceConstListeners; mutable ResourceListenerMap m_resourceListeners; std::atomic_bool m_resourcePersistent; mutable std::atomic_uint m_resourceReferenceCount; diff --git a/include/Nazara/Core/ResourceConstListener.hpp b/include/Nazara/Core/ResourceConstListener.hpp new file mode 100644 index 000000000..7113c3c94 --- /dev/null +++ b/include/Nazara/Core/ResourceConstListener.hpp @@ -0,0 +1,26 @@ +// 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 + +#pragma once + +#ifndef NAZARA_RESOURCECONSTLISTENER_HPP +#define NAZARA_RESOURCECONSTLISTENER_HPP + +#include + +class NzResource; + +class NAZARA_API NzResourceConstListener +{ + public: + NzResourceConstListener() = default; + virtual ~NzResourceConstListener(); + + virtual bool OnResourceCreated(const NzResource* resource, int index) const; + virtual bool OnResourceDestroy(const NzResource* resource, int index) const; + virtual bool OnResourceModified(const NzResource* resource, int index, unsigned int code) const; + virtual void OnResourceReleased(const NzResource* resource, int index) const; +}; + +#endif // NAZARA_RESOURCECONSTLISTENER_HPP diff --git a/src/Nazara/Core/Resource.cpp b/src/Nazara/Core/Resource.cpp index 5610d9d13..fbdaf1853 100644 --- a/src/Nazara/Core/Resource.cpp +++ b/src/Nazara/Core/Resource.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #if NAZARA_CORE_THREADSAFE && NAZARA_THREADSAFETY_RESOURCE @@ -34,6 +35,19 @@ NzResource::~NzResource() #endif } +void NzResource::AddResourceConstListener(const NzResourceConstListener* listener, int index) const +{ + ///DOC: Est ignoré si appelé depuis un évènement + NazaraLock(m_mutex) + + if (!m_resourceListenersLocked) + { + auto pair = m_resourceConstListeners.insert(std::make_pair(listener, std::make_pair(index, 1U))); + if (!pair.second) + pair.first->second.second++; + } +} + void NzResource::AddResourceListener(NzResourceListener* listener, int index) const { ///DOC: Est ignoré si appelé depuis un évènement @@ -62,6 +76,19 @@ bool NzResource::IsPersistent() const return m_resourcePersistent; } +void NzResource::RemoveResourceConstListener(const NzResourceConstListener* listener) const +{ + ///DOC: Est ignoré si appelé depuis un évènement + NazaraLock(m_mutex); + + if (!m_resourceListenersLocked) + { + ResourceConstListenerMap::iterator it = m_resourceConstListeners.find(listener); + if (it != m_resourceConstListeners.end()) + RemoveResourceConstListenerIterator(it); + } +} + void NzResource::RemoveResourceListener(NzResourceListener* listener) const { ///DOC: Est ignoré si appelé depuis un évènement @@ -115,6 +142,15 @@ void NzResource::NotifyCreated() m_resourceListenersLocked = true; + auto constIt = m_resourceConstListeners.begin(); + while (constIt != m_resourceConstListeners.end()) + { + if (!constIt->first->OnResourceCreated(this, constIt->second.first)) + RemoveResourceConstListenerIterator(constIt++); + else + ++constIt; + } + auto it = m_resourceListeners.begin(); while (it != m_resourceListeners.end()) { @@ -133,6 +169,15 @@ void NzResource::NotifyDestroy() m_resourceListenersLocked = true; + auto constIt = m_resourceConstListeners.begin(); + while (constIt != m_resourceConstListeners.end()) + { + if (!constIt->first->OnResourceDestroy(this, constIt->second.first)) + RemoveResourceConstListenerIterator(constIt++); + else + ++constIt; + } + auto it = m_resourceListeners.begin(); while (it != m_resourceListeners.end()) { @@ -151,6 +196,15 @@ void NzResource::NotifyModified(unsigned int code) m_resourceListenersLocked = true; + auto constIt = m_resourceConstListeners.begin(); + while (constIt != m_resourceConstListeners.end()) + { + if (!constIt->first->OnResourceModified(this, constIt->second.first, code)) + RemoveResourceConstListenerIterator(constIt++); + else + ++constIt; + } + auto it = m_resourceListeners.begin(); while (it != m_resourceListeners.end()) { @@ -163,6 +217,15 @@ void NzResource::NotifyModified(unsigned int code) m_resourceListenersLocked = false; } +void NzResource::RemoveResourceConstListenerIterator(ResourceConstListenerMap::iterator iterator) const +{ + unsigned int& referenceCount = iterator->second.second; + if (referenceCount == 1) + m_resourceConstListeners.erase(iterator); + else + referenceCount--; +} + void NzResource::RemoveResourceListenerIterator(ResourceListenerMap::iterator iterator) const { unsigned int& referenceCount = iterator->second.second; diff --git a/src/Nazara/Core/ResourceConstListener.cpp b/src/Nazara/Core/ResourceConstListener.cpp new file mode 100644 index 000000000..ebcbdc0ec --- /dev/null +++ b/src/Nazara/Core/ResourceConstListener.cpp @@ -0,0 +1,39 @@ +// Copyright (C) 2014 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 + +NzResourceConstListener::~NzResourceConstListener() = default; + +bool NzResourceConstListener::OnResourceCreated(const NzResource* resource, int index) const +{ + NazaraUnused(resource); + NazaraUnused(index); + + return true; +} + +bool NzResourceConstListener::OnResourceDestroy(const NzResource* resource, int index) const +{ + NazaraUnused(resource); + NazaraUnused(index); + + return true; +} + +bool NzResourceConstListener::OnResourceModified(const NzResource* resource, int index, unsigned int code) const +{ + NazaraUnused(resource); + NazaraUnused(index); + NazaraUnused(code); + + return true; +} + +void NzResourceConstListener::OnResourceReleased(const NzResource* resource, int index) const +{ + NazaraUnused(resource); + NazaraUnused(index); +} From a9ef2f7e3675ea1c9fed76c2ab617ec3bcd037a8 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 8 Jan 2015 14:19:53 +0100 Subject: [PATCH 137/233] Added support for faux-bold and faux-italic Former-commit-id: 259429e8d38b0299e30d539253b50e3aab12c76b --- include/Nazara/Utility/Font.hpp | 4 +- include/Nazara/Utility/FontData.hpp | 4 +- src/Nazara/Utility/Font.cpp | 99 +++++++++++++------ .../Utility/Loaders/FreeType/Loader.cpp | 44 +++++---- 4 files changed, 100 insertions(+), 51 deletions(-) diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index 2264b7604..4ebef9d3d 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -87,6 +87,8 @@ class NAZARA_API NzFont : public NzResource, NzNonCopyable { NzRecti aabb; NzRectui atlasRect; + bool requireFauxBold; + bool requireFauxItalic; bool flipped; bool valid; int advance; @@ -105,7 +107,7 @@ class NAZARA_API NzFont : public NzResource, NzNonCopyable nzUInt64 ComputeKey(unsigned int characterSize, nzUInt32 style) const; void OnAtlasCleared(); - const Glyph& PrecacheGlyph(GlyphMap& glyphMap, unsigned int characterSize, bool bold, char32_t character) const; + const Glyph& PrecacheGlyph(GlyphMap& glyphMap, unsigned int characterSize, nzUInt32 style, char32_t character) const; std::shared_ptr m_atlas; std::unique_ptr m_data; diff --git a/include/Nazara/Utility/FontData.hpp b/include/Nazara/Utility/FontData.hpp index 9805c1d2b..171735b10 100644 --- a/include/Nazara/Utility/FontData.hpp +++ b/include/Nazara/Utility/FontData.hpp @@ -18,7 +18,7 @@ class NAZARA_API NzFontData NzFontData() = default; virtual ~NzFontData(); - virtual bool ExtractGlyph(unsigned int characterSize, char32_t character, bool bold, NzFontGlyph* dst) = 0; + virtual bool ExtractGlyph(unsigned int characterSize, char32_t character, nzUInt32 style, NzFontGlyph* dst) = 0; virtual NzString GetFamilyName() const = 0; virtual NzString GetStyleName() const = 0; @@ -31,6 +31,8 @@ class NAZARA_API NzFontData virtual unsigned int QueryLineHeight(unsigned int characterSize) const = 0; virtual float QueryUnderlinePosition(unsigned int characterSize) const = 0; virtual float QueryUnderlineThickness(unsigned int characterSize) const = 0; + + virtual bool SupportsStyle(nzUInt32 style) const = 0; }; #endif // NAZARA_FONTDATA_HPP diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index e41d6b755..65909fe05 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -96,7 +96,7 @@ bool NzFont::ExtractGlyph(unsigned int characterSize, char32_t character, nzUInt } #endif - return m_data->ExtractGlyph(characterSize, character, style & nzTextStyle_Bold, glyph); + return m_data->ExtractGlyph(characterSize, character, style, glyph); } const NzAbstractFontAtlas* NzFont::GetAtlas() const @@ -284,12 +284,11 @@ nzUInt64 NzFont::ComputeKey(unsigned int characterSize, nzUInt32 style) const nzUInt64 sizePart = static_cast((characterSize/m_minimumSizeStep)*m_minimumSizeStep); nzUInt64 stylePart = 0; - if (style & nzTextStyle_Bold) // Les caractères gras sont générés différemment + if (style & nzTextStyle_Bold) stylePart |= nzTextStyle_Bold; - // Les caractères italiques peuvent venir d'une autre police, dans le cas contraire ils sont générés au runtime - //if (style & nzTextStyle_Italic) - // stylePart |= nzTextStyle_Italic; + if (style & nzTextStyle_Italic) + stylePart |= nzTextStyle_Italic; return (stylePart << 32) | sizePart; } @@ -302,52 +301,88 @@ void NzFont::OnAtlasCleared() NotifyModified(ModificationCode_GlyphCacheCleared); } -const NzFont::Glyph& NzFont::PrecacheGlyph(GlyphMap& glyphMap, unsigned int characterSize, bool bold, char32_t character) const +const NzFont::Glyph& NzFont::PrecacheGlyph(GlyphMap& glyphMap, unsigned int characterSize, nzUInt32 style, char32_t character) const { auto it = glyphMap.find(character); if (it != glyphMap.end()) // Si le glyphe n'est pas déjà chargé return it->second; Glyph& glyph = glyphMap[character]; // Insertion du glyphe + glyph.requireFauxBold = false; + glyph.requireFauxItalic = false; glyph.valid = false; - // On extrait le glyphe depuis la police - NzFontGlyph fontGlyph; - if (ExtractGlyph(characterSize, character, bold, &fontGlyph)) + // On vérifie que le style demandé est supporté par la police (dans le cas contraire il devra être simulé au rendu) + nzUInt32 supportedStyle = style; + if (style & nzTextStyle_Bold && !m_data->SupportsStyle(nzTextStyle_Bold)) { - glyph.atlasRect.width = fontGlyph.image.GetWidth(); - glyph.atlasRect.height = fontGlyph.image.GetHeight(); + glyph.requireFauxBold = true; + supportedStyle &= ~nzTextStyle_Bold; + } - // Insertion du rectangle dans l'un des atlas - if (glyph.atlasRect.width > 0 && glyph.atlasRect.height > 0) // Si l'image contient quelque chose + if (style & nzTextStyle_Italic && !m_data->SupportsStyle(nzTextStyle_Italic)) + { + glyph.requireFauxItalic = true; + supportedStyle &= ~nzTextStyle_Italic; + } + + // Est-ce que la police supporte le style demandé ? + if (style == supportedStyle) + { + // On extrait le glyphe depuis la police + NzFontGlyph fontGlyph; + if (ExtractGlyph(characterSize, character, style, &fontGlyph)) { - // Padding (pour éviter le débordement lors du filtrage) - const unsigned int padding = 1; // Un pixel de contour + glyph.atlasRect.width = fontGlyph.image.GetWidth(); + glyph.atlasRect.height = fontGlyph.image.GetHeight(); - glyph.atlasRect.width += padding*2; - glyph.atlasRect.height += padding*2; - - // Insertion du rectangle dans l'atlas virtuel - if (!m_atlas->Insert(fontGlyph.image, &glyph.atlasRect, &glyph.flipped, &glyph.layerIndex)) + // Insertion du rectangle dans l'un des atlas + if (glyph.atlasRect.width > 0 && glyph.atlasRect.height > 0) // Si l'image contient quelque chose { - NazaraError("Failed to insert glyph into atlas"); - return glyph; + // Padding (pour éviter le débordement lors du filtrage) + const unsigned int padding = 1; // Un pixel de contour + + glyph.atlasRect.width += padding*2; + glyph.atlasRect.height += padding*2; + + // Insertion du rectangle dans l'atlas virtuel + if (!m_atlas->Insert(fontGlyph.image, &glyph.atlasRect, &glyph.flipped, &glyph.layerIndex)) + { + NazaraError("Failed to insert glyph into atlas"); + return glyph; + } + + // Compensation du contour (centrage du glyphe) + glyph.atlasRect.x += padding; + glyph.atlasRect.y += padding; + glyph.atlasRect.width -= padding*2; + glyph.atlasRect.height -= padding*2; } - // Compensation du contour (centrage du glyphe) - glyph.atlasRect.x += padding; - glyph.atlasRect.y += padding; - glyph.atlasRect.width -= padding*2; - glyph.atlasRect.height -= padding*2; + glyph.aabb = fontGlyph.aabb; + glyph.advance = fontGlyph.advance; + glyph.valid = true; + } + else + { + NazaraWarning("Failed to extract glyph \"" + NzString::Unicode(character) + "\""); } - - glyph.aabb = fontGlyph.aabb; - glyph.advance = fontGlyph.advance; - glyph.valid = true; } else { - NazaraWarning("Failed to extract glyph \"" + NzString::Unicode(character) + "\""); + // La police ne supporte pas le style demandé, nous allons donc précharger le glyphe supportant le style "minimum" supporté + // et copier ses données + nzUInt64 newKey = ComputeKey(characterSize, supportedStyle); + const Glyph& referenceGlyph = PrecacheGlyph(m_glyphes[newKey], characterSize, supportedStyle, character); + if (referenceGlyph.valid) + { + glyph.aabb = referenceGlyph.aabb; + glyph.advance = referenceGlyph.advance; + glyph.atlasRect = referenceGlyph.atlasRect; + glyph.flipped = referenceGlyph.flipped; + glyph.layerIndex = referenceGlyph.layerIndex; + glyph.valid = true; + } } return glyph; diff --git a/src/Nazara/Utility/Loaders/FreeType/Loader.cpp b/src/Nazara/Utility/Loaders/FreeType/Loader.cpp index 46b91ffe8..35d6f0ff3 100644 --- a/src/Nazara/Utility/Loaders/FreeType/Loader.cpp +++ b/src/Nazara/Utility/Loaders/FreeType/Loader.cpp @@ -75,7 +75,7 @@ namespace return FT_Open_Face(s_library, &m_args, -1, nullptr) == 0; } - bool ExtractGlyph(unsigned int characterSize, char32_t character, bool bold, NzFontGlyph* dst) + bool ExtractGlyph(unsigned int characterSize, char32_t character, nzUInt32 style, NzFontGlyph* dst) override { #ifdef NAZARA_DEBUG if (!dst) @@ -97,10 +97,16 @@ namespace const FT_Pos boldStrength = 2 << 6; - bool outlineFormat = (glyph->format == FT_GLYPH_FORMAT_OUTLINE); - if (outlineFormat && bold) + bool embolden = (style & nzTextStyle_Bold); + + dst->advance = (embolden) ? boldStrength >> 6 : 0; + + if (embolden && glyph->format == FT_GLYPH_FORMAT_OUTLINE) + { // http://www.freetype.org/freetype2/docs/reference/ft2-outline_processing.html#FT_Outline_Embolden FT_Outline_Embolden(&glyph->outline, boldStrength); + embolden = false; + } // http://www.freetype.org/freetype2/docs/reference/ft2-glyph_management.html#FT_Glyph_To_Bitmap // Conversion du glyphe vers le format bitmap @@ -113,18 +119,16 @@ namespace // Dans le cas où nous voulons des caractères gras mais que nous n'avons pas pu agir plus tôt // nous demandons à FreeType d'agir directement sur le bitmap généré - if (!outlineFormat && bold) + if (embolden) { // http://www.freetype.org/freetype2/docs/reference/ft2-bitmap_handling.html#FT_Bitmap_Embolden // "If you want to embolden the bitmap owned by a FT_GlyphSlot_Rec, you should call FT_GlyphSlot_Own_Bitmap on the slot first" FT_GlyphSlot_Own_Bitmap(glyph); FT_Bitmap_Embolden(s_library, &glyph->bitmap, boldStrength, boldStrength); + embolden = false; } - dst->advance = glyph->metrics.horiAdvance >> 6; - if (bold) - dst->advance += boldStrength >> 6; - + dst->advance += glyph->metrics.horiAdvance >> 6; dst->aabb.x = glyph->metrics.horiBearingX >> 6; dst->aabb.y = -(glyph->metrics.horiBearingY >> 6); // Inversion du repère dst->aabb.width = glyph->metrics.width >> 6; @@ -177,22 +181,22 @@ namespace return true; } - NzString GetFamilyName() const + NzString GetFamilyName() const override { return m_face->family_name; } - NzString GetStyleName() const + NzString GetStyleName() const override { return m_face->style_name; } - bool HasKerning() const + bool HasKerning() const override { return FT_HAS_KERNING(m_face); } - bool IsScalable() const + bool IsScalable() const override { return FT_IS_SCALABLE(m_face); } @@ -202,7 +206,7 @@ namespace return FT_Open_Face(s_library, &m_args, 0, &m_face) == 0; } - int QueryKerning(unsigned int characterSize, char32_t first, char32_t second) const + int QueryKerning(unsigned int characterSize, char32_t first, char32_t second) const override { if (FT_HAS_KERNING(m_face)) { @@ -220,7 +224,7 @@ namespace return 0; } - unsigned int QueryLineHeight(unsigned int characterSize) const + unsigned int QueryLineHeight(unsigned int characterSize) const override { SetCharacterSize(characterSize); @@ -228,7 +232,7 @@ namespace return m_face->size->metrics.height >> 6; } - float QueryUnderlinePosition(unsigned int characterSize) const + float QueryUnderlinePosition(unsigned int characterSize) const override { if (FT_IS_SCALABLE(m_face)) { @@ -241,7 +245,7 @@ namespace return characterSize / 10.f; // Joker ? } - float QueryUnderlineThickness(unsigned int characterSize) const + float QueryUnderlineThickness(unsigned int characterSize) const override { if (FT_IS_SCALABLE(m_face)) { @@ -280,6 +284,12 @@ namespace m_args.stream = &m_stream; } + bool SupportsStyle(nzUInt32 style) const override + { + ///TODO + return style == nzTextStyle_None || style == nzTextStyle_Bold; + } + private: void SetCharacterSize(unsigned int characterSize) const { @@ -299,7 +309,7 @@ namespace bool IsSupported(const NzString& extension) { - ///FIXME: Je suppose qu'il en manque quelques uns.. + ///FIXME: Je suppose qu'il en manque quelques unes.. static std::set supportedExtensions = { "afm", "bdf", "cff", "cid", "dfont", "fnt", "pfa", "pfb", "pfm", "pfr", "sfnt", "tte", "ttf" }; From 703ea6e9c8e14f6ec966446a02e0f38fd950f194 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 8 Jan 2015 14:20:00 +0100 Subject: [PATCH 138/233] Removed useless call Former-commit-id: 1c3d84596b5c6b61c6bb64e9067653b8d2279955 --- src/Nazara/Graphics/GuillotineTextureAtlas.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Nazara/Graphics/GuillotineTextureAtlas.cpp b/src/Nazara/Graphics/GuillotineTextureAtlas.cpp index 7ff8bfa0c..20e4c6db4 100644 --- a/src/Nazara/Graphics/GuillotineTextureAtlas.cpp +++ b/src/Nazara/Graphics/GuillotineTextureAtlas.cpp @@ -12,8 +12,6 @@ bool NzGuillotineTextureAtlas::ResizeImage(Layer& layer, const NzVector2ui& size NzTexture newTexture; if (newTexture.Create(nzImageType_2D, nzPixelFormat_A8, size.x, size.y, 1, 0xFF)) { - newTexture.EnableMipmapping(true); - if (layer.image) { NzTexture& texture = *static_cast(layer.image.get()); From 1b266e7d7cf98f368d2d6b6d4321384ccc42f471 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 8 Jan 2015 14:24:35 +0100 Subject: [PATCH 139/233] Allowed font to set glyph border Former-commit-id: f410fb83ecd0e1ace639e32fd809d00caa4145bc --- include/Nazara/Utility/Font.hpp | 3 +++ src/Nazara/Utility/Font.cpp | 30 ++++++++++++++++++++---------- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index 4ebef9d3d..c2a5f1412 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -57,6 +57,7 @@ class NAZARA_API NzFont : public NzResource, NzNonCopyable NzString GetFamilyName() const; int GetKerning(unsigned int characterSize, char32_t first, char32_t second) const; const Glyph& GetGlyph(unsigned int characterSize, nzUInt32 style, char32_t character) const; + unsigned int GetGlyphBorder() const; unsigned int GetMinimumStepSize() const; const SizeInfo& GetSizeInfo(unsigned int characterSize) const; NzString GetStyleName() const; @@ -72,6 +73,7 @@ class NAZARA_API NzFont : public NzResource, NzNonCopyable bool OpenFromStream(NzInputStream& stream, const NzFontParams& params = NzFontParams()); void SetAtlas(std::shared_ptr atlas); + void SetGlyphBorder(unsigned int borderSize); void SetMinimumStepSize(unsigned int minimumSizeStep); NzFont& operator=(NzFont&& font) = default; @@ -114,6 +116,7 @@ class NAZARA_API NzFont : public NzResource, NzNonCopyable mutable std::unordered_map> m_kerningCache; mutable std::unordered_map m_glyphes; mutable std::unordered_map m_sizeInfoCache; + unsigned int m_glyphBorder; unsigned int m_minimumSizeStep; static NzFontLoader::LoaderList s_loaders; diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index 65909fe05..81def3c1e 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -14,6 +14,7 @@ bool NzFontParams::IsValid() const } NzFont::NzFont() : +m_glyphBorder(1), m_minimumSizeStep(1) { } @@ -170,6 +171,11 @@ const NzFont::Glyph& NzFont::GetGlyph(unsigned int characterSize, nzUInt32 style return PrecacheGlyph(m_glyphes[key], characterSize, style, character); } +unsigned int NzFont::GetGlyphBorder() const +{ + return m_glyphBorder; +} + unsigned int NzFont::GetMinimumStepSize() const { return m_minimumSizeStep; @@ -265,6 +271,12 @@ void NzFont::SetAtlas(std::shared_ptr atlas) m_atlas = atlas; } +void NzFont::SetGlyphBorder(unsigned int borderSize) +{ + m_glyphBorder = borderSize; + ClearGlyphCache(); +} + void NzFont::SetMinimumStepSize(unsigned int minimumStepSize) { #if NAZARA_UTILITY_SAFE @@ -339,11 +351,9 @@ const NzFont::Glyph& NzFont::PrecacheGlyph(GlyphMap& glyphMap, unsigned int char // Insertion du rectangle dans l'un des atlas if (glyph.atlasRect.width > 0 && glyph.atlasRect.height > 0) // Si l'image contient quelque chose { - // Padding (pour éviter le débordement lors du filtrage) - const unsigned int padding = 1; // Un pixel de contour - - glyph.atlasRect.width += padding*2; - glyph.atlasRect.height += padding*2; + // Bordure (pour éviter le débordement lors du filtrage) + glyph.atlasRect.width += m_glyphBorder*2; + glyph.atlasRect.height += m_glyphBorder*2; // Insertion du rectangle dans l'atlas virtuel if (!m_atlas->Insert(fontGlyph.image, &glyph.atlasRect, &glyph.flipped, &glyph.layerIndex)) @@ -352,11 +362,11 @@ const NzFont::Glyph& NzFont::PrecacheGlyph(GlyphMap& glyphMap, unsigned int char return glyph; } - // Compensation du contour (centrage du glyphe) - glyph.atlasRect.x += padding; - glyph.atlasRect.y += padding; - glyph.atlasRect.width -= padding*2; - glyph.atlasRect.height -= padding*2; + // Compensation de la bordure (centrage du glyphe) + glyph.atlasRect.x += m_glyphBorder; + glyph.atlasRect.y += m_glyphBorder; + glyph.atlasRect.width -= m_glyphBorder*2; + glyph.atlasRect.height -= m_glyphBorder*2; } glyph.aabb = fontGlyph.aabb; From 6885166dc5cce1592c65e518181fb803087f754b Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 16 Jan 2015 11:15:59 +0100 Subject: [PATCH 140/233] Removed useless file Former-commit-id: a171ca369adc2e7fddf1c7b5ce8e40f4cb1fac91 --- build/codeblocks/CppCheckResults.xml | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 build/codeblocks/CppCheckResults.xml diff --git a/build/codeblocks/CppCheckResults.xml b/build/codeblocks/CppCheckResults.xml deleted file mode 100644 index 8bd3586b0..000000000 --- a/build/codeblocks/CppCheckResults.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - From e3de7e6f3cbf79b4be8a12aae1141955494f43c6 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 16 Jan 2015 12:36:13 +0100 Subject: [PATCH 141/233] Added Atlas listeners Former-commit-id: a487b6ed53d9b97bfee27b28ba5523e43c1e9e7e --- include/Nazara/Utility/AbstractFontAtlas.hpp | 26 ++++++-- include/Nazara/Utility/Font.hpp | 5 +- .../Nazara/Utility/GuillotineImageAtlas.hpp | 2 - src/Nazara/Utility/AbstractFontAtlas.cpp | 63 +++++++++++++++++++ src/Nazara/Utility/Font.cpp | 52 +++++++++++++-- 5 files changed, 132 insertions(+), 16 deletions(-) create mode 100644 src/Nazara/Utility/AbstractFontAtlas.cpp diff --git a/include/Nazara/Utility/AbstractFontAtlas.hpp b/include/Nazara/Utility/AbstractFontAtlas.hpp index f3f06346a..f029731f2 100644 --- a/include/Nazara/Utility/AbstractFontAtlas.hpp +++ b/include/Nazara/Utility/AbstractFontAtlas.hpp @@ -10,31 +10,45 @@ #include #include #include -#include +#include class NzAbstractImage; -class NzFont; class NzImage; class NAZARA_API NzAbstractFontAtlas { public: - NzAbstractFontAtlas() = default; + class Listener; + + NzAbstractFontAtlas(); virtual ~NzAbstractFontAtlas(); + void AddListener(Listener* font, void* userdata = nullptr) const; + virtual void Clear() = 0; virtual void Free(NzSparsePtr rects, NzSparsePtr layers, unsigned int count) = 0; virtual NzAbstractImage* GetLayer(unsigned int layerIndex) const = 0; virtual unsigned int GetLayerCount() const = 0; virtual bool Insert(const NzImage& image, NzRectui* rect, bool* flipped, unsigned int* layerIndex) = 0; - void RegisterFont(NzFont* font); - void UnregisterFont(NzFont* font); + + void RemoveListener(Listener* font) const; + + class Listener + { + public: + Listener() = default; + virtual ~Listener(); + + virtual bool OnAtlasCleared(const NzAbstractFontAtlas* atlas, void* userdata); + virtual void OnAtlasReleased(const NzAbstractFontAtlas* atlas, void* userdata); + }; protected: void NotifyCleared(); private: - std::set m_registredFonts; + mutable std::unordered_map m_listeners; + bool m_listenersLocked; }; #endif // NAZARA_ABSTRACTFONTATLAS_HPP diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index c2a5f1412..82164b09f 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -29,7 +29,7 @@ using NzFontConstRef = NzResourceRef; using NzFontLoader = NzResourceLoader; using NzFontRef = NzResourceRef; -class NAZARA_API NzFont : public NzResource, NzNonCopyable +class NAZARA_API NzFont : public NzResource, NzAbstractFontAtlas::Listener, NzNonCopyable { friend NzAbstractFontAtlas; friend NzFontLoader; @@ -108,7 +108,8 @@ class NAZARA_API NzFont : public NzResource, NzNonCopyable using GlyphMap = std::unordered_map; nzUInt64 ComputeKey(unsigned int characterSize, nzUInt32 style) const; - void OnAtlasCleared(); + bool OnAtlasCleared(const NzAbstractFontAtlas* atlas, void* userdata) override; + void OnAtlasReleased(const NzAbstractFontAtlas* atlas, void* userdata) override; const Glyph& PrecacheGlyph(GlyphMap& glyphMap, unsigned int characterSize, nzUInt32 style, char32_t character) const; std::shared_ptr m_atlas; diff --git a/include/Nazara/Utility/GuillotineImageAtlas.hpp b/include/Nazara/Utility/GuillotineImageAtlas.hpp index dc1542560..1bc478427 100644 --- a/include/Nazara/Utility/GuillotineImageAtlas.hpp +++ b/include/Nazara/Utility/GuillotineImageAtlas.hpp @@ -13,7 +13,6 @@ #include #include #include -#include #include class NAZARA_API NzGuillotineImageAtlas : public NzAbstractFontAtlas @@ -59,7 +58,6 @@ class NAZARA_API NzGuillotineImageAtlas : public NzAbstractFontAtlas private: void ProcessGlyphQueue(Layer& layer) const; - std::set m_fonts; mutable std::vector m_layers; NzGuillotineBinPack::FreeRectChoiceHeuristic m_rectChoiceHeuristic; NzGuillotineBinPack::GuillotineSplitHeuristic m_rectSplitHeuristic; diff --git a/src/Nazara/Utility/AbstractFontAtlas.cpp b/src/Nazara/Utility/AbstractFontAtlas.cpp new file mode 100644 index 000000000..710c52d8f --- /dev/null +++ b/src/Nazara/Utility/AbstractFontAtlas.cpp @@ -0,0 +1,63 @@ +// 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 + +#include +#include +#include + +NzAbstractFontAtlas::NzAbstractFontAtlas() : +m_listenersLocked(false) +{ +} + +NzAbstractFontAtlas::~NzAbstractFontAtlas() +{ + m_listenersLocked = true; + for (auto& pair : m_listeners) + pair.first->OnAtlasReleased(this, pair.second); +} + +void NzAbstractFontAtlas::AddListener(Listener* listener, void* userdata) const +{ + if (!m_listenersLocked) + m_listeners.insert(std::make_pair(listener, userdata)); +} + +void NzAbstractFontAtlas::RemoveListener(Listener* listener) const +{ + if (!m_listenersLocked) + m_listeners.erase(listener); +} + +void NzAbstractFontAtlas::NotifyCleared() +{ + m_listenersLocked = true; + + auto it = m_listeners.begin(); + while (it != m_listeners.end()) + { + if (!it->first->OnAtlasCleared(this, it->second)) + m_listeners.erase(it++); + else + ++it; + } + + m_listenersLocked = false; +} + +NzAbstractFontAtlas::Listener::~Listener() = default; + +bool NzAbstractFontAtlas::Listener::OnAtlasCleared(const NzAbstractFontAtlas* atlas, void* userdata) +{ + NazaraUnused(atlas); + NazaraUnused(userdata); + + return true; +} + +void NzAbstractFontAtlas::Listener::OnAtlasReleased(const NzAbstractFontAtlas* atlas, void* userdata) +{ + NazaraUnused(atlas); + NazaraUnused(userdata); +} diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index 81def3c1e..d1e061b0b 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -28,8 +28,11 @@ void NzFont::ClearGlyphCache() { if (m_atlas) { - if (m_atlas.use_count() > 1) // Au moins une autre police utilise cet atlas, on vire nos glyphes + if (m_atlas.unique()) + m_atlas->Clear(); // Appellera OnAtlasCleared + else { + // Au moins une autre police utilise cet atlas, on vire nos glyphes un par un for (auto mapIt = m_glyphes.begin(); mapIt != m_glyphes.end(); ++mapIt) { GlyphMap& glyphMap = mapIt->second; @@ -40,12 +43,10 @@ void NzFont::ClearGlyphCache() } } - // Destruction des glyphes mémorisés + // Destruction des glyphes mémorisés et notification m_glyphes.clear(); NotifyModified(ModificationCode_GlyphCacheCleared); } - else - m_atlas->Clear(); } } @@ -268,7 +269,12 @@ void NzFont::SetAtlas(std::shared_ptr atlas) { ClearGlyphCache(); + if (m_atlas) + m_atlas->RemoveListener(this); + m_atlas = atlas; + if (m_atlas) + m_atlas->AddListener(this); } void NzFont::SetGlyphBorder(unsigned int borderSize) @@ -293,7 +299,10 @@ void NzFont::SetMinimumStepSize(unsigned int minimumStepSize) nzUInt64 NzFont::ComputeKey(unsigned int characterSize, nzUInt32 style) const { + // On prend le pas en compte nzUInt64 sizePart = static_cast((characterSize/m_minimumSizeStep)*m_minimumSizeStep); + + // Ainsi que le style (uniquement le gras et l'italique, les autres sont gérés par un TextDrawer) nzUInt64 stylePart = 0; if (style & nzTextStyle_Bold) @@ -305,12 +314,43 @@ nzUInt64 NzFont::ComputeKey(unsigned int characterSize, nzUInt32 style) const return (stylePart << 32) | sizePart; } -void NzFont::OnAtlasCleared() +bool NzFont::OnAtlasCleared(const NzAbstractFontAtlas* atlas, void* userdata) { + NazaraUnused(atlas); + NazaraUnused(userdata); + + #ifdef NAZARA_DEBUG + // Est-ce qu'il s'agit bien de notre atlas ? + if (m_atlas != atlas) + { + NazaraInternalError("Notified by a non-listening-to resource"); + return false; // On ne veut plus être notifié par cette ressource, évidemment + } + #endif + // Notre atlas vient d'être vidé, détruisons le cache de glyphe m_glyphes.clear(); - NotifyModified(ModificationCode_GlyphCacheCleared); + + return true; +} + +void NzFont::OnAtlasReleased(const NzAbstractFontAtlas* atlas, void* userdata) +{ + NazaraUnused(atlas); + NazaraUnused(userdata); + + #ifdef NAZARA_DEBUG + // Est-ce qu'il s'agit bien de notre atlas ? + if (m_atlas != atlas) + { + NazaraInternalError("Notified by a non-listening-to resource"); + return; + } + #endif + + // Nous ne pouvons pas faire grand chose d'autre que se balancer une erreur à la tête de l'utilisateur avant un potentiel crash... + NazaraError("Atlas has been released while in use"); } const NzFont::Glyph& NzFont::PrecacheGlyph(GlyphMap& glyphMap, unsigned int characterSize, nzUInt32 style, char32_t character) const From 1781e934624fa94e8cb2f1c457db2a92fdc63e39 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 16 Jan 2015 12:40:23 +0100 Subject: [PATCH 142/233] Renamed AbstractFontAtlas to AbstractAtlas Former-commit-id: 2908a05a7d2d6d44e2e29e96c52cafe962382b71 --- ...bstractFontAtlas.hpp => AbstractAtlas.hpp} | 16 ++++++++-------- include/Nazara/Utility/Font.hpp | 15 +++++++-------- .../Nazara/Utility/GuillotineImageAtlas.hpp | 4 ++-- ...bstractFontAtlas.cpp => AbstractAtlas.cpp} | 19 +++++++++---------- src/Nazara/Utility/Font.cpp | 8 ++++---- 5 files changed, 30 insertions(+), 32 deletions(-) rename include/Nazara/Utility/{AbstractFontAtlas.hpp => AbstractAtlas.hpp} (74%) rename src/Nazara/Utility/{AbstractFontAtlas.cpp => AbstractAtlas.cpp} (58%) diff --git a/include/Nazara/Utility/AbstractFontAtlas.hpp b/include/Nazara/Utility/AbstractAtlas.hpp similarity index 74% rename from include/Nazara/Utility/AbstractFontAtlas.hpp rename to include/Nazara/Utility/AbstractAtlas.hpp index f029731f2..6cb56f41f 100644 --- a/include/Nazara/Utility/AbstractFontAtlas.hpp +++ b/include/Nazara/Utility/AbstractAtlas.hpp @@ -4,8 +4,8 @@ #pragma once -#ifndef NAZARA_ABSTRACTFONTATLAS_HPP -#define NAZARA_ABSTRACTFONTATLAS_HPP +#ifndef NAZARA_ABSTRACTATLAS_HPP +#define NAZARA_ABSTRACTATLAS_HPP #include #include @@ -15,13 +15,13 @@ class NzAbstractImage; class NzImage; -class NAZARA_API NzAbstractFontAtlas +class NAZARA_API NzAbstractAtlas { public: class Listener; - NzAbstractFontAtlas(); - virtual ~NzAbstractFontAtlas(); + NzAbstractAtlas(); + virtual ~NzAbstractAtlas(); void AddListener(Listener* font, void* userdata = nullptr) const; @@ -39,8 +39,8 @@ class NAZARA_API NzAbstractFontAtlas Listener() = default; virtual ~Listener(); - virtual bool OnAtlasCleared(const NzAbstractFontAtlas* atlas, void* userdata); - virtual void OnAtlasReleased(const NzAbstractFontAtlas* atlas, void* userdata); + virtual bool OnAtlasCleared(const NzAbstractAtlas* atlas, void* userdata); + virtual void OnAtlasReleased(const NzAbstractAtlas* atlas, void* userdata); }; protected: @@ -51,4 +51,4 @@ class NAZARA_API NzAbstractFontAtlas bool m_listenersLocked; }; -#endif // NAZARA_ABSTRACTFONTATLAS_HPP +#endif // NAZARA_ABSTRACTATLAS_HPP diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index 82164b09f..0c6080429 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include @@ -29,9 +29,8 @@ using NzFontConstRef = NzResourceRef; using NzFontLoader = NzResourceLoader; using NzFontRef = NzResourceRef; -class NAZARA_API NzFont : public NzResource, NzAbstractFontAtlas::Listener, NzNonCopyable +class NAZARA_API NzFont : public NzResource, NzAbstractAtlas::Listener, NzNonCopyable { - friend NzAbstractFontAtlas; friend NzFontLoader; public: @@ -51,7 +50,7 @@ class NAZARA_API NzFont : public NzResource, NzAbstractFontAtlas::Listener, NzNo bool ExtractGlyph(unsigned int characterSize, char32_t character, nzUInt32 style, NzFontGlyph* glyph) const; - const NzAbstractFontAtlas* GetAtlas() const; + const NzAbstractAtlas* GetAtlas() const; unsigned int GetCachedGlyphCount(unsigned int characterSize, nzUInt32 style) const; unsigned int GetCachedGlyphCount() const; NzString GetFamilyName() const; @@ -72,7 +71,7 @@ class NAZARA_API NzFont : public NzResource, NzAbstractFontAtlas::Listener, NzNo bool OpenFromMemory(const void* data, std::size_t size, const NzFontParams& params = NzFontParams()); bool OpenFromStream(NzInputStream& stream, const NzFontParams& params = NzFontParams()); - void SetAtlas(std::shared_ptr atlas); + void SetAtlas(std::shared_ptr atlas); void SetGlyphBorder(unsigned int borderSize); void SetMinimumStepSize(unsigned int minimumSizeStep); @@ -108,11 +107,11 @@ class NAZARA_API NzFont : public NzResource, NzAbstractFontAtlas::Listener, NzNo using GlyphMap = std::unordered_map; nzUInt64 ComputeKey(unsigned int characterSize, nzUInt32 style) const; - bool OnAtlasCleared(const NzAbstractFontAtlas* atlas, void* userdata) override; - void OnAtlasReleased(const NzAbstractFontAtlas* atlas, void* userdata) override; + bool OnAtlasCleared(const NzAbstractAtlas* atlas, void* userdata) override; + void OnAtlasReleased(const NzAbstractAtlas* atlas, void* userdata) override; const Glyph& PrecacheGlyph(GlyphMap& glyphMap, unsigned int characterSize, nzUInt32 style, char32_t character) const; - std::shared_ptr m_atlas; + std::shared_ptr m_atlas; std::unique_ptr m_data; mutable std::unordered_map> m_kerningCache; mutable std::unordered_map m_glyphes; diff --git a/include/Nazara/Utility/GuillotineImageAtlas.hpp b/include/Nazara/Utility/GuillotineImageAtlas.hpp index 1bc478427..b17e2c647 100644 --- a/include/Nazara/Utility/GuillotineImageAtlas.hpp +++ b/include/Nazara/Utility/GuillotineImageAtlas.hpp @@ -9,13 +9,13 @@ #include #include -#include +#include #include #include #include #include -class NAZARA_API NzGuillotineImageAtlas : public NzAbstractFontAtlas +class NAZARA_API NzGuillotineImageAtlas : public NzAbstractAtlas { public: NzGuillotineImageAtlas(); diff --git a/src/Nazara/Utility/AbstractFontAtlas.cpp b/src/Nazara/Utility/AbstractAtlas.cpp similarity index 58% rename from src/Nazara/Utility/AbstractFontAtlas.cpp rename to src/Nazara/Utility/AbstractAtlas.cpp index 710c52d8f..5fa7a2ca1 100644 --- a/src/Nazara/Utility/AbstractFontAtlas.cpp +++ b/src/Nazara/Utility/AbstractAtlas.cpp @@ -2,35 +2,34 @@ // 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 -NzAbstractFontAtlas::NzAbstractFontAtlas() : +NzAbstractAtlas::NzAbstractAtlas() : m_listenersLocked(false) { } -NzAbstractFontAtlas::~NzAbstractFontAtlas() +NzAbstractAtlas::~NzAbstractAtlas() { m_listenersLocked = true; for (auto& pair : m_listeners) pair.first->OnAtlasReleased(this, pair.second); } -void NzAbstractFontAtlas::AddListener(Listener* listener, void* userdata) const +void NzAbstractAtlas::AddListener(Listener* listener, void* userdata) const { if (!m_listenersLocked) m_listeners.insert(std::make_pair(listener, userdata)); } -void NzAbstractFontAtlas::RemoveListener(Listener* listener) const +void NzAbstractAtlas::RemoveListener(Listener* listener) const { if (!m_listenersLocked) m_listeners.erase(listener); } -void NzAbstractFontAtlas::NotifyCleared() +void NzAbstractAtlas::NotifyCleared() { m_listenersLocked = true; @@ -46,9 +45,9 @@ void NzAbstractFontAtlas::NotifyCleared() m_listenersLocked = false; } -NzAbstractFontAtlas::Listener::~Listener() = default; +NzAbstractAtlas::Listener::~Listener() = default; -bool NzAbstractFontAtlas::Listener::OnAtlasCleared(const NzAbstractFontAtlas* atlas, void* userdata) +bool NzAbstractAtlas::Listener::OnAtlasCleared(const NzAbstractAtlas* atlas, void* userdata) { NazaraUnused(atlas); NazaraUnused(userdata); @@ -56,7 +55,7 @@ bool NzAbstractFontAtlas::Listener::OnAtlasCleared(const NzAbstractFontAtlas* at return true; } -void NzAbstractFontAtlas::Listener::OnAtlasReleased(const NzAbstractFontAtlas* atlas, void* userdata) +void NzAbstractAtlas::Listener::OnAtlasReleased(const NzAbstractAtlas* atlas, void* userdata) { NazaraUnused(atlas); NazaraUnused(userdata); diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index d1e061b0b..70122458a 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -101,7 +101,7 @@ bool NzFont::ExtractGlyph(unsigned int characterSize, char32_t character, nzUInt return m_data->ExtractGlyph(characterSize, character, style, glyph); } -const NzAbstractFontAtlas* NzFont::GetAtlas() const +const NzAbstractAtlas* NzFont::GetAtlas() const { return m_atlas.get(); } @@ -265,7 +265,7 @@ bool NzFont::OpenFromStream(NzInputStream& stream, const NzFontParams& params) return NzFontLoader::LoadFromStream(this, stream, params); } -void NzFont::SetAtlas(std::shared_ptr atlas) +void NzFont::SetAtlas(std::shared_ptr atlas) { ClearGlyphCache(); @@ -314,7 +314,7 @@ nzUInt64 NzFont::ComputeKey(unsigned int characterSize, nzUInt32 style) const return (stylePart << 32) | sizePart; } -bool NzFont::OnAtlasCleared(const NzAbstractFontAtlas* atlas, void* userdata) +bool NzFont::OnAtlasCleared(const NzAbstractAtlas* atlas, void* userdata) { NazaraUnused(atlas); NazaraUnused(userdata); @@ -335,7 +335,7 @@ bool NzFont::OnAtlasCleared(const NzAbstractFontAtlas* atlas, void* userdata) return true; } -void NzFont::OnAtlasReleased(const NzAbstractFontAtlas* atlas, void* userdata) +void NzFont::OnAtlasReleased(const NzAbstractAtlas* atlas, void* userdata) { NazaraUnused(atlas); NazaraUnused(userdata); From 9d83f3f474db74cb335e5c63deb1bf771b6a19e3 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 16 Jan 2015 12:42:27 +0100 Subject: [PATCH 143/233] (Font) Added spaceAdvance SizeInfo Former-commit-id: 2767915c2554103615918347c6e742cb324092c5 --- include/Nazara/Utility/Font.hpp | 1 + src/Nazara/Utility/Font.cpp | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index 0c6080429..4605fe975 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -98,6 +98,7 @@ class NAZARA_API NzFont : public NzResource, NzAbstractAtlas::Listener, NzNonCop struct SizeInfo { + int spaceAdvance; unsigned int lineHeight; float underlinePosition; float underlineThickness; diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index 70122458a..c15756a67 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -202,6 +202,15 @@ const NzFont::SizeInfo& NzFont::GetSizeInfo(unsigned int characterSize) const sizeInfo.underlinePosition = m_data->QueryUnderlinePosition(characterSize); sizeInfo.underlineThickness = m_data->QueryUnderlineThickness(characterSize); + NzFontGlyph glyph; + if (m_data->ExtractGlyph(characterSize, ' ', nzTextStyle_None, &glyph)) + sizeInfo.spaceAdvance = glyph.advance; + else + { + NazaraWarning("Failed to extract space character from font, using half the size"); + sizeInfo.spaceAdvance = characterSize/2; + } + it = m_sizeInfoCache.insert(std::make_pair(characterSize, sizeInfo)).first; } From bdaa4f283889929667b256a2aaa14191d91d58fa Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 16 Jan 2015 12:45:29 +0100 Subject: [PATCH 144/233] Renamed TextStyle_None to TextStyle_Regular Former-commit-id: 3bd44c785f8c6f011bcade1242b051d8662287d2 --- include/Nazara/Utility/Enums.hpp | 2 +- src/Nazara/Utility/Font.cpp | 2 +- src/Nazara/Utility/Loaders/FreeType/Loader.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/Nazara/Utility/Enums.hpp b/include/Nazara/Utility/Enums.hpp index 4c00fdad6..d243a4864 100644 --- a/include/Nazara/Utility/Enums.hpp +++ b/include/Nazara/Utility/Enums.hpp @@ -230,7 +230,7 @@ enum nzTextAlign enum nzTextStyleFlags { - nzTextStyle_None = 0x0, + nzTextStyle_Regular = 0x0, nzTextStyle_Bold = 0x1, nzTextStyle_Italic = 0x2, diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index c15756a67..f73eceee9 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -203,7 +203,7 @@ const NzFont::SizeInfo& NzFont::GetSizeInfo(unsigned int characterSize) const sizeInfo.underlineThickness = m_data->QueryUnderlineThickness(characterSize); NzFontGlyph glyph; - if (m_data->ExtractGlyph(characterSize, ' ', nzTextStyle_None, &glyph)) + if (m_data->ExtractGlyph(characterSize, ' ', nzTextStyle_Regular, &glyph)) sizeInfo.spaceAdvance = glyph.advance; else { diff --git a/src/Nazara/Utility/Loaders/FreeType/Loader.cpp b/src/Nazara/Utility/Loaders/FreeType/Loader.cpp index 35d6f0ff3..92c9b0910 100644 --- a/src/Nazara/Utility/Loaders/FreeType/Loader.cpp +++ b/src/Nazara/Utility/Loaders/FreeType/Loader.cpp @@ -287,7 +287,7 @@ namespace bool SupportsStyle(nzUInt32 style) const override { ///TODO - return style == nzTextStyle_None || style == nzTextStyle_Bold; + return style == nzTextStyle_Regular || style == nzTextStyle_Bold; } private: From e85c6afa1201737dcd3d3705ef9837c3e00023db Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 16 Jan 2015 12:46:07 +0100 Subject: [PATCH 145/233] Added some formats (.fon, .otf and .ttc) support to FreeType loader Former-commit-id: ff5d9f9522c920976929603f25d056ed68e6d971 --- src/Nazara/Utility/Loaders/FreeType/Loader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Utility/Loaders/FreeType/Loader.cpp b/src/Nazara/Utility/Loaders/FreeType/Loader.cpp index 92c9b0910..1bf65dcbd 100644 --- a/src/Nazara/Utility/Loaders/FreeType/Loader.cpp +++ b/src/Nazara/Utility/Loaders/FreeType/Loader.cpp @@ -311,7 +311,7 @@ namespace { ///FIXME: Je suppose qu'il en manque quelques unes.. static std::set supportedExtensions = { - "afm", "bdf", "cff", "cid", "dfont", "fnt", "pfa", "pfb", "pfm", "pfr", "sfnt", "tte", "ttf" + "afm", "bdf", "cff", "cid", "dfont", "fnt", "fon", "otf", "pfa", "pfb", "pfm", "pfr", "sfnt", "ttc", "tte", "ttf" }; return supportedExtensions.find(extension) != supportedExtensions.end(); From fbcdd6bb2bc726ffca3c2f9bff6245a5ab7e92be Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 16 Jan 2015 12:46:27 +0100 Subject: [PATCH 146/233] Fixed potential crash Former-commit-id: df8cde180c157f08031cd04d37bb735aa266ee53 --- src/Nazara/Graphics/ForwardRenderQueue.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index 254194e87..c148d56f1 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -165,7 +165,8 @@ void NzForwardRenderQueue::Clear(bool fully) for (auto& overlayPair : overlayMap) { const NzTexture* overlay = overlayPair.first; - overlay->RemoveResourceListener(this); + if (overlay) + overlay->RemoveResourceListener(this); } } basicSprites.clear(); From 3139e80902557f24fd7e7219a8fb5e930374d636 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 16 Jan 2015 12:46:42 +0100 Subject: [PATCH 147/233] Fixed do-while Former-commit-id: 08f2520ddee6e6f006f04d60df4a3da52b2ec356 --- src/Nazara/Graphics/ForwardRenderTechnique.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 6764c271a..0a73e8641 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -226,6 +226,8 @@ void NzForwardRenderTechnique::DrawBasicSprites(const NzScene* scene) const NzVertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(vertexMapper.GetPointer()); unsigned int spriteCount = 0; + + do { NzForwardRenderQueue::SpriteChain_XYZ_Color_UV& currentChain = spriteChainVector[spriteChain]; unsigned int count = std::min(s_maxSprites - spriteCount, currentChain.spriteCount - spriteChainOffset); From b5dbe6f03f454c35701208d4ff2c180ae953f209 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 16 Jan 2015 12:52:10 +0100 Subject: [PATCH 148/233] Added XY_Color VertexLayout Former-commit-id: 0f53126584b61738b25b1d86cec819d6166ad678 --- include/Nazara/Utility/Enums.hpp | 1 + include/Nazara/Utility/VertexStruct.hpp | 5 +++++ src/Nazara/Utility/VertexDeclaration.cpp | 7 +++++++ 3 files changed, 13 insertions(+) diff --git a/include/Nazara/Utility/Enums.hpp b/include/Nazara/Utility/Enums.hpp index d243a4864..ac056a41b 100644 --- a/include/Nazara/Utility/Enums.hpp +++ b/include/Nazara/Utility/Enums.hpp @@ -274,6 +274,7 @@ enum nzVertexLayout { // Déclarations destinées au rendu nzVertexLayout_XY, + nzVertexLayout_XY_Color, nzVertexLayout_XY_UV, nzVertexLayout_XYZ, nzVertexLayout_XYZ_Color, diff --git a/include/Nazara/Utility/VertexStruct.hpp b/include/Nazara/Utility/VertexStruct.hpp index 15cb02d28..9cc365aee 100644 --- a/include/Nazara/Utility/VertexStruct.hpp +++ b/include/Nazara/Utility/VertexStruct.hpp @@ -18,6 +18,11 @@ struct NzVertexStruct_XY NzVector2f position; }; +struct NzVertexStruct_XY_Color : NzVertexStruct_XY +{ + NzColor color; +}; + struct NzVertexStruct_XY_UV : NzVertexStruct_XY { NzVector2f uv; diff --git a/src/Nazara/Utility/VertexDeclaration.cpp b/src/Nazara/Utility/VertexDeclaration.cpp index 00e9d9768..9cb0162de 100644 --- a/src/Nazara/Utility/VertexDeclaration.cpp +++ b/src/Nazara/Utility/VertexDeclaration.cpp @@ -192,6 +192,13 @@ bool NzVertexDeclaration::Initialize() NazaraAssert(declaration->GetStride() == sizeof(NzVertexStruct_XY), "Invalid stride for declaration nzVertexLayout_XY"); + // nzVertexLayout_XY_Color : NzVertexStruct_XY_Color + declaration = &s_declarations[nzVertexLayout_XY_Color]; + declaration->EnableComponent(nzVertexComponent_Position, nzComponentType_Float2, NzOffsetOf(NzVertexStruct_XY_Color, position)); + declaration->EnableComponent(nzVertexComponent_Color, nzComponentType_Color, NzOffsetOf(NzVertexStruct_XY_Color, color)); + + NazaraAssert(declaration->GetStride() == sizeof(NzVertexStruct_XY_Color), "Invalid stride for declaration nzVertexLayout_XY_Color"); + // nzVertexLayout_XY_UV : NzVertexStruct_XY_UV declaration = &s_declarations[nzVertexLayout_XY_UV]; declaration->EnableComponent(nzVertexComponent_Position, nzComponentType_Float2, NzOffsetOf(NzVertexStruct_XY_UV, position)); From e36e8a21e04effe20af6e644ffa2cdb1f25ed616 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 16 Jan 2015 12:52:48 +0100 Subject: [PATCH 149/233] Fixed VertexLayout_XYZ_Color_UV declaration Former-commit-id: e9aa4604e88467c23dd889da943d9e00b75ae637 --- src/Nazara/Utility/VertexDeclaration.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Utility/VertexDeclaration.cpp b/src/Nazara/Utility/VertexDeclaration.cpp index 9cb0162de..e65814660 100644 --- a/src/Nazara/Utility/VertexDeclaration.cpp +++ b/src/Nazara/Utility/VertexDeclaration.cpp @@ -213,7 +213,7 @@ bool NzVertexDeclaration::Initialize() NazaraAssert(declaration->GetStride() == sizeof(NzVertexStruct_XYZ), "Invalid stride for declaration nzVertexLayout_XYZ"); // nzVertexLayout_XYZ_Color : NzVertexStruct_XYZ_Color - declaration = &s_declarations[nzVertexLayout_XYZ_Color_UV]; + declaration = &s_declarations[nzVertexLayout_XYZ_Color]; declaration->EnableComponent(nzVertexComponent_Position, nzComponentType_Float3, NzOffsetOf(NzVertexStruct_XYZ_Color, position)); declaration->EnableComponent(nzVertexComponent_Color, nzComponentType_Color, NzOffsetOf(NzVertexStruct_XYZ_Color, color)); From 40db7a729298550fa842f770014f1ddcec60537d Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 16 Jan 2015 12:53:23 +0100 Subject: [PATCH 150/233] Fixed AbstractImage destructor not being virtual Former-commit-id: fd93b711d9b4ffbd370a61d1a7515da71e3d6001 --- include/Nazara/Utility/AbstractImage.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Utility/AbstractImage.hpp b/include/Nazara/Utility/AbstractImage.hpp index 345868890..8697ea813 100644 --- a/include/Nazara/Utility/AbstractImage.hpp +++ b/include/Nazara/Utility/AbstractImage.hpp @@ -17,7 +17,7 @@ class NAZARA_API NzAbstractImage { public: NzAbstractImage() = default; - ~NzAbstractImage(); + virtual ~NzAbstractImage(); nzUInt8 GetBytesPerPixel() const; virtual unsigned int GetDepth(nzUInt8 level = 0) const = 0; From c2f3ba00f28e2e4f09bb4f3c2396e67179dbda6f Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 16 Jan 2015 13:02:53 +0100 Subject: [PATCH 151/233] Revert "Added ResourceConstListener" This reverts commit 2492f87ba89bafa180308c60d2470b07e3aac27d [formerly 793b9a8884fb6153d5da152e2cf22659fc7e511b]. Former-commit-id: 05a9dff26921db1e7c1c5b90c0cd50073a839f3c --- include/Nazara/Core/Resource.hpp | 6 -- include/Nazara/Core/ResourceConstListener.hpp | 26 -------- src/Nazara/Core/Resource.cpp | 63 ------------------- src/Nazara/Core/ResourceConstListener.cpp | 39 ------------ 4 files changed, 134 deletions(-) delete mode 100644 include/Nazara/Core/ResourceConstListener.hpp delete mode 100644 src/Nazara/Core/ResourceConstListener.cpp diff --git a/include/Nazara/Core/Resource.hpp b/include/Nazara/Core/Resource.hpp index e82b33fad..adf0eace2 100644 --- a/include/Nazara/Core/Resource.hpp +++ b/include/Nazara/Core/Resource.hpp @@ -17,7 +17,6 @@ #include #endif -class NzResourceConstListener; class NzResourceListener; class NAZARA_API NzResource @@ -26,7 +25,6 @@ class NAZARA_API NzResource NzResource(bool persistent = true); virtual ~NzResource(); - void AddResourceConstListener(const NzResourceConstListener* listener, int index = 0) const; void AddResourceListener(NzResourceListener* listener, int index = 0) const; void AddResourceReference() const; @@ -34,7 +32,6 @@ class NAZARA_API NzResource bool IsPersistent() const; - void RemoveResourceConstListener(const NzResourceConstListener* listener) const; void RemoveResourceListener(NzResourceListener* listener) const; bool RemoveResourceReference() const; @@ -46,16 +43,13 @@ class NAZARA_API NzResource void NotifyModified(unsigned int code); private: - using ResourceConstListenerMap = std::unordered_map>; using ResourceListenerMap = std::unordered_map>; - void RemoveResourceConstListenerIterator(ResourceConstListenerMap::iterator iterator) const; void RemoveResourceListenerIterator(ResourceListenerMap::iterator iterator) const; NazaraMutexAttrib(m_mutex, mutable) // Je fais précéder le nom par 'resource' pour éviter les éventuels conflits de noms - mutable ResourceConstListenerMap m_resourceConstListeners; mutable ResourceListenerMap m_resourceListeners; std::atomic_bool m_resourcePersistent; mutable std::atomic_uint m_resourceReferenceCount; diff --git a/include/Nazara/Core/ResourceConstListener.hpp b/include/Nazara/Core/ResourceConstListener.hpp deleted file mode 100644 index 7113c3c94..000000000 --- a/include/Nazara/Core/ResourceConstListener.hpp +++ /dev/null @@ -1,26 +0,0 @@ -// 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 - -#pragma once - -#ifndef NAZARA_RESOURCECONSTLISTENER_HPP -#define NAZARA_RESOURCECONSTLISTENER_HPP - -#include - -class NzResource; - -class NAZARA_API NzResourceConstListener -{ - public: - NzResourceConstListener() = default; - virtual ~NzResourceConstListener(); - - virtual bool OnResourceCreated(const NzResource* resource, int index) const; - virtual bool OnResourceDestroy(const NzResource* resource, int index) const; - virtual bool OnResourceModified(const NzResource* resource, int index, unsigned int code) const; - virtual void OnResourceReleased(const NzResource* resource, int index) const; -}; - -#endif // NAZARA_RESOURCECONSTLISTENER_HPP diff --git a/src/Nazara/Core/Resource.cpp b/src/Nazara/Core/Resource.cpp index fbdaf1853..5610d9d13 100644 --- a/src/Nazara/Core/Resource.cpp +++ b/src/Nazara/Core/Resource.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #if NAZARA_CORE_THREADSAFE && NAZARA_THREADSAFETY_RESOURCE @@ -35,19 +34,6 @@ NzResource::~NzResource() #endif } -void NzResource::AddResourceConstListener(const NzResourceConstListener* listener, int index) const -{ - ///DOC: Est ignoré si appelé depuis un évènement - NazaraLock(m_mutex) - - if (!m_resourceListenersLocked) - { - auto pair = m_resourceConstListeners.insert(std::make_pair(listener, std::make_pair(index, 1U))); - if (!pair.second) - pair.first->second.second++; - } -} - void NzResource::AddResourceListener(NzResourceListener* listener, int index) const { ///DOC: Est ignoré si appelé depuis un évènement @@ -76,19 +62,6 @@ bool NzResource::IsPersistent() const return m_resourcePersistent; } -void NzResource::RemoveResourceConstListener(const NzResourceConstListener* listener) const -{ - ///DOC: Est ignoré si appelé depuis un évènement - NazaraLock(m_mutex); - - if (!m_resourceListenersLocked) - { - ResourceConstListenerMap::iterator it = m_resourceConstListeners.find(listener); - if (it != m_resourceConstListeners.end()) - RemoveResourceConstListenerIterator(it); - } -} - void NzResource::RemoveResourceListener(NzResourceListener* listener) const { ///DOC: Est ignoré si appelé depuis un évènement @@ -142,15 +115,6 @@ void NzResource::NotifyCreated() m_resourceListenersLocked = true; - auto constIt = m_resourceConstListeners.begin(); - while (constIt != m_resourceConstListeners.end()) - { - if (!constIt->first->OnResourceCreated(this, constIt->second.first)) - RemoveResourceConstListenerIterator(constIt++); - else - ++constIt; - } - auto it = m_resourceListeners.begin(); while (it != m_resourceListeners.end()) { @@ -169,15 +133,6 @@ void NzResource::NotifyDestroy() m_resourceListenersLocked = true; - auto constIt = m_resourceConstListeners.begin(); - while (constIt != m_resourceConstListeners.end()) - { - if (!constIt->first->OnResourceDestroy(this, constIt->second.first)) - RemoveResourceConstListenerIterator(constIt++); - else - ++constIt; - } - auto it = m_resourceListeners.begin(); while (it != m_resourceListeners.end()) { @@ -196,15 +151,6 @@ void NzResource::NotifyModified(unsigned int code) m_resourceListenersLocked = true; - auto constIt = m_resourceConstListeners.begin(); - while (constIt != m_resourceConstListeners.end()) - { - if (!constIt->first->OnResourceModified(this, constIt->second.first, code)) - RemoveResourceConstListenerIterator(constIt++); - else - ++constIt; - } - auto it = m_resourceListeners.begin(); while (it != m_resourceListeners.end()) { @@ -217,15 +163,6 @@ void NzResource::NotifyModified(unsigned int code) m_resourceListenersLocked = false; } -void NzResource::RemoveResourceConstListenerIterator(ResourceConstListenerMap::iterator iterator) const -{ - unsigned int& referenceCount = iterator->second.second; - if (referenceCount == 1) - m_resourceConstListeners.erase(iterator); - else - referenceCount--; -} - void NzResource::RemoveResourceListenerIterator(ResourceListenerMap::iterator iterator) const { unsigned int& referenceCount = iterator->second.second; diff --git a/src/Nazara/Core/ResourceConstListener.cpp b/src/Nazara/Core/ResourceConstListener.cpp deleted file mode 100644 index ebcbdc0ec..000000000 --- a/src/Nazara/Core/ResourceConstListener.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (C) 2014 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 - -NzResourceConstListener::~NzResourceConstListener() = default; - -bool NzResourceConstListener::OnResourceCreated(const NzResource* resource, int index) const -{ - NazaraUnused(resource); - NazaraUnused(index); - - return true; -} - -bool NzResourceConstListener::OnResourceDestroy(const NzResource* resource, int index) const -{ - NazaraUnused(resource); - NazaraUnused(index); - - return true; -} - -bool NzResourceConstListener::OnResourceModified(const NzResource* resource, int index, unsigned int code) const -{ - NazaraUnused(resource); - NazaraUnused(index); - NazaraUnused(code); - - return true; -} - -void NzResourceConstListener::OnResourceReleased(const NzResource* resource, int index) const -{ - NazaraUnused(resource); - NazaraUnused(index); -} From 96743375d9d4ff6181cafefd41ea449ee4fdff45 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 16 Jan 2015 13:25:51 +0100 Subject: [PATCH 152/233] Fixed debug build Former-commit-id: 5a7ebd258d4b453412d0d74e7be8590905b26a78 --- src/Nazara/Utility/Font.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index f73eceee9..495e0dc7f 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -330,7 +330,7 @@ bool NzFont::OnAtlasCleared(const NzAbstractAtlas* atlas, void* userdata) #ifdef NAZARA_DEBUG // Est-ce qu'il s'agit bien de notre atlas ? - if (m_atlas != atlas) + if (m_atlas.get() != atlas) { NazaraInternalError("Notified by a non-listening-to resource"); return false; // On ne veut plus être notifié par cette ressource, évidemment @@ -351,7 +351,7 @@ void NzFont::OnAtlasReleased(const NzAbstractAtlas* atlas, void* userdata) #ifdef NAZARA_DEBUG // Est-ce qu'il s'agit bien de notre atlas ? - if (m_atlas != atlas) + if (m_atlas.get() != atlas) { NazaraInternalError("Notified by a non-listening-to resource"); return; From 5eec0d2abe4fb8ae18efa693ba938e4e8dec3a48 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 16 Jan 2015 14:03:06 +0100 Subject: [PATCH 153/233] Improved (Fixed ?) Material Copy/Move Former-commit-id: 8eb9b716e2b028c6d2e249f9706ad6f5567c95dc --- include/Nazara/Graphics/Material.hpp | 1 + src/Nazara/Graphics/Material.cpp | 89 ++++++++++++++++------------ 2 files changed, 51 insertions(+), 39 deletions(-) diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index 0f41e0f39..a4192b0e3 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -140,6 +140,7 @@ class NAZARA_API NzMaterial : public NzResource }; void Copy(const NzMaterial& material); + void Move(NzMaterial&& material); void GenerateShader(nzUInt32 flags) const; void InvalidateShaders(); diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 24e26613d..e674f8e96 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -36,16 +36,7 @@ NzResource() NzMaterial::NzMaterial(NzMaterial&& material) { - Copy(material); - - // Nous "volons" la référence du matériau - material.m_alphaMap.Reset(); - material.m_diffuseMap.Reset(); - material.m_emissiveMap.Reset(); - material.m_heightMap.Reset(); - material.m_normalMap.Reset(); - material.m_specularMap.Reset(); - material.m_uberShader.Reset(); + Move(material); } NzMaterial::~NzMaterial() @@ -624,16 +615,7 @@ NzMaterial& NzMaterial::operator=(const NzMaterial& material) NzMaterial& NzMaterial::operator=(NzMaterial&& material) { - Copy(material); - - // Comme ça nous volons la référence du matériau - material.m_alphaMap.Reset(); - material.m_diffuseMap.Reset(); - material.m_emissiveMap.Reset(); - material.m_heightMap.Reset(); - material.m_normalMap.Reset(); - material.m_specularMap.Reset(); - material.m_uberShader.Reset(); + Move(material); return *this; } @@ -645,33 +627,62 @@ NzMaterial* NzMaterial::GetDefault() void NzMaterial::Copy(const NzMaterial& material) { - // On relache les références proprement - m_alphaMap.Reset(); - m_diffuseMap.Reset(); - m_emissiveMap.Reset(); - m_heightMap.Reset(); - m_normalMap.Reset(); - m_specularMap.Reset(); - m_uberShader.Reset(); - - std::memcpy(this, &material, sizeof(NzMaterial)); // Autorisé dans notre cas, et bien plus rapide - - // Ensuite une petite astuce pour récupérer correctement les références - m_alphaMap.Release(); - m_diffuseMap.Release(); - m_emissiveMap.Release(); - m_heightMap.Release(); - m_normalMap.Release(); - m_specularMap.Release(); - m_uberShader.Release(); + // Copie des états de base + m_alphaTestEnabled = material.m_alphaTestEnabled; + m_alphaThreshold = material.m_alphaThreshold; + m_ambientColor = material.m_ambientColor; + 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; + // 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; + + // 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)); +} + +void NzMaterial::Move(NzMaterial&& material) +{ + // Copie des états de base + m_alphaTestEnabled = material.m_alphaTestEnabled; + m_alphaThreshold = material.m_alphaThreshold; + m_ambientColor = material.m_ambientColor; + 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; + + // Vol des références de texture + m_alphaMap = std::move(material.m_alphaMap); + m_diffuseMap = std::move(material.m_diffuseMap); + m_emissiveMap = std::move(material.m_emissiveMap); + m_heightMap = std::move(material.m_heightMap); + m_normalMap = std::move(material.m_normalMap); + m_specularMap = std::move(material.m_specularMap); + + // Vol de la référence vers l'Über-Shader + m_uberShader = std::move(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)); } void NzMaterial::GenerateShader(nzUInt32 flags) const From ff7cfa226e59f5d6989582c81c105dcaf20a26cd Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 16 Jan 2015 16:26:15 +0100 Subject: [PATCH 154/233] Improved Atlas class It now handles layer resize failure and will notify listeners of a pointer change Former-commit-id: df5e2a129897128a4e41e0b3205f6a1dbeb2069c --- .../Graphics/GuillotineTextureAtlas.hpp | 3 +- include/Nazara/Utility/AbstractAtlas.hpp | 2 + .../Nazara/Utility/GuillotineImageAtlas.hpp | 4 +- .../Graphics/GuillotineTextureAtlas.cpp | 38 +++----- src/Nazara/Utility/AbstractAtlas.cpp | 27 ++++++ src/Nazara/Utility/GuillotineImageAtlas.cpp | 88 +++++++++++-------- 6 files changed, 97 insertions(+), 65 deletions(-) diff --git a/include/Nazara/Graphics/GuillotineTextureAtlas.hpp b/include/Nazara/Graphics/GuillotineTextureAtlas.hpp index 3eb14dd68..04197a41b 100644 --- a/include/Nazara/Graphics/GuillotineTextureAtlas.hpp +++ b/include/Nazara/Graphics/GuillotineTextureAtlas.hpp @@ -17,8 +17,7 @@ class NAZARA_API NzGuillotineTextureAtlas : public NzGuillotineImageAtlas ~NzGuillotineTextureAtlas() = default; private: - unsigned int GetMaxAtlasSize() const override; - bool ResizeImage(Layer& layer, const NzVector2ui& size) const override; + NzAbstractImage* ResizeImage(NzAbstractImage* oldImage, const NzVector2ui& size) const override; }; #endif // NAZARA_GUILLOTINETEXTUREATLAS_HPP diff --git a/include/Nazara/Utility/AbstractAtlas.hpp b/include/Nazara/Utility/AbstractAtlas.hpp index 6cb56f41f..2d290153b 100644 --- a/include/Nazara/Utility/AbstractAtlas.hpp +++ b/include/Nazara/Utility/AbstractAtlas.hpp @@ -40,11 +40,13 @@ class NAZARA_API NzAbstractAtlas virtual ~Listener(); virtual bool OnAtlasCleared(const NzAbstractAtlas* atlas, void* userdata); + virtual bool OnAtlasLayerChange(const NzAbstractAtlas* atlas, NzAbstractImage* oldLayer, NzAbstractImage* newLayer, void* userdata); virtual void OnAtlasReleased(const NzAbstractAtlas* atlas, void* userdata); }; protected: void NotifyCleared(); + void NotifyLayerChange(NzAbstractImage* oldLayer, NzAbstractImage* newLayer); private: mutable std::unordered_map m_listeners; diff --git a/include/Nazara/Utility/GuillotineImageAtlas.hpp b/include/Nazara/Utility/GuillotineImageAtlas.hpp index b17e2c647..22c50fdcb 100644 --- a/include/Nazara/Utility/GuillotineImageAtlas.hpp +++ b/include/Nazara/Utility/GuillotineImageAtlas.hpp @@ -37,8 +37,8 @@ class NAZARA_API NzGuillotineImageAtlas : public NzAbstractAtlas protected: struct Layer; - virtual unsigned int GetMaxAtlasSize() const; - virtual bool ResizeImage(Layer& layer, const NzVector2ui& size) const; + virtual NzAbstractImage* ResizeImage(NzAbstractImage* oldImage, const NzVector2ui& size) const; + bool ResizeLayer(Layer& layer, const NzVector2ui& size); struct QueuedGlyph { diff --git a/src/Nazara/Graphics/GuillotineTextureAtlas.cpp b/src/Nazara/Graphics/GuillotineTextureAtlas.cpp index 20e4c6db4..0963eddf3 100644 --- a/src/Nazara/Graphics/GuillotineTextureAtlas.cpp +++ b/src/Nazara/Graphics/GuillotineTextureAtlas.cpp @@ -7,49 +7,37 @@ #include #include -bool NzGuillotineTextureAtlas::ResizeImage(Layer& layer, const NzVector2ui& size) const +NzAbstractImage* NzGuillotineTextureAtlas::ResizeImage(NzAbstractImage* oldImage, const NzVector2ui& size) const { - NzTexture newTexture; - if (newTexture.Create(nzImageType_2D, nzPixelFormat_A8, size.x, size.y, 1, 0xFF)) + std::unique_ptr newTexture(new NzTexture); + if (newTexture->Create(nzImageType_2D, nzPixelFormat_A8, size.x, size.y, 1, 0xFF)) { - if (layer.image) + if (oldImage) { - NzTexture& texture = *static_cast(layer.image.get()); + NzTexture* oldTexture = static_cast(oldImage); // Copie des anciennes données ///TODO: Copie de texture à texture NzImage image; - if (!texture.Download(&image)) + if (!oldTexture->Download(&image)) { NazaraError("Failed to download old texture"); - return false; + return nullptr; } - if (!newTexture.Update(image, NzRectui(0, 0, image.GetWidth(), image.GetHeight()))) + if (!newTexture->Update(image, NzRectui(0, 0, image.GetWidth(), image.GetHeight()))) { NazaraError("Failed to update texture"); - return false; + return nullptr; } - - texture = std::move(newTexture); } - else - layer.image.reset(new NzTexture(std::move(newTexture))); - return true; + return newTexture.release(); } else { - NazaraError("Failed to create texture"); - return false; + // Si on arrive ici c'est que la taille demandée est trop grande pour la carte graphique + // ou que nous manquons de mémoire + return nullptr; } } - -unsigned int NzGuillotineTextureAtlas::GetMaxAtlasSize() const -{ - ///FIXME: D'après la documentation OpenGL, cette valeur n'est qu'une approximation et les texture proxies sont une meilleure solution - /// Cependant le test ne se fait pas au même moment, penser à adapter le code pour gérer ce cas ? - /// (Cela permettrait au passage de gérer le cas où une image ne peut être allouée car il n'y a pas assez de mémoire contigüe pour la contenir) - - return NzRenderer::GetMaxTextureSize(); -} diff --git a/src/Nazara/Utility/AbstractAtlas.cpp b/src/Nazara/Utility/AbstractAtlas.cpp index 5fa7a2ca1..dac73acf7 100644 --- a/src/Nazara/Utility/AbstractAtlas.cpp +++ b/src/Nazara/Utility/AbstractAtlas.cpp @@ -45,6 +45,23 @@ void NzAbstractAtlas::NotifyCleared() m_listenersLocked = false; } +void NzAbstractAtlas::NotifyLayerChange(NzAbstractImage* oldLayer, NzAbstractImage* newLayer) +{ + m_listenersLocked = true; + + auto it = m_listeners.begin(); + while (it != m_listeners.end()) + { + if (!it->first->OnAtlasLayerChange(this, oldLayer, newLayer, it->second)) + m_listeners.erase(it++); + else + ++it; + } + + m_listenersLocked = false; +} + + NzAbstractAtlas::Listener::~Listener() = default; bool NzAbstractAtlas::Listener::OnAtlasCleared(const NzAbstractAtlas* atlas, void* userdata) @@ -55,6 +72,16 @@ bool NzAbstractAtlas::Listener::OnAtlasCleared(const NzAbstractAtlas* atlas, voi return true; } +bool NzAbstractAtlas::Listener::OnAtlasLayerChange(const NzAbstractAtlas* atlas, NzAbstractImage* oldLayer, NzAbstractImage* newLayer, void* userdata) +{ + NazaraUnused(atlas); + NazaraUnused(oldLayer); + NazaraUnused(newLayer); + NazaraUnused(userdata); + + return true; +} + void NzAbstractAtlas::Listener::OnAtlasReleased(const NzAbstractAtlas* atlas, void* userdata) { NazaraUnused(atlas); diff --git a/src/Nazara/Utility/GuillotineImageAtlas.cpp b/src/Nazara/Utility/GuillotineImageAtlas.cpp index a04eed25a..bd7486ab7 100644 --- a/src/Nazara/Utility/GuillotineImageAtlas.cpp +++ b/src/Nazara/Utility/GuillotineImageAtlas.cpp @@ -75,8 +75,6 @@ unsigned int NzGuillotineImageAtlas::GetLayerCount() const bool NzGuillotineImageAtlas::Insert(const NzImage& image, NzRectui* rect, bool* flipped, unsigned int* layerIndex) { - unsigned int maxAtlasSize = GetMaxAtlasSize(); - if (m_layers.empty()) { // On créé une première couche s'il n'y en a pas @@ -112,30 +110,39 @@ bool NzGuillotineImageAtlas::Insert(const NzImage& image, NzRectui* rect, bool* else if (i == m_layers.size() - 1) // Dernière itération ? { // Dernière couche, et le glyphe ne rentre pas, peut-on agrandir la taille de l'image ? - unsigned int size = layer.binPack.GetWidth(); // l'image étant carrée, on ne teste qu'une dimension - if (size < maxAtlasSize) + NzVector2ui newSize = layer.binPack.GetSize()*2; + if (ResizeLayer(layer, newSize)) { - // On peut encore agrandir la couche - size = std::min(size*2, maxAtlasSize); - layer.binPack.Expand(size, size); + // Oui on peut ! + layer.binPack.Expand(newSize); // On ajuste l'atlas virtuel - // On relance la boucle sur la nouvelle dernière couche + // Et on relance la boucle sur la nouvelle dernière couche i--; } else { // On ne peut plus agrandir la dernière couche, il est temps d'en créer une nouvelle - m_layers.resize(m_layers.size() + 1); - Layer& newLayer = m_layers.back(); + newSize.Set(s_atlasStartSize); - newLayer.binPack.Reset(s_atlasStartSize, s_atlasStartSize); + Layer newLayer; + if (!ResizeLayer(newLayer, newSize)) + { + // Impossible d'allouer une nouvelle couche, nous manquons probablement de mémoire (ou le glyphe est trop grand) + NazaraError("Failed to allocate new layer, we are probably out of memory"); + return false; + } + + newLayer.binPack.Reset(newSize); + + m_layers.emplace_back(std::move(newLayer)); // Insertion du layer // On laisse la boucle insérer toute seule le rectangle à la prochaine itération } } } - return false; // Normalement impossible + NazaraInternalError("Unknown error"); // Normalement on ne peut pas arriver ici + return false; } void NzGuillotineImageAtlas::SetRectChoiceHeuristic(NzGuillotineBinPack::FreeRectChoiceHeuristic heuristic) @@ -148,21 +155,46 @@ void NzGuillotineImageAtlas::SetRectSplitHeuristic(NzGuillotineBinPack::Guilloti m_rectSplitHeuristic = heuristic; } -unsigned int NzGuillotineImageAtlas::GetMaxAtlasSize() const +NzAbstractImage* NzGuillotineImageAtlas::ResizeImage(NzAbstractImage* oldImage, const NzVector2ui& size) const { - return 8192; // Valeur totalement arbitraire + std::unique_ptr newImage(new NzImage(nzImageType_2D, nzPixelFormat_A8, size.x, size.y)); + if (oldImage) + { + NzImage& image = *static_cast(oldImage); + newImage->Copy(image, NzRectui(size), NzVector2ui(0, 0)); // Copie des anciennes données + } + + return newImage.release(); +} + +bool NzGuillotineImageAtlas::ResizeLayer(Layer& layer, const NzVector2ui& size) +{ + NzAbstractImage* oldLayer = layer.image.get(); + + std::unique_ptr newImage(ResizeImage(layer.image.get(), size)); + if (!newImage) + return false; // Nous n'avons pas pu allouer + + if (newImage.get() == oldLayer) // Le layer a été agrandi dans le même objet, pas de souci + { + newImage.release(); // On possède déjà un unique_ptr sur cette ressource + return true; + } + + // On indique à ceux que ça intéresse qu'on a changé de pointeur + // (chose très importante pour ceux qui le stockent) + NotifyLayerChange(layer.image.get(), newImage.get()); + + // Et on ne met à jour le pointeur qu'après (car cette ligne libère également l'ancienne image) + layer.image = std::move(newImage); + + return true; } void NzGuillotineImageAtlas::ProcessGlyphQueue(Layer& layer) const { std::vector pixelBuffer; - // On s'assure que l'image est de la bonne taille - NzVector2ui binPackSize(layer.binPack.GetSize()); - NzVector2ui imageSize((layer.image) ? layer.image->GetSize() : NzVector3ui(0U)); - if (binPackSize != imageSize) - ResizeImage(layer, binPackSize); - for (QueuedGlyph& glyph : layer.queuedGlyphs) { unsigned int glyphWidth = glyph.image.GetWidth(); @@ -226,19 +258,3 @@ void NzGuillotineImageAtlas::ProcessGlyphQueue(Layer& layer) const layer.queuedGlyphs.clear(); } - -bool NzGuillotineImageAtlas::ResizeImage(Layer& layer, const NzVector2ui& size) const -{ - NzImage newImage(nzImageType_2D, nzPixelFormat_A8, size.x, size.y); - if (layer.image) - { - NzImage& image = *static_cast(layer.image.get()); - newImage.Copy(image, NzRectui(size), NzVector2ui(0, 0)); // Copie des anciennes données - - image = std::move(newImage); - } - else - layer.image.reset(new NzImage(std::move(newImage))); - - return true; -} From cd5399459d3e3ea22a09a55ee0f170e633bfb2af Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 16 Jan 2015 16:28:38 +0100 Subject: [PATCH 155/233] Made Resource copying/moving impossible It is still possible to copy some Resource-based classes though Former-commit-id: bbb6066f736c210015ff9fdfded7d95eb9695359 --- include/Nazara/Core/Resource.hpp | 5 ++++ include/Nazara/Graphics/Material.hpp | 2 -- include/Nazara/Renderer/Texture.hpp | 3 -- include/Nazara/Utility/Image.hpp | 2 -- src/Nazara/Graphics/Material.cpp | 42 ---------------------------- src/Nazara/Renderer/Texture.cpp | 42 +++++++++------------------- src/Nazara/Utility/Image.cpp | 13 --------- 7 files changed, 18 insertions(+), 91 deletions(-) diff --git a/include/Nazara/Core/Resource.hpp b/include/Nazara/Core/Resource.hpp index adf0eace2..2bc392734 100644 --- a/include/Nazara/Core/Resource.hpp +++ b/include/Nazara/Core/Resource.hpp @@ -23,6 +23,8 @@ class NAZARA_API NzResource { public: NzResource(bool persistent = true); + NzResource(const NzResource& resource) = delete; + NzResource(NzResource&& resource) = delete; virtual ~NzResource(); void AddResourceListener(NzResourceListener* listener, int index = 0) const; @@ -37,6 +39,9 @@ class NAZARA_API NzResource bool SetPersistent(bool persistent = true, bool checkReferenceCount = false); + NzResource& operator=(const NzResource& resource) = delete; + NzResource& operator=(NzResource&& resource) = delete; + protected: void NotifyCreated(); void NotifyDestroy(); diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index a4192b0e3..ffe7f8217 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -46,7 +46,6 @@ class NAZARA_API NzMaterial : public NzResource public: NzMaterial(); NzMaterial(const NzMaterial& material); - NzMaterial(NzMaterial&& material); ~NzMaterial(); const NzShader* Apply(nzUInt32 shaderFlags = 0, nzUInt8 textureUnit = 0, nzUInt8* lastUsedUnit = nullptr) const; @@ -127,7 +126,6 @@ class NAZARA_API NzMaterial : public NzResource void SetSrcBlend(nzBlendFunc func); NzMaterial& operator=(const NzMaterial& material); - NzMaterial& operator=(NzMaterial&& material); static NzMaterial* GetDefault(); diff --git a/include/Nazara/Renderer/Texture.hpp b/include/Nazara/Renderer/Texture.hpp index 5c082cc2e..02a1a208f 100644 --- a/include/Nazara/Renderer/Texture.hpp +++ b/include/Nazara/Renderer/Texture.hpp @@ -31,7 +31,6 @@ class NAZARA_API NzTexture : public NzAbstractImage, public NzResource, NzNonCop NzTexture() = default; NzTexture(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth = 1, nzUInt8 levelCount = 1); explicit NzTexture(const NzImage& image); - NzTexture(NzTexture&& texture); ~NzTexture(); bool Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth = 1, nzUInt8 levelCount = 1); @@ -94,8 +93,6 @@ class NAZARA_API NzTexture : public NzAbstractImage, public NzResource, NzNonCop // Fonctions OpenGL unsigned int GetOpenGLID() const; - NzTexture& operator=(NzTexture&& texture); - static unsigned int GetValidSize(unsigned int size); static bool IsFormatSupported(nzPixelFormat format); static bool IsMipmappingSupported(); diff --git a/include/Nazara/Utility/Image.hpp b/include/Nazara/Utility/Image.hpp index d94177bbe..57c188822 100644 --- a/include/Nazara/Utility/Image.hpp +++ b/include/Nazara/Utility/Image.hpp @@ -46,7 +46,6 @@ class NAZARA_API NzImage : public NzAbstractImage, public NzResource NzImage(); NzImage(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth = 1, nzUInt8 levelCount = 1); NzImage(const NzImage& image); - NzImage(NzImage&& image) noexcept; NzImage(SharedImage* sharedImage); ~NzImage(); @@ -105,7 +104,6 @@ class NAZARA_API NzImage : public NzAbstractImage, public NzResource bool Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0); NzImage& operator=(const NzImage& image); - NzImage& operator=(NzImage&& image) noexcept; static void Copy(nzUInt8* destination, const nzUInt8* source, nzUInt8 bpp, unsigned int width, unsigned int height, unsigned int depth = 1, unsigned int dstWidth = 0, unsigned int dstHeight = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0); static nzUInt8 GetMaxLevel(unsigned int width, unsigned int height, unsigned int depth = 1); diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index e674f8e96..8a6ca4357 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -34,11 +34,6 @@ NzResource() Copy(material); } -NzMaterial::NzMaterial(NzMaterial&& material) -{ - Move(material); -} - NzMaterial::~NzMaterial() { NotifyDestroy(); @@ -613,13 +608,6 @@ NzMaterial& NzMaterial::operator=(const NzMaterial& material) return *this; } -NzMaterial& NzMaterial::operator=(NzMaterial&& material) -{ - Move(material); - - return *this; -} - NzMaterial* NzMaterial::GetDefault() { return s_defaultMaterial; @@ -655,36 +643,6 @@ void NzMaterial::Copy(const NzMaterial& material) std::memcpy(&m_shaders[0], &material.m_shaders[0], (nzShaderFlags_Max+1)*sizeof(ShaderInstance)); } -void NzMaterial::Move(NzMaterial&& material) -{ - // Copie des états de base - m_alphaTestEnabled = material.m_alphaTestEnabled; - m_alphaThreshold = material.m_alphaThreshold; - m_ambientColor = material.m_ambientColor; - 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; - - // Vol des références de texture - m_alphaMap = std::move(material.m_alphaMap); - m_diffuseMap = std::move(material.m_diffuseMap); - m_emissiveMap = std::move(material.m_emissiveMap); - m_heightMap = std::move(material.m_heightMap); - m_normalMap = std::move(material.m_normalMap); - m_specularMap = std::move(material.m_specularMap); - - // Vol de la référence vers l'Über-Shader - m_uberShader = std::move(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)); -} - void NzMaterial::GenerateShader(nzUInt32 flags) const { NzParameterList list; diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index 80b580312..bee9c9ae8 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -60,12 +60,6 @@ NzTexture::NzTexture(const NzImage& image) LoadFromImage(image); } -NzTexture::NzTexture(NzTexture&& texture) : -m_impl(texture.m_impl) -{ - texture.m_impl = nullptr; -} - NzTexture::~NzTexture() { Destroy(); @@ -477,6 +471,19 @@ bool NzTexture::HasMipmaps() const return m_impl->levelCount > 1; } +void NzTexture::InvalidateMipmaps() +{ + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraInternalError("Texture must be valid"); + return; + } + #endif + + m_impl->mipmapsUpdated = false; +} + bool NzTexture::IsValid() const { return m_impl != nullptr; @@ -1031,16 +1038,6 @@ unsigned int NzTexture::GetOpenGLID() const return m_impl->id; } -NzTexture& NzTexture::operator=(NzTexture&& texture) -{ - Destroy(); - - m_impl = texture.m_impl; - texture.m_impl = nullptr; - - return *this; -} - unsigned int NzTexture::GetValidSize(unsigned int size) { if (NzRenderer::HasCapability(nzRendererCap_TextureNPOT)) @@ -1277,16 +1274,3 @@ bool NzTexture::CreateTexture(bool proxy) return true; } - -void NzTexture::InvalidateMipmaps() -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraInternalError("Texture must be valid"); - return; - } - #endif - - m_impl->mipmapsUpdated = false; -} diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index 4cc9297d2..b25ccdfd4 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -57,12 +57,6 @@ m_sharedImage(image.m_sharedImage) m_sharedImage->refCount++; } -NzImage::NzImage(NzImage&& image) noexcept : -m_sharedImage(image.m_sharedImage) -{ - image.m_sharedImage = &emptyImage; -} - NzImage::NzImage(SharedImage* sharedImage) : m_sharedImage(sharedImage) { @@ -1283,13 +1277,6 @@ NzImage& NzImage::operator=(const NzImage& image) return *this; } -NzImage& NzImage::operator=(NzImage&& image) noexcept -{ - std::swap(m_sharedImage, image.m_sharedImage); - - return *this; -} - void NzImage::Copy(nzUInt8* destination, const nzUInt8* source, nzUInt8 bpp, unsigned int width, unsigned int height, unsigned int depth, unsigned int dstWidth, unsigned int dstHeight, unsigned int srcWidth, unsigned int srcHeight) { if (dstWidth == 0) From 77347c8582ad3d7a63f4367730aa425ffcec1d71 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 16 Jan 2015 18:57:09 +0100 Subject: [PATCH 156/233] (Font) Added notification on atlas change Will only clear glyphes when setting differents parameters Former-commit-id: b16a289742c0f23fa5066d3c52ce35b4abc626c6 --- include/Nazara/Utility/Font.hpp | 1 + src/Nazara/Utility/Font.cpp | 31 +++++++++++++++++++++---------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index 4605fe975..30b5e385c 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -79,6 +79,7 @@ class NAZARA_API NzFont : public NzResource, NzAbstractAtlas::Listener, NzNonCop enum ModicationCode { + ModificationCode_AtlasChanged, ModificationCode_GlyphCacheCleared, ModificationCode_KerningCacheCleared, ModificationCode_SizeInfoCacheCleared diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index 495e0dc7f..e164d57c3 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -276,20 +276,28 @@ bool NzFont::OpenFromStream(NzInputStream& stream, const NzFontParams& params) void NzFont::SetAtlas(std::shared_ptr atlas) { - ClearGlyphCache(); + if (m_atlas != atlas) + { + ClearGlyphCache(); - if (m_atlas) - m_atlas->RemoveListener(this); + if (m_atlas) + m_atlas->RemoveListener(this); - m_atlas = atlas; - if (m_atlas) - m_atlas->AddListener(this); + m_atlas = atlas; + if (m_atlas) + m_atlas->AddListener(this); + + NotifyModified(ModificationCode_AtlasChanged); + } } void NzFont::SetGlyphBorder(unsigned int borderSize) { - m_glyphBorder = borderSize; - ClearGlyphCache(); + if (m_glyphBorder != borderSize) + { + m_glyphBorder = borderSize; + ClearGlyphCache(); + } } void NzFont::SetMinimumStepSize(unsigned int minimumStepSize) @@ -302,8 +310,11 @@ void NzFont::SetMinimumStepSize(unsigned int minimumStepSize) } #endif - m_minimumSizeStep = minimumStepSize; - ClearGlyphCache(); + if (m_minimumSizeStep != minimumStepSize) + { + m_minimumSizeStep = minimumStepSize; + ClearGlyphCache(); + } } nzUInt64 NzFont::ComputeKey(unsigned int characterSize, nzUInt32 style) const From 48ecb058f0b9d4e79871b55896a489404ae96c69 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 16 Jan 2015 23:34:56 +0100 Subject: [PATCH 157/233] (Font) Added notification on atlas layer change Fixed irrelevant error message when a font destroy an atlas Former-commit-id: ddbd04e9172f2d35a8e0cf8a37fe48724aeb5c64 --- include/Nazara/Utility/Font.hpp | 2 ++ src/Nazara/Utility/Font.cpp | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index 30b5e385c..80b175f5f 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -80,6 +80,7 @@ class NAZARA_API NzFont : public NzResource, NzAbstractAtlas::Listener, NzNonCop enum ModicationCode { ModificationCode_AtlasChanged, + ModificationCode_AtlasLayerChanged, ModificationCode_GlyphCacheCleared, ModificationCode_KerningCacheCleared, ModificationCode_SizeInfoCacheCleared @@ -110,6 +111,7 @@ class NAZARA_API NzFont : public NzResource, NzAbstractAtlas::Listener, NzNonCop nzUInt64 ComputeKey(unsigned int characterSize, nzUInt32 style) const; bool OnAtlasCleared(const NzAbstractAtlas* atlas, void* userdata) override; + bool OnAtlasLayerChange(const NzAbstractAtlas* atlas, NzAbstractImage* oldLayer, NzAbstractImage* newLayer, void* userdata) override; void OnAtlasReleased(const NzAbstractAtlas* atlas, void* userdata) override; const Glyph& PrecacheGlyph(GlyphMap& glyphMap, unsigned int characterSize, nzUInt32 style, char32_t character) const; diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index e164d57c3..79ce37878 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -22,6 +22,7 @@ m_minimumSizeStep(1) NzFont::~NzFont() { Destroy(); + SetAtlas(nullptr); // On libère l'atlas par la même occasion } void NzFont::ClearGlyphCache() @@ -355,6 +356,28 @@ bool NzFont::OnAtlasCleared(const NzAbstractAtlas* atlas, void* userdata) return true; } +bool NzFont::OnAtlasLayerChange(const NzAbstractAtlas* atlas, NzAbstractImage* oldLayer, NzAbstractImage* newLayer, void* userdata) +{ + NazaraUnused(atlas); + NazaraUnused(oldLayer); + NazaraUnused(newLayer); + NazaraUnused(userdata); + + #ifdef NAZARA_DEBUG + // Est-ce qu'il s'agit bien de notre atlas ? + if (m_atlas.get() != atlas) + { + NazaraInternalError("Notified by a non-listening-to resource"); + return false; // On ne veut plus être notifié par cette ressource, évidemment + } + #endif + + // Pour faciliter le travail des ressources qui nous écoutent + NotifyModified(ModificationCode_AtlasLayerChanged); + + return true; +} + void NzFont::OnAtlasReleased(const NzAbstractAtlas* atlas, void* userdata) { NazaraUnused(atlas); From 6d3228477f211b6a937ef4431252aec209d99801 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 16 Jan 2015 23:36:20 +0100 Subject: [PATCH 158/233] Added TextDrawer classes Former-commit-id: 4c5ace385f1a9b9ceebb774022bbc001b69a3bb4 --- include/Nazara/Utility/AbstractTextDrawer.hpp | 42 +++ include/Nazara/Utility/SimpleTextDrawer.hpp | 59 ++++ src/Nazara/Utility/AbstractTextDrawer.cpp | 9 + src/Nazara/Utility/SimpleTextDrawer.cpp | 305 ++++++++++++++++++ 4 files changed, 415 insertions(+) create mode 100644 include/Nazara/Utility/AbstractTextDrawer.hpp create mode 100644 include/Nazara/Utility/SimpleTextDrawer.hpp create mode 100644 src/Nazara/Utility/AbstractTextDrawer.cpp create mode 100644 src/Nazara/Utility/SimpleTextDrawer.cpp diff --git a/include/Nazara/Utility/AbstractTextDrawer.hpp b/include/Nazara/Utility/AbstractTextDrawer.hpp new file mode 100644 index 000000000..76df09a00 --- /dev/null +++ b/include/Nazara/Utility/AbstractTextDrawer.hpp @@ -0,0 +1,42 @@ +// 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_ABSTRACTTEXTDRAWER_HPP +#define NAZARA_ABSTRACTTEXTDRAWER_HPP + +#include +#include +#include +#include + +class NzAbstractImage; +class NzFont; + +class NAZARA_API NzAbstractTextDrawer +{ + public: + struct Glyph; + + NzAbstractTextDrawer() = default; + virtual ~NzAbstractTextDrawer(); + + virtual const NzRectui& GetBounds() const = 0; + virtual NzFont* GetFont(unsigned int index) const = 0; + virtual unsigned int GetFontCount() const = 0; + virtual const Glyph& GetGlyph(unsigned int index) const = 0; + virtual unsigned int GetGlyphCount() const = 0; + + struct Glyph + { + NzColor color; + NzRectui atlasRect; + NzVector2f corners[4]; + NzAbstractImage* atlas; + bool flipped; + }; +}; + +#endif // NAZARA_ABSTRACTTEXTDRAWER_HPP diff --git a/include/Nazara/Utility/SimpleTextDrawer.hpp b/include/Nazara/Utility/SimpleTextDrawer.hpp new file mode 100644 index 000000000..ca4b11845 --- /dev/null +++ b/include/Nazara/Utility/SimpleTextDrawer.hpp @@ -0,0 +1,59 @@ +// 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_SIMPLETEXTDRAWER_HPP +#define NAZARA_SIMPLETEXTDRAWER_HPP + +#include +#include +#include +#include +#include +#include +#include + +class NAZARA_API NzSimpleTextDrawer : public NzAbstractTextDrawer, NzResourceListener +{ + public: + NzSimpleTextDrawer(); + virtual ~NzSimpleTextDrawer(); + + const NzRectui& GetBounds() const; + unsigned int GetCharacterSize() const; + const NzColor& GetColor() const; + NzFont* GetFont() const; + nzUInt32 GetStyle() const; + + void SetCharacterSize(unsigned int characterSize); + void SetColor(const NzColor& color); + void SetFont(NzFont* font); + void SetStyle(nzUInt32 style); + void SetText(const NzString& str); + + static NzSimpleTextDrawer Draw(unsigned int characterSize, const NzString& str, nzUInt32 style = nzTextStyle_Regular, const NzColor& color = NzColor::White); + static NzSimpleTextDrawer Draw(NzFont* font, unsigned int characterSize, const NzString& str, nzUInt32 style = nzTextStyle_Regular, const NzColor& color = NzColor::White); + + private: + NzFont* GetFont(unsigned int index) const override; + unsigned int GetFontCount() const override; + const Glyph& GetGlyph(unsigned int index) const override; + unsigned int GetGlyphCount() const override; + + bool OnResourceModified(const NzResource* resource, int index, unsigned int code) override; + void OnResourceReleased(const NzResource* resource, int index) override; + void UpdateGlyphs() const; + + mutable std::vector m_glyphs; + NzColor m_color; + NzFontRef m_font; + mutable NzRectui m_bounds; + NzString m_text; + nzUInt32 m_style; + mutable bool m_glyphUpdated; + unsigned int m_characterSize; +}; + +#endif // NAZARA_SIMPLETEXTDRAWER_HPP diff --git a/src/Nazara/Utility/AbstractTextDrawer.cpp b/src/Nazara/Utility/AbstractTextDrawer.cpp new file mode 100644 index 000000000..289836751 --- /dev/null +++ b/src/Nazara/Utility/AbstractTextDrawer.cpp @@ -0,0 +1,9 @@ +// 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 + +#include +#include + +NzAbstractTextDrawer::~NzAbstractTextDrawer() = default; + diff --git a/src/Nazara/Utility/SimpleTextDrawer.cpp b/src/Nazara/Utility/SimpleTextDrawer.cpp new file mode 100644 index 000000000..e16161d69 --- /dev/null +++ b/src/Nazara/Utility/SimpleTextDrawer.cpp @@ -0,0 +1,305 @@ +// 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 + +#include +#include +#include + +///TODO: Listener de font (cas où l'atlas a changé) + +NzSimpleTextDrawer::NzSimpleTextDrawer() : +m_color(NzColor::White), +m_style(nzTextStyle_Regular) +{ + // SetFont(NzFont::GetDefault()); +} + +NzSimpleTextDrawer::~NzSimpleTextDrawer() +{ + if (m_font) + m_font->RemoveResourceListener(this); +} + +const NzRectui& NzSimpleTextDrawer::GetBounds() const +{ + if (!m_glyphUpdated) + UpdateGlyphs(); + + return m_bounds; +} + +unsigned int NzSimpleTextDrawer::GetCharacterSize() const +{ + return m_characterSize; +} + +const NzColor& NzSimpleTextDrawer::GetColor() const +{ + return m_color; +} + +NzFont* NzSimpleTextDrawer::GetFont() const +{ + return m_font; +} + +nzUInt32 NzSimpleTextDrawer::GetStyle() const +{ + return m_style; +} + +void NzSimpleTextDrawer::SetCharacterSize(unsigned int characterSize) +{ + m_characterSize = characterSize; + + m_glyphUpdated = false; +} + +void NzSimpleTextDrawer::SetColor(const NzColor& color) +{ + m_color = color; + + m_glyphUpdated = false; +} + +void NzSimpleTextDrawer::SetFont(NzFont* font) +{ + if (m_font) + m_font->RemoveResourceListener(this); + + m_font = font; + if (m_font) + m_font->AddResourceListener(this); + + m_glyphUpdated = false; +} + +void NzSimpleTextDrawer::SetStyle(nzUInt32 style) +{ + m_style = style; + + m_glyphUpdated = false; +} + +void NzSimpleTextDrawer::SetText(const NzString& str) +{ + m_text = str; + + m_glyphUpdated = false; +} + +NzSimpleTextDrawer NzSimpleTextDrawer::Draw(unsigned int characterSize, const NzString& str, nzUInt32 style, const NzColor& color) +{ + ///FIXME: Sans default font ça n'a aucun intérêt + NzSimpleTextDrawer drawer; + drawer.SetCharacterSize(characterSize); + drawer.SetColor(color); + drawer.SetStyle(style); + drawer.SetText(str); + + return drawer; +} + +NzSimpleTextDrawer NzSimpleTextDrawer::Draw(NzFont* font, unsigned int characterSize, const NzString& str, nzUInt32 style, const NzColor& color) +{ + NzSimpleTextDrawer drawer; + drawer.SetCharacterSize(characterSize); + drawer.SetColor(color); + drawer.SetFont(font); + drawer.SetStyle(style); + drawer.SetText(str); + + return drawer; +} + +NzFont* NzSimpleTextDrawer::GetFont(unsigned int index) const +{ + #if NAZARA_UTILITY_SAFE + if (index > 0) + { + NazaraError("Font index out of range (" + NzString::Number(index) + " >= 1)"); + return nullptr; + } + #endif + + return m_font; +} + +unsigned int NzSimpleTextDrawer::GetFontCount() const +{ + return 1; +} + +const NzAbstractTextDrawer::Glyph& NzSimpleTextDrawer::GetGlyph(unsigned int index) const +{ + if (!m_glyphUpdated) + UpdateGlyphs(); + + return m_glyphs[index]; +} + +unsigned int NzSimpleTextDrawer::GetGlyphCount() const +{ + if (!m_glyphUpdated) + UpdateGlyphs(); + + return m_glyphs.size(); +} + +bool NzSimpleTextDrawer::OnResourceModified(const NzResource* resource, int index, unsigned int code) +{ + NazaraUnused(resource); + NazaraUnused(index); + + #ifdef NAZARA_DEBUG + if (m_font != resource) + { + NazaraInternalError("Not listening to " + NzString::Pointer(resource)); + return false; + } + #endif + + if (code == NzFont::ModificationCode_AtlasChanged || + code == NzFont::ModificationCode_AtlasLayerChanged || + code == NzFont::ModificationCode_GlyphCacheCleared) + { + m_glyphUpdated = false; + } + + return true; +} + +void NzSimpleTextDrawer::OnResourceReleased(const NzResource* resource, int index) +{ + NazaraUnused(resource); + NazaraUnused(index); + + #ifdef NAZARA_DEBUG + if (m_font != resource) + { + NazaraInternalError("Not listening to " + NzString::Pointer(resource)); + return; + } + #endif + + SetFont(nullptr); +} + +void NzSimpleTextDrawer::UpdateGlyphs() const +{ + m_bounds.MakeZero(); + m_glyphs.clear(); + m_glyphUpdated = true; + + #if NAZARA_UTILITY_SAFE + if (!m_font || !m_font->IsValid()) + { + NazaraError("Invalid font"); + return; + } + #endif + + if (m_text.IsEmpty()) + return; + + ///TODO: Itération UTF-8 => UTF-32 sans allocation de buffer (Exposer utf8cpp ?) + unsigned int size; + std::unique_ptr characters(m_text.GetUtf32Buffer(&size)); + if (!characters) + { + NazaraError("Invalid character set"); + return; + } + + const NzFont::SizeInfo& sizeInfo = m_font->GetSizeInfo(m_characterSize); + + // "Curseur" de dessin + NzVector2ui drawPos(0, m_characterSize); + NzVector2ui lastPos(0, 0); + + m_glyphs.reserve(size); + nzUInt32 previousCharacter = 0; + for (unsigned int i = 0; i < size; ++i) + { + char32_t character = characters[i]; + + if (previousCharacter != 0) + drawPos.x += m_font->GetKerning(m_characterSize, previousCharacter, character); + + previousCharacter = character; + + bool whitespace = true; + switch (character) + { + case ' ': + drawPos.x += sizeInfo.spaceAdvance; + break; + + case '\n': + drawPos.x = 0; + drawPos.y += sizeInfo.lineHeight; + break; + + case '\t': + drawPos.x += sizeInfo.spaceAdvance*4; + break; + + default: + whitespace = false; + break; + } + + if (whitespace) + continue; // Inutile d'avoir un glyphe pour un espace blanc + + const NzFont::Glyph& fontGlyph = m_font->GetGlyph(m_characterSize, m_style, character); + if (!fontGlyph.valid) + continue; // Le glyphe n'a pas été correctement chargé, que pouvons-nous faire d'autre que le passer + + Glyph glyph; + glyph.atlas = m_font->GetAtlas()->GetLayer(fontGlyph.layerIndex); + glyph.atlasRect = fontGlyph.atlasRect; + glyph.color = m_color; + glyph.flipped = fontGlyph.flipped; + + float advance = fontGlyph.advance; + + NzRectf bounds(fontGlyph.aabb); + bounds.x += drawPos.x; + bounds.y += drawPos.y; + + if (fontGlyph.requireFauxBold) + { + // On va agrandir le glyphe pour simuler le gras (idée moisie, mais idée quand même) + NzVector2f center = bounds.GetCenter(); + + bounds.width *= 1.1f; + bounds.height *= 1.1f; + + // On le replace à la bonne hauteur + NzVector2f offset(bounds.GetCenter() - center); + bounds.y -= offset.y; + + // On ajuste l'espacement + advance *= 1.1f; + } + + // On "penche" le glyphe pour obtenir un semblant d'italique + float italic = (fontGlyph.requireFauxItalic) ? 0.208f : 0.f; + float italicTop = italic * bounds.y; + float italicBottom = italic * bounds.GetMaximum().y; + + glyph.corners[0].Set(bounds.x - italicTop, bounds.y); + glyph.corners[1].Set(bounds.x + bounds.width - italicTop, bounds.y); + glyph.corners[2].Set(bounds.x - italicBottom, bounds.y + bounds.height); + glyph.corners[3].Set(bounds.x + bounds.width - italicBottom, bounds.y + bounds.height); + + m_glyphs.push_back(glyph); + + lastPos = drawPos; + drawPos.x += advance; + } + + m_bounds.ExtendTo(lastPos); +} From fdb722ef14bcc2031c868ad7f0b60b9dec9cac41 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 00:15:01 +0100 Subject: [PATCH 159/233] Made SceneNodes non-movable Fixed SceneNodes copy constructor not parenting the right object Former-commit-id: 21a08e3bb0931af426d97399dab86dda9acdf172 --- include/Nazara/Graphics/Model.hpp | 2 -- include/Nazara/Graphics/SceneNode.hpp | 3 ++- include/Nazara/Graphics/Sprite.hpp | 5 +++-- src/Nazara/Graphics/Light.cpp | 2 +- src/Nazara/Graphics/Model.cpp | 28 ++--------------------- src/Nazara/Graphics/SceneNode.cpp | 11 --------- src/Nazara/Graphics/Sprite.cpp | 32 ++++++++++++++------------- 7 files changed, 25 insertions(+), 58 deletions(-) diff --git a/include/Nazara/Graphics/Model.hpp b/include/Nazara/Graphics/Model.hpp index ea5b937ba..3249cdd48 100644 --- a/include/Nazara/Graphics/Model.hpp +++ b/include/Nazara/Graphics/Model.hpp @@ -36,7 +36,6 @@ class NAZARA_API NzModel : public NzSceneNode public: NzModel(); NzModel(const NzModel& model); - NzModel(NzModel&& model); virtual ~NzModel(); void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; @@ -83,7 +82,6 @@ class NAZARA_API NzModel : public NzSceneNode void SetSkinCount(unsigned int skinCount); NzModel& operator=(const NzModel& node); - NzModel& operator=(NzModel&& node); protected: void InvalidateNode() override; diff --git a/include/Nazara/Graphics/SceneNode.hpp b/include/Nazara/Graphics/SceneNode.hpp index e5d70d10c..edfdf56e2 100644 --- a/include/Nazara/Graphics/SceneNode.hpp +++ b/include/Nazara/Graphics/SceneNode.hpp @@ -21,6 +21,7 @@ class NAZARA_API NzSceneNode : public NzNode public: NzSceneNode(); NzSceneNode(const NzSceneNode& sceneNode); + NzSceneNode(NzSceneNode& sceneNode) = delete; virtual ~NzSceneNode(); virtual void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const = 0; @@ -43,7 +44,7 @@ class NAZARA_API NzSceneNode : public NzNode bool IsVisible() const; NzSceneNode& operator=(const NzSceneNode& sceneNode); - NzSceneNode& operator=(NzSceneNode&& sceneNode); + NzSceneNode& operator=(NzSceneNode&& sceneNode) = delete; protected: virtual bool FrustumCull(const NzFrustumf& frustum) const; diff --git a/include/Nazara/Graphics/Sprite.hpp b/include/Nazara/Graphics/Sprite.hpp index a6040823c..ed4b99f20 100644 --- a/include/Nazara/Graphics/Sprite.hpp +++ b/include/Nazara/Graphics/Sprite.hpp @@ -18,8 +18,7 @@ class NAZARA_API NzSprite : public NzSceneNode NzSprite(); NzSprite(NzTexture* texture); NzSprite(const NzSprite& sprite); - NzSprite(NzSprite&& sprite); - ~NzSprite(); + ~NzSprite() = default; void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; @@ -40,6 +39,8 @@ class NAZARA_API NzSprite : public NzSceneNode void SetTextureCoords(const NzRectf& coords); void SetTextureRect(const NzRectui& rect); + NzSprite& operator=(const NzSprite& sprite); + private: void InvalidateNode() override; void Register() override; diff --git a/src/Nazara/Graphics/Light.cpp b/src/Nazara/Graphics/Light.cpp index ff3d5bfdd..e3288adc2 100644 --- a/src/Nazara/Graphics/Light.cpp +++ b/src/Nazara/Graphics/Light.cpp @@ -41,7 +41,7 @@ m_innerAngle(light.m_innerAngle), m_outerAngle(light.m_outerAngle), m_radius(light.m_radius) { - SetParent(light); + SetParent(light.GetParent()); } void NzLight::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const diff --git a/src/Nazara/Graphics/Model.cpp b/src/Nazara/Graphics/Model.cpp index 54e9b964f..64e68a709 100644 --- a/src/Nazara/Graphics/Model.cpp +++ b/src/Nazara/Graphics/Model.cpp @@ -35,20 +35,14 @@ m_skinCount(1) NzModel::NzModel(const NzModel& model) : NzSceneNode(model), m_materials(model.m_materials), +m_mesh(model.m_mesh), m_boundingVolume(model.m_boundingVolume), m_boundingVolumeUpdated(model.m_boundingVolumeUpdated), m_matCount(model.m_matCount), m_skin(model.m_skin), m_skinCount(model.m_skinCount) { - if (model.m_mesh) - { - // Nous n'avons des matériaux que si nous avons un mesh - m_mesh = model.m_mesh; - m_materials = model.m_materials; - } - - SetParent(model); + SetParent(model.GetParent()); } NzModel::~NzModel() @@ -420,24 +414,6 @@ NzModel& NzModel::operator=(const NzModel& node) return *this; } -NzModel& NzModel::operator=(NzModel&& node) -{ - NzSceneNode::operator=(node); - - // Ressources - m_mesh = std::move(node.m_mesh); - m_materials = std::move(node.m_materials); - - // Paramètres - m_boundingVolume = node.m_boundingVolume; - m_boundingVolumeUpdated = node.m_boundingVolumeUpdated; - m_matCount = node.m_matCount; - m_skin = node.m_skin; - m_skinCount = node.m_skinCount; - - return *this; -} - void NzModel::InvalidateNode() { NzSceneNode::InvalidateNode(); diff --git a/src/Nazara/Graphics/SceneNode.cpp b/src/Nazara/Graphics/SceneNode.cpp index fcaf02743..d5ae7da72 100644 --- a/src/Nazara/Graphics/SceneNode.cpp +++ b/src/Nazara/Graphics/SceneNode.cpp @@ -140,17 +140,6 @@ NzSceneNode& NzSceneNode::operator=(const NzSceneNode& sceneNode) return *this; } -NzSceneNode& NzSceneNode::operator=(NzSceneNode&& sceneNode) -{ - NzNode::operator=(sceneNode); - - // La scène est affectée via le parenting du node - m_drawingEnabled = sceneNode.m_drawingEnabled; - m_visible = sceneNode.m_visible; - - return *this; -} - bool NzSceneNode::FrustumCull(const NzFrustumf& frustum) const { return frustum.Contains(GetBoundingVolume()); diff --git a/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index 3d7a6d48e..24778dbd6 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -53,23 +53,9 @@ m_vertices(sprite.m_vertices), m_boundingVolumeUpdated(sprite.m_boundingVolumeUpdated), m_verticesUpdated(sprite.m_verticesUpdated) { - SetParent(sprite); + SetParent(sprite.GetParent()); } -NzSprite::NzSprite(NzSprite&& sprite) : -NzSceneNode(sprite), -m_boundingVolume(sprite.m_boundingVolume), -m_material(std::move(sprite.m_material)), -m_textureCoords(sprite.m_textureCoords), -m_size(sprite.m_size), -m_vertices(sprite.m_vertices), -m_boundingVolumeUpdated(sprite.m_boundingVolumeUpdated), -m_verticesUpdated(sprite.m_verticesUpdated) -{ -} - -NzSprite::~NzSprite() = default; - void NzSprite::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const { if (!m_verticesUpdated) @@ -189,6 +175,22 @@ void NzSprite::SetTextureRect(const NzRectui& rect) SetTextureCoords(NzRectf(invWidth*rect.x, invHeight*rect.y, invWidth*rect.width, invHeight*rect.height)); } +NzSprite& NzSprite::operator=(const NzSprite& sprite) +{ + NzSceneNode::operator=(sprite); + + m_color = sprite.m_color; + m_material = sprite.m_material; + m_textureCoords = sprite.m_textureCoords; + m_size = sprite.m_size; + + // On ne copie pas les sommets finaux car il est très probable que nos paramètres soient modifiés et qu'ils doivent être régénérés de toute façon + m_boundingVolumeUpdated = false; + m_verticesUpdated = false; + + return *this; +} + void NzSprite::InvalidateNode() { NzSceneNode::InvalidateNode(); From a0054def7bf1195f4e2dd7ca1eae79c1eb9069a0 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 00:16:52 +0100 Subject: [PATCH 160/233] Added TextSprites Former-commit-id: 85bef5ec14336710b2fdc782d3d0d77787ab65dd --- include/Nazara/Graphics/Enums.hpp | 9 +- include/Nazara/Graphics/TextSprite.hpp | 75 +++++ src/Nazara/Graphics/TextSprite.cpp | 407 +++++++++++++++++++++++++ 3 files changed, 487 insertions(+), 4 deletions(-) create mode 100644 include/Nazara/Graphics/TextSprite.hpp create mode 100644 src/Nazara/Graphics/TextSprite.cpp diff --git a/include/Nazara/Graphics/Enums.hpp b/include/Nazara/Graphics/Enums.hpp index 4f4cb1472..257928a66 100644 --- a/include/Nazara/Graphics/Enums.hpp +++ b/include/Nazara/Graphics/Enums.hpp @@ -71,10 +71,11 @@ enum nzRenderTechniqueType enum nzSceneNodeType { - nzSceneNodeType_Light, // NzLight - nzSceneNodeType_Model, // NzModel - nzSceneNodeType_Root, // NzSceneRoot - nzSceneNodeType_Sprite, // NzSprite + nzSceneNodeType_Light, // NzLight + nzSceneNodeType_Model, // NzModel + nzSceneNodeType_Root, // NzSceneRoot + nzSceneNodeType_Sprite, // NzSprite + nzSceneNodeType_TextSprite, // NzTextSprite nzSceneNodeType_User, nzSceneNodeType_Max = nzSceneNodeType_User diff --git a/include/Nazara/Graphics/TextSprite.hpp b/include/Nazara/Graphics/TextSprite.hpp new file mode 100644 index 000000000..be8df8b69 --- /dev/null +++ b/include/Nazara/Graphics/TextSprite.hpp @@ -0,0 +1,75 @@ +// Copyright (C) 2014 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_TEXTSPRITE_HPP +#define NAZARA_TEXTSPRITE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class NAZARA_API NzTextSprite : public NzSceneNode, NzAbstractAtlas::Listener +{ + public: + NzTextSprite(); + NzTextSprite(const NzTextSprite& sprite); + ~NzTextSprite(); + + void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; + + void Clear(); + + const NzBoundingVolumef& GetBoundingVolume() const override; + const NzColor& GetColor() const; + NzMaterial* GetMaterial() const; + nzSceneNodeType GetSceneNodeType() const override; + + void InvalidateVertices(); + bool IsDrawable() const; + + void SetColor(const NzColor& color); + void SetDefaultMaterial(); + void SetMaterial(NzMaterial* material); + void SetText(const NzAbstractTextDrawer& drawer); + + NzTextSprite& operator=(const NzTextSprite& text); + + private: + void ClearAtlases(); + void InvalidateNode() override; + bool OnAtlasCleared(const NzAbstractAtlas* atlas, void* userdata) override; + bool OnAtlasLayerChange(const NzAbstractAtlas* atlas, NzAbstractImage* oldLayer, NzAbstractImage* newLayer, void* userdata) override; + void OnAtlasReleased(const NzAbstractAtlas* atlas, void* userdata) override; + void Register() override; + void Unregister() override; + void UpdateBoundingVolume() const; + void UpdateVertices() const; + + struct RenderIndices + { + unsigned int first; + unsigned int count; + }; + + std::set m_atlases; + mutable std::unordered_map m_renderInfos; + mutable std::vector m_localVertices; + mutable std::vector m_vertices; + mutable NzBoundingVolumef m_boundingVolume; + NzColor m_color; + NzMaterialRef m_material; + NzRectui m_localBounds; + mutable bool m_boundingVolumeUpdated; + mutable bool m_verticesUpdated; +}; + +#endif // NAZARA_TEXTSPRITE_HPP diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp new file mode 100644 index 000000000..ab028ec91 --- /dev/null +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -0,0 +1,407 @@ +// Copyright (C) 2014 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 + +///TODO: Gérer allocation nouvel atlas + +NzTextSprite::NzTextSprite() : +m_boundingVolume(NzBoundingVolumef::Null()), +m_color(NzColor::White), +m_verticesUpdated(false) +{ + SetDefaultMaterial(); +} + +NzTextSprite::NzTextSprite(const NzTextSprite& sprite) : +NzSceneNode(sprite), +m_atlases(sprite.m_atlases), +m_renderInfos(sprite.m_renderInfos), +m_localVertices(sprite.m_localVertices), +m_vertices(sprite.m_vertices), +m_boundingVolume(sprite.m_boundingVolume), +m_color(sprite.m_color), +m_material(sprite.m_material), +m_localBounds(sprite.m_localBounds), +m_boundingVolumeUpdated(sprite.m_boundingVolumeUpdated), +m_verticesUpdated(sprite.m_verticesUpdated) +{ + SetParent(sprite.GetParent()); + + for (const NzAbstractAtlas* atlas : m_atlases) + atlas->AddListener(this); +} + +NzTextSprite::~NzTextSprite() +{ + ClearAtlases(); +} + +void NzTextSprite::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const +{ + if (!m_verticesUpdated) + UpdateVertices(); + + for (auto& pair : m_renderInfos) + { + NzTexture* overlay = pair.first; + RenderIndices& indices = pair.second; + + if (indices.count > 0) + renderQueue->AddSprites(m_material, &m_vertices[indices.first*4], indices.count, overlay); + } +} + +void NzTextSprite::Clear() +{ + ClearAtlases(); + m_boundingVolume.MakeNull(); + m_localVertices.clear(); + m_renderInfos.clear(); + m_vertices.clear(); +} + +const NzBoundingVolumef& NzTextSprite::GetBoundingVolume() const +{ + if (!m_boundingVolumeUpdated) + UpdateBoundingVolume(); + + return m_boundingVolume; +} + +const NzColor& NzTextSprite::GetColor() const +{ + return m_color; +} + +NzMaterial* NzTextSprite::GetMaterial() const +{ + return m_material; +} + +nzSceneNodeType NzTextSprite::GetSceneNodeType() const +{ + return nzSceneNodeType_TextSprite; +} + +void NzTextSprite::InvalidateVertices() +{ + m_verticesUpdated = false; +} + +bool NzTextSprite::IsDrawable() const +{ + return m_material != nullptr; +} + +void NzTextSprite::SetColor(const NzColor& color) +{ + m_color = color; + m_verticesUpdated = false; +} + +void NzTextSprite::SetDefaultMaterial() +{ + std::unique_ptr material(new NzMaterial); + material->Enable(nzRendererParameter_Blend, true); + material->Enable(nzRendererParameter_DepthWrite, false); + material->Enable(nzRendererParameter_FaceCulling, false); + material->EnableLighting(false); + material->SetDstBlend(nzBlendFunc_InvSrcAlpha); + material->SetSrcBlend(nzBlendFunc_SrcAlpha); + + SetMaterial(material.get()); + + material->SetPersistent(false); + material.release(); +} + +void NzTextSprite::SetMaterial(NzMaterial* material) +{ + m_material = material; +} + +void NzTextSprite::SetText(const NzAbstractTextDrawer& drawer) +{ + ClearAtlases(); + + unsigned int fontCount = drawer.GetFontCount(); + for (unsigned int i = 0; i < fontCount; ++i) + { + const NzAbstractAtlas* atlas = drawer.GetFont(i)->GetAtlas(); + if (m_atlases.insert(atlas).second) + atlas->AddListener(this); + } + + unsigned int glyphCount = drawer.GetGlyphCount(); + m_localVertices.resize(glyphCount * 4); + m_vertices.resize(glyphCount * 4); + + NzTexture* lastTexture = nullptr; + unsigned int* count = nullptr; + for (unsigned int i = 0; i < glyphCount; ++i) + { + const NzAbstractTextDrawer::Glyph& glyph = drawer.GetGlyph(i); + + NzTexture* texture = static_cast(glyph.atlas); + if (lastTexture != texture) + { + auto pair = m_renderInfos.insert(std::make_pair(texture, RenderIndices{0U, 0U})); + + count = &pair.first->second.count; + lastTexture = texture; + } + + (*count)++; + } + + // Attribution des indices + unsigned int index = 0; + for (auto& pair : m_renderInfos) + { + RenderIndices& indices = pair.second; + + indices.first = index; + + index += indices.count; + indices.count = 0; // On réinitialise count à zéro (on va s'en servir pour compteur dans la boucle suivante) + } + + NzSparsePtr texCoordPtr(&m_vertices[0].uv, sizeof(NzVertexStruct_XYZ_Color_UV)); + + lastTexture = nullptr; + RenderIndices* indices = nullptr; + for (unsigned int i = 0; i < glyphCount; ++i) + { + const NzAbstractTextDrawer::Glyph& glyph = drawer.GetGlyph(i); + + NzTexture* texture = static_cast(glyph.atlas); + if (lastTexture != texture) + { + indices = &m_renderInfos[texture]; // On a changé de texture, on ajuste le pointeur + lastTexture = texture; + } + + // Affectation des positions et couleurs (locaux) + for (unsigned int j = 0; j < 4; ++j) + { + m_localVertices[i*4 + j].color = glyph.color; + m_localVertices[i*4 + j].position.Set(glyph.corners[j]); + } + + // Calcul des coordonnées de texture (globaux) + + // On commence par transformer les coordonnées entières en flottantes: + NzVector2ui size(texture->GetSize()); + float invWidth = 1.f/size.x; + float invHeight = 1.f/size.y; + + NzRectf uvRect(glyph.atlasRect); + uvRect.x *= invWidth; + uvRect.y *= invHeight; + uvRect.width *= invWidth; + uvRect.height *= invHeight; + + // Extraction des quatre coins et attribution + NzSparsePtr texCoord = texCoordPtr + indices->first*4 + indices->count*4; + if (!glyph.flipped) + { + // Le glyphe n'est pas retourné, l'ordre des UV suit celui des sommets + *texCoord++ = uvRect.GetCorner(nzRectCorner_LeftTop); + *texCoord++ = uvRect.GetCorner(nzRectCorner_RightTop); + *texCoord++ = uvRect.GetCorner(nzRectCorner_LeftBottom); + *texCoord++ = uvRect.GetCorner(nzRectCorner_RightBottom); + } + else + { + // Le glyphe a subit une rotation de 90° (sens antihoraire), on adapte les UV en conséquence + *texCoord++ = uvRect.GetCorner(nzRectCorner_LeftBottom); + *texCoord++ = uvRect.GetCorner(nzRectCorner_LeftTop); + *texCoord++ = uvRect.GetCorner(nzRectCorner_RightBottom); + *texCoord++ = uvRect.GetCorner(nzRectCorner_RightTop); + } + + // Et on passe au prochain + indices->count++; + } + + m_localBounds = drawer.GetBounds(); + m_boundingVolume.MakeNull(); + m_boundingVolumeUpdated = false; + m_verticesUpdated = false; +} + +NzTextSprite& NzTextSprite::operator=(const NzTextSprite& text) +{ + NzSceneNode::operator=(text); + + m_atlases = text.m_atlases; + m_color = text.m_color; + m_material = text.m_material; + m_renderInfos = text.m_renderInfos; + m_localBounds = text.m_localBounds; + m_localVertices = text.m_localVertices; + + // On ne copie pas les sommets finaux car il est très probable que nos paramètres soient modifiés et qu'ils doivent être régénérés de toute façon + m_boundingVolumeUpdated = false; + m_verticesUpdated = false; + + return *this; +} + +void NzTextSprite::ClearAtlases() +{ + for (const NzAbstractAtlas* atlas : m_atlases) + atlas->RemoveListener(this); + + m_atlases.clear(); +} + +void NzTextSprite::InvalidateNode() +{ + NzSceneNode::InvalidateNode(); + + m_boundingVolumeUpdated = false; + m_verticesUpdated = false; +} + +bool NzTextSprite::OnAtlasCleared(const NzAbstractAtlas* atlas, void* userdata) +{ + NazaraUnused(userdata); + + #ifdef NAZARA_DEBUG + if (m_atlases.find(atlas) == m_atlases.end()) + { + NazaraInternalError("Not listening to " + NzString::Pointer(atlas)); + return false; + } + #endif + + NazaraWarning("TextSprite " + NzString::Pointer(this) + " has been cleared because atlas " + NzString::Pointer(atlas) + " that was under use has been cleared"); + Clear(); + + return false; +} + +bool NzTextSprite::OnAtlasLayerChange(const NzAbstractAtlas* atlas, NzAbstractImage* oldLayer, NzAbstractImage* newLayer, void* userdata) +{ + NazaraUnused(atlas); + NazaraUnused(userdata); + + #ifdef NAZARA_DEBUG + if (m_atlases.find(atlas) == m_atlases.end()) + { + NazaraInternalError("Not listening to " + NzString::Pointer(atlas)); + return false; + } + #endif + + NzTexture* oldTexture = static_cast(oldLayer); + NzTexture* newTexture = static_cast(newLayer); + + auto it = m_renderInfos.find(oldTexture); + if (it != m_renderInfos.end()) + { + // Nous utilisons bien cette texture, nous devons mettre à jour les coordonnées de texture + RenderIndices indices = std::move(it->second); + + NzVector2ui oldSize(oldTexture->GetSize()); + NzVector2ui newSize(newTexture->GetSize()); + NzVector2f scale = NzVector2f(oldSize)/NzVector2f(newSize); + + NzSparsePtr texCoordPtr(&m_vertices[indices.first].uv, sizeof(NzVertexStruct_XYZ_Color_UV)); + for (unsigned int i = 0; i < indices.count; ++i) + { + for (unsigned int j = 0; j < 4; ++j) + texCoordPtr[i*4 + j] *= scale; + } + + // Nous enlevons l'ancienne texture et rajoutons la nouvelle à sa place (pour les mêmes indices) + m_renderInfos.erase(it); + m_renderInfos.insert(std::make_pair(newTexture, std::move(indices))); + } + + return true; +} + +void NzTextSprite::OnAtlasReleased(const NzAbstractAtlas* atlas, void* userdata) +{ + NazaraUnused(userdata); + + #ifdef NAZARA_DEBUG + if (m_atlases.find(atlas) == m_atlases.end()) + { + NazaraInternalError("Not listening to " + NzString::Pointer(atlas)); + return; + } + #endif + + NazaraWarning("TextSprite " + NzString::Pointer(this) + " has been cleared because atlas " + NzString::Pointer(atlas) + " that was under use has been released"); + Clear(); +} + +void NzTextSprite::Register() +{ + // Le changement de scène peut affecter les sommets + m_verticesUpdated = false; +} + +void NzTextSprite::Unregister() +{ +} + +void NzTextSprite::UpdateBoundingVolume() const +{ + if (m_boundingVolume.IsNull()) + { + NzVector3f down = m_scene->GetDown(); + NzVector3f right = m_scene->GetRight(); + + m_boundingVolume.Set(NzVector3f(0.f), static_cast(m_localBounds.width)*right + static_cast(m_localBounds.height)*down); + } + + if (!m_transformMatrixUpdated) + UpdateTransformMatrix(); + + m_boundingVolume.Update(m_transformMatrix); + m_boundingVolumeUpdated = true; +} + +void NzTextSprite::UpdateVertices() const +{ + if (!m_transformMatrixUpdated) + UpdateTransformMatrix(); + + NzVector3f down = m_scene->GetDown(); + NzVector3f right = m_scene->GetRight(); + + NzSparsePtr colorPtr(&m_vertices[0].color, sizeof(NzVertexStruct_XYZ_Color_UV)); + NzSparsePtr posPtr(&m_vertices[0].position, sizeof(NzVertexStruct_XYZ_Color_UV)); + + for (auto& pair : m_renderInfos) + { + RenderIndices& indices = pair.second; + + NzSparsePtr color = colorPtr + indices.first*4; + NzSparsePtr pos = posPtr + indices.first*4; + NzVertexStruct_XY_Color* localVertex = &m_localVertices[indices.first*4]; + for (unsigned int i = 0; i < indices.count; ++i) + { + for (unsigned int j = 0; j < 4; ++j) + { + *pos++ = m_transformMatrix.Transform(localVertex->position.x*right + localVertex->position.y*down); + *color++ = m_color * localVertex->color; + + localVertex++; + } + } + } + + m_verticesUpdated = true; +} From 71c1d5f527f3c4b2efb2c16a7d462c0e8d09ee95 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 00:29:26 +0100 Subject: [PATCH 161/233] Fixed reordered warning Former-commit-id: e825c3f282e1b1c3f65d32be8512210c92a3a1d9 --- src/Nazara/Graphics/Model.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Graphics/Model.cpp b/src/Nazara/Graphics/Model.cpp index 64e68a709..cf32336b8 100644 --- a/src/Nazara/Graphics/Model.cpp +++ b/src/Nazara/Graphics/Model.cpp @@ -35,8 +35,8 @@ m_skinCount(1) NzModel::NzModel(const NzModel& model) : NzSceneNode(model), m_materials(model.m_materials), -m_mesh(model.m_mesh), m_boundingVolume(model.m_boundingVolume), +m_mesh(model.m_mesh), m_boundingVolumeUpdated(model.m_boundingVolumeUpdated), m_matCount(model.m_matCount), m_skin(model.m_skin), From 3ed18e70da6c155d57575e994ac154b0e30dae3a Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 00:34:09 +0100 Subject: [PATCH 162/233] Added default material to sprites Former-commit-id: 8a68d3d9b251ff93a793d4e001aed721558a8eef --- include/Nazara/Graphics/Sprite.hpp | 1 + src/Nazara/Graphics/Sprite.cpp | 63 ++++++++++++++++-------------- 2 files changed, 34 insertions(+), 30 deletions(-) diff --git a/include/Nazara/Graphics/Sprite.hpp b/include/Nazara/Graphics/Sprite.hpp index ed4b99f20..b3739cb07 100644 --- a/include/Nazara/Graphics/Sprite.hpp +++ b/include/Nazara/Graphics/Sprite.hpp @@ -32,6 +32,7 @@ class NAZARA_API NzSprite : public NzSceneNode bool IsDrawable() const; void SetColor(const NzColor& color); + void SetDefaultMaterial(); void SetMaterial(NzMaterial* material, bool resizeSprite = true); void SetSize(const NzVector2f& size); void SetSize(float sizeX, float sizeY); diff --git a/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index 24778dbd6..542f17cd4 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -15,32 +16,18 @@ m_size(64.f, 64.f), m_boundingVolumeUpdated(true), m_verticesUpdated(false) { + SetDefaultMaterial(); } NzSprite::NzSprite(NzTexture* texture) : m_boundingVolume(NzBoundingVolumef::Null()), m_color(NzColor::White), m_textureCoords(0.f, 0.f, 1.f, 1.f), +m_size(64.f, 64.f), +m_boundingVolumeUpdated(false), m_verticesUpdated(false) { - if (texture) - { - m_material = new NzMaterial; - m_material->SetPersistent(false); - m_material->SetDiffuseMap(texture); - - if (texture->IsValid()) - m_size.Set(texture->GetWidth(), texture->GetHeight()); - else - m_size.Set(64.f, 64.f); - - m_boundingVolumeUpdated = false; - } - else - { - m_size.Set(64.f, 64.f); - m_boundingVolumeUpdated = true; - } + SetTexture(texture, true); } NzSprite::NzSprite(const NzSprite& sprite) : @@ -108,13 +95,27 @@ void NzSprite::SetColor(const NzColor& color) m_verticesUpdated = false; } +void NzSprite::SetDefaultMaterial() +{ + std::unique_ptr material(new NzMaterial); + material->Enable(nzRendererParameter_FaceCulling, false); + material->EnableLighting(false); + + SetMaterial(material.get()); + + material->SetPersistent(false); + material.release(); +} + void NzSprite::SetMaterial(NzMaterial* material, bool resizeSprite) { m_material = material; - - NzTexture* diffuseMap = m_material->GetDiffuseMap(); - if (resizeSprite && diffuseMap && diffuseMap->IsValid()) - SetSize(NzVector2f(NzVector2ui(diffuseMap->GetSize()))); + if (m_material && resizeSprite) + { + NzTexture* diffuseMap = m_material->GetDiffuseMap(); + if (diffuseMap && diffuseMap->IsValid()) + SetSize(NzVector2f(NzVector2ui(diffuseMap->GetSize()))); + } } void NzSprite::SetSize(const NzVector2f& size) @@ -134,15 +135,17 @@ void NzSprite::SetSize(float sizeX, float sizeY) void NzSprite::SetTexture(NzTexture* texture, bool resizeSprite) { - std::unique_ptr material(new NzMaterial); - material->SetPersistent(false); + if (!m_material) + SetDefaultMaterial(); + else if (m_material->GetResourceReferenceCount() > 1) + { + m_material = new NzMaterial(*m_material); + m_material->SetPersistent(false); + } - material->Enable(nzRendererParameter_FaceCulling, false); - material->EnableLighting(false); - material->SetDiffuseMap(texture); - - SetMaterial(material.get(), resizeSprite); - material.release(); + m_material->SetDiffuseMap(texture); + if (resizeSprite && texture && texture->IsValid()) + SetSize(NzVector2f(NzVector2ui(texture->GetSize()))); } void NzSprite::SetTextureCoords(const NzRectf& coords) From 03b91575fb3d06b0103d36bd08f15f3b9e254371 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 00:34:37 +0100 Subject: [PATCH 163/233] Fixed Node::Move taking local scale into account Former-commit-id: ce7b2c086e141c8cfa9981838c9d695f997b3941 --- src/Nazara/Utility/Node.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Utility/Node.cpp b/src/Nazara/Utility/Node.cpp index 6361ea3de..b9105aece 100644 --- a/src/Nazara/Utility/Node.cpp +++ b/src/Nazara/Utility/Node.cpp @@ -270,7 +270,7 @@ NzNode& NzNode::Move(const NzVector3f& movement, nzCoordSys coordSys) } case nzCoordSys_Local: - m_position += m_scale * (m_rotation * movement); + m_position += m_rotation * movement; break; } From 18367d26daaa40adb846d976710c14f74d74846c Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 00:34:59 +0100 Subject: [PATCH 164/233] Added View::SetSize(width, height) Former-commit-id: 9afd04b62e99702720cb10feae2462eaad33a90b --- include/Nazara/Graphics/View.hpp | 1 + src/Nazara/Graphics/View.cpp | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Graphics/View.hpp b/include/Nazara/Graphics/View.hpp index e9d0de8da..b7f016afc 100644 --- a/include/Nazara/Graphics/View.hpp +++ b/include/Nazara/Graphics/View.hpp @@ -45,6 +45,7 @@ class NAZARA_API NzView : public NzAbstractViewer, public NzNode, NzRenderTarget float GetZNear() const; void SetSize(const NzVector2f& size); + void SetSize(float width, float height); void SetTarget(const NzRenderTarget* renderTarget); void SetTarget(const NzRenderTarget& renderTarget); void SetTargetRegion(const NzRectf& region); diff --git a/src/Nazara/Graphics/View.cpp b/src/Nazara/Graphics/View.cpp index 045b22a22..fb55c5054 100644 --- a/src/Nazara/Graphics/View.cpp +++ b/src/Nazara/Graphics/View.cpp @@ -24,7 +24,7 @@ m_zNear(-1.f) NzView::NzView(const NzVector2f& size) : NzView() // On délègue { - m_size = size; + SetSize(size); } NzView::~NzView() @@ -147,6 +147,17 @@ float NzView::GetZNear() const return m_zNear; } +void NzView::SetSize(const NzVector2f& size) +{ + SetSize(size.x, size.y); +} + +void NzView::SetSize(float width, float height) +{ + m_size.Set(width, height); + m_projectionMatrixUpdated = false; +} + void NzView::SetTarget(const NzRenderTarget* renderTarget) { if (m_target) From a244029e116c64e5562bc68635aa93b0e5f71e72 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 00:35:20 +0100 Subject: [PATCH 165/233] Fixed RenderTarget destructor not being virtual Even though it's pretty useless Former-commit-id: 9140fc3bc8aeabf041c5cf90ea3efcabc4ed4940 --- include/Nazara/Renderer/RenderTarget.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Renderer/RenderTarget.hpp b/include/Nazara/Renderer/RenderTarget.hpp index eaec9f2ce..b04edd177 100644 --- a/include/Nazara/Renderer/RenderTarget.hpp +++ b/include/Nazara/Renderer/RenderTarget.hpp @@ -44,7 +44,7 @@ class NAZARA_API NzRenderTarget { public: Listener() = default; - ~Listener(); + virtual ~Listener(); virtual bool OnRenderTargetParametersChange(const NzRenderTarget* renderTarget, void* userdata); virtual void OnRenderTargetReleased(const NzRenderTarget* renderTarget, void* userdata); From 22791ecaf404ec88d78e38f648c683751d733731 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 00:37:05 +0100 Subject: [PATCH 166/233] Fixed some comments Former-commit-id: cbf931edb8cd9d8ba41b4d1f082d0bff7a3b02ba --- src/Nazara/Graphics/DeferredGeometryPass.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Nazara/Graphics/DeferredGeometryPass.cpp b/src/Nazara/Graphics/DeferredGeometryPass.cpp index 577afe5a0..4fe2b2905 100644 --- a/src/Nazara/Graphics/DeferredGeometryPass.cpp +++ b/src/Nazara/Graphics/DeferredGeometryPass.cpp @@ -64,9 +64,6 @@ bool NzDeferredGeometryPass::Process(const NzScene* scene, unsigned int firstWor { 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 useInstancing = instancingEnabled && renderQueueInstancing; // On commence par récupérer le programme du matériau @@ -145,7 +142,7 @@ bool NzDeferredGeometryPass::Process(const NzScene* scene, unsigned int firstWor } else { - // Sans instancing, on doit effectuer un drawcall pour chaque instance + // 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) From 2fed71cc3ae7e1c219bcaf5d52f93ccb2a62f172 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 00:37:47 +0100 Subject: [PATCH 167/233] Fixed mesh centering Former-commit-id: d27dc7f0734d6a5bf0ecd6d36ede2f11cbff7c9c --- src/Nazara/Graphics/Loaders/OBJ/Loader.cpp | 15 ++++++++++++--- src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp | 14 +++++++++++--- src/Nazara/Utility/StaticMesh.cpp | 4 +++- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp b/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp index 07c1742ec..bc9f3b3a4 100644 --- a/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp +++ b/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp @@ -170,9 +170,6 @@ namespace subMesh->SetMaterialIndex(meshes[i].material); subMesh->SetPrimitiveMode(nzPrimitiveMode_TriangleList); - if (parameters.mesh.center) - subMesh->Center(); - // Ce que nous pouvons générer dépend des données à disposition (par exemple les tangentes nécessitent des coordonnées de texture) if (hasNormals && hasTexCoords) subMesh->GenerateTangents(); @@ -185,6 +182,18 @@ namespace subMesh.release(); } + if (parameters.mesh.center) + { + unsigned int subMeshCount = mesh->GetSubMeshCount(); + for (unsigned int i = 0; i < subMeshCount; ++i) + { + NzStaticMesh* subMesh = static_cast(mesh->GetSubMesh(i)); + subMesh->Center(); + } + + mesh->InvalidateAABB(); + } + mesh->SetMaterialCount(parser.GetMaterialCount()); model->SetMesh(mesh.get()); diff --git a/src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp b/src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp index b2b518dae..4712cf9ab 100644 --- a/src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp +++ b/src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp @@ -294,12 +294,20 @@ namespace subMesh->GenerateNormalsAndTangents(); subMesh->SetMaterialIndex(i); - if (parameters.center) - subMesh->Center(); - mesh->AddSubMesh(subMesh.get()); subMesh.release(); } + + if (parameters.center) + { + for (unsigned int i = 0; i < meshCount; ++i) + { + NzStaticMesh* subMesh = static_cast(mesh->GetSubMesh(i)); + subMesh->Center(); + } + + mesh->InvalidateAABB(); + } } return true; diff --git a/src/Nazara/Utility/StaticMesh.cpp b/src/Nazara/Utility/StaticMesh.cpp index b54126008..9e64eceea 100644 --- a/src/Nazara/Utility/StaticMesh.cpp +++ b/src/Nazara/Utility/StaticMesh.cpp @@ -23,7 +23,9 @@ NzStaticMesh::~NzStaticMesh() void NzStaticMesh::Center() { - NzVector3f offset(m_aabb.x + m_aabb.width/2.f, m_aabb.y + m_aabb.height/2.f, m_aabb.z + m_aabb.depth/2.f); + ///DOC: Invalider l'AABB après ça + NzBoxf aabb(m_parent->GetAABB()); + NzVector3f offset(aabb.x + aabb.width/2.f, aabb.y + aabb.height/2.f, aabb.z + aabb.depth/2.f); NzVertexMapper mapper(this); NzSparsePtr position = mapper.GetComponentPtr(nzVertexComponent_Position); From 4a4b4e0fdac0698e0bfbfaa3931d8524b9a9eae4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 00:39:40 +0100 Subject: [PATCH 168/233] Regenerated global headers Former-commit-id: 01c6359d8fae9309dfd1003c3c786de57a93692c --- include/Nazara/Core.hpp | 3 ++- include/Nazara/Graphics.hpp | 5 ++++- include/Nazara/Utility.hpp | 10 +++++++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/include/Nazara/Core.hpp b/include/Nazara/Core.hpp index 71c845bfc..5874cfe07 100644 --- a/include/Nazara/Core.hpp +++ b/include/Nazara/Core.hpp @@ -1,4 +1,4 @@ -// This file was automatically generated on 11 Jul 2014 at 10:21:52 +// This file was automatically generated on 17 Jan 2015 at 00:38:08 /* Nazara Engine - Core module @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include diff --git a/include/Nazara/Graphics.hpp b/include/Nazara/Graphics.hpp index 4d0787084..7e3bf9370 100644 --- a/include/Nazara/Graphics.hpp +++ b/include/Nazara/Graphics.hpp @@ -1,4 +1,4 @@ -// This file was automatically generated on 11 Jul 2014 at 10:21:52 +// This file was automatically generated on 17 Jan 2015 at 00:38:08 /* Nazara Engine - Graphics module @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -61,9 +62,11 @@ #include #include #include +#include #include #include #include +#include #include #include diff --git a/include/Nazara/Utility.hpp b/include/Nazara/Utility.hpp index 78642c29b..6f7ecb312 100644 --- a/include/Nazara/Utility.hpp +++ b/include/Nazara/Utility.hpp @@ -1,4 +1,4 @@ -// This file was automatically generated on 11 Jul 2014 at 10:21:52 +// This file was automatically generated on 17 Jan 2015 at 00:38:08 /* Nazara Engine - Utility module @@ -29,7 +29,10 @@ #ifndef NAZARA_GLOBAL_UTILITY_HPP #define NAZARA_GLOBAL_UTILITY_HPP +#include #include +#include +#include #include #include #include @@ -39,6 +42,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include @@ -52,6 +59,7 @@ #include #include #include +#include #include #include #include From a89adfe55169a005f925abdbc76d79c9dcc52b90 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 19:41:38 +0100 Subject: [PATCH 169/233] Fixed Freetype not being linked to Utility Former-commit-id: 4bbfced926430defe35d6ef800954cdb0f2f6c2a --- build/scripts/module/utility.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build/scripts/module/utility.lua b/build/scripts/module/utility.lua index ba88c4c3b..e6c25021e 100644 --- a/build/scripts/module/utility.lua +++ b/build/scripts/module/utility.lua @@ -10,6 +10,8 @@ files "../src/Nazara/Utility/**.cpp" } +links "freetype-s" + if (os.is("windows")) then excludes { "../src/Nazara/Utility/Posix/*.hpp", "../src/Nazara/Utility/Posix/*.cpp" } links "gdi32" From 91912463fab184622495fae9df9f37bd2e442c28 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 21:42:23 +0100 Subject: [PATCH 170/233] Fixed crash when loading "small" images into atlas Former-commit-id: e34c26159a663a5680658d6312993147a6d804ee --- src/Nazara/Utility/GuillotineImageAtlas.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Nazara/Utility/GuillotineImageAtlas.cpp b/src/Nazara/Utility/GuillotineImageAtlas.cpp index bd7486ab7..ebce4b01a 100644 --- a/src/Nazara/Utility/GuillotineImageAtlas.cpp +++ b/src/Nazara/Utility/GuillotineImageAtlas.cpp @@ -76,12 +76,8 @@ unsigned int NzGuillotineImageAtlas::GetLayerCount() const bool NzGuillotineImageAtlas::Insert(const NzImage& image, NzRectui* rect, bool* flipped, unsigned int* layerIndex) { if (m_layers.empty()) - { // On créé une première couche s'il n'y en a pas m_layers.resize(1); - Layer& layer = m_layers.back(); - layer.binPack.Reset(s_atlasStartSize, s_atlasStartSize); - } // Cette fonction ne fait qu'insérer un rectangle de façon virtuelle, l'insertion des images se fait après for (unsigned int i = 0; i < m_layers.size(); ++i) From 829e82fdd99a54668a638c61598223483ac6041d Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 21:42:35 +0100 Subject: [PATCH 171/233] Removed outdated comment Former-commit-id: b2667fe3877022b61b5fbd6ae1ececc403fe5c1f --- src/Nazara/Graphics/TextSprite.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index ab028ec91..3b34b1ce3 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -9,8 +9,6 @@ #include #include -///TODO: Gérer allocation nouvel atlas - NzTextSprite::NzTextSprite() : m_boundingVolume(NzBoundingVolumef::Null()), m_color(NzColor::White), From b787ce94cff07afde95c51aba9fd9eadb5e29bec Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 21:53:47 +0100 Subject: [PATCH 172/233] (Font) Removed default move-constructor Former-commit-id: 15ccd22b9333327e761500f7b07f0ef7db8ad857 --- include/Nazara/Utility/Font.hpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index 80b175f5f..976b6bb14 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -38,7 +38,6 @@ class NAZARA_API NzFont : public NzResource, NzAbstractAtlas::Listener, NzNonCop struct SizeInfo; NzFont(); - NzFont(NzFont&& font) = default; ~NzFont(); void ClearGlyphCache(); @@ -75,8 +74,6 @@ class NAZARA_API NzFont : public NzResource, NzAbstractAtlas::Listener, NzNonCop void SetGlyphBorder(unsigned int borderSize); void SetMinimumStepSize(unsigned int minimumSizeStep); - NzFont& operator=(NzFont&& font) = default; - enum ModicationCode { ModificationCode_AtlasChanged, From f1694fd6e92a95e71869177d7dbc8e8d4a9eb428 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 22:03:04 +0100 Subject: [PATCH 173/233] (Font) Added mutable default values for glyph border and minimum step size Former-commit-id: 9b69b591afb95fdea9d686ef9b775f965de40d9f --- include/Nazara/Utility/Font.hpp | 7 +++++ src/Nazara/Utility/Font.cpp | 46 +++++++++++++++++++++++++++------ 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index 976b6bb14..d28c04df4 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -74,6 +74,11 @@ class NAZARA_API NzFont : public NzResource, NzAbstractAtlas::Listener, NzNonCop void SetGlyphBorder(unsigned int borderSize); void SetMinimumStepSize(unsigned int minimumSizeStep); + static unsigned int GetDefaultGlyphBorder(); + static unsigned int GetDefaultMinimumStepSize(); + static void SetDefaultGlyphBorder(unsigned int borderSize); + static void SetDefaultMinimumStepSize(unsigned int minimumSizeStep); + enum ModicationCode { ModificationCode_AtlasChanged, @@ -121,6 +126,8 @@ class NAZARA_API NzFont : public NzResource, NzAbstractAtlas::Listener, NzNonCop unsigned int m_minimumSizeStep; static NzFontLoader::LoaderList s_loaders; + static unsigned int s_defaultGlyphBorder; + static unsigned int s_defaultMinimumSizeStep; }; #endif // NAZARA_FONT_HPP diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index 79ce37878..73ea385c7 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -14,15 +14,15 @@ bool NzFontParams::IsValid() const } NzFont::NzFont() : -m_glyphBorder(1), -m_minimumSizeStep(1) +m_glyphBorder(s_defaultGlyphBorder), +m_minimumSizeStep(s_defaultMinimumSizeStep) { } NzFont::~NzFont() { Destroy(); - SetAtlas(nullptr); // On libère l'atlas par la même occasion + SetAtlas(nullptr); // On libère l'atlas proprement } void NzFont::ClearGlyphCache() @@ -302,6 +302,38 @@ void NzFont::SetGlyphBorder(unsigned int borderSize) } void NzFont::SetMinimumStepSize(unsigned int minimumStepSize) +{ + if (m_minimumSizeStep != minimumStepSize) + { + #if NAZARA_UTILITY_SAFE + if (minimumStepSize == 0) + { + NazaraError("Minimum step size cannot be zero as it implies division by zero"); + return; + } + #endif + + m_minimumSizeStep = minimumStepSize; + ClearGlyphCache(); + } +} + +unsigned int NzFont::GetDefaultGlyphBorder() +{ + return s_defaultGlyphBorder; +} + +unsigned int NzFont::GetDefaultMinimumStepSize() +{ + return s_defaultMinimumSizeStep; +} + +void NzFont::SetDefaultGlyphBorder(unsigned int borderSize) +{ + s_defaultGlyphBorder = borderSize; +} + +void NzFont::SetDefaultMinimumStepSize(unsigned int minimumSizeStep) { #if NAZARA_UTILITY_SAFE if (minimumStepSize == 0) @@ -311,11 +343,7 @@ void NzFont::SetMinimumStepSize(unsigned int minimumStepSize) } #endif - if (m_minimumSizeStep != minimumStepSize) - { - m_minimumSizeStep = minimumStepSize; - ClearGlyphCache(); - } + s_defaultMinimumSizeStep = minimumSizeStep; } nzUInt64 NzFont::ComputeKey(unsigned int characterSize, nzUInt32 style) const @@ -482,3 +510,5 @@ const NzFont::Glyph& NzFont::PrecacheGlyph(GlyphMap& glyphMap, unsigned int char } NzFontLoader::LoaderList NzFont::s_loaders; +unsigned int NzFont::s_defaultGlyphBorder = 1; +unsigned int NzFont::s_defaultMinimumSizeStep = 1; From 8b1660a1217861c93efb01346536f32dc8c0c0db Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 22:07:28 +0100 Subject: [PATCH 174/233] (Font) Added Atlas safe check Former-commit-id: daf33e34880e6142f2617e8afa84f8d9df12c4f2 --- src/Nazara/Utility/Font.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index 73ea385c7..01456a1f3 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -431,11 +431,20 @@ const NzFont::Glyph& NzFont::PrecacheGlyph(GlyphMap& glyphMap, unsigned int char return it->second; Glyph& glyph = glyphMap[character]; // Insertion du glyphe - glyph.requireFauxBold = false; - glyph.requireFauxItalic = false; glyph.valid = false; + #if NAZARA_UTILITY_SAFE + if (!m_atlas) + { + NazaraError("Font has no atlas"); + return glyph; + } + #endif + // On vérifie que le style demandé est supporté par la police (dans le cas contraire il devra être simulé au rendu) + glyph.requireFauxBold = false; + glyph.requireFauxItalic = false; + nzUInt32 supportedStyle = style; if (style & nzTextStyle_Bold && !m_data->SupportsStyle(nzTextStyle_Bold)) { From c0995d1739a225b9df32a6acc0ed5193e053a26a Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 22:08:14 +0100 Subject: [PATCH 175/233] Fixed typo Former-commit-id: d1aafe31020733e027a63c9e59dad13b40cd9c29 --- src/Nazara/Utility/Font.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index 01456a1f3..6dfd0cf1f 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -420,7 +420,7 @@ void NzFont::OnAtlasReleased(const NzAbstractAtlas* atlas, void* userdata) } #endif - // Nous ne pouvons pas faire grand chose d'autre que se balancer une erreur à la tête de l'utilisateur avant un potentiel crash... + // Nous ne pouvons pas faire grand chose d'autre que de balancer une erreur à la tête de l'utilisateur avant un potentiel crash... NazaraError("Atlas has been released while in use"); } From 77db6f5dd3927073d0506bda6e56a953e09e3529 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 22:11:29 +0100 Subject: [PATCH 176/233] Added Font initializer Former-commit-id: 9d64e5f28508ebfafe7504a9ba47f57a970e77ce --- include/Nazara/Utility/Font.hpp | 5 +++++ src/Nazara/Utility/Font.cpp | 17 +++++++++++++++-- src/Nazara/Utility/Utility.cpp | 8 ++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index d28c04df4..c0bc61a40 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -76,9 +76,14 @@ class NAZARA_API NzFont : public NzResource, NzAbstractAtlas::Listener, NzNonCop static unsigned int GetDefaultGlyphBorder(); static unsigned int GetDefaultMinimumStepSize(); + + static bool Initialize(); + static void SetDefaultGlyphBorder(unsigned int borderSize); static void SetDefaultMinimumStepSize(unsigned int minimumSizeStep); + static void Uninitialize(); + enum ModicationCode { ModificationCode_AtlasChanged, diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index 6dfd0cf1f..f896c8674 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -328,6 +328,14 @@ unsigned int NzFont::GetDefaultMinimumStepSize() return s_defaultMinimumSizeStep; } +bool NzFont::Initialize() +{ + s_defaultGlyphBorder = 1; + s_defaultMinimumSizeStep = 1; + + return true; +} + void NzFont::SetDefaultGlyphBorder(unsigned int borderSize) { s_defaultGlyphBorder = borderSize; @@ -346,6 +354,11 @@ void NzFont::SetDefaultMinimumStepSize(unsigned int minimumSizeStep) s_defaultMinimumSizeStep = minimumSizeStep; } +void NzFont::Uninitialize() +{ + +} + nzUInt64 NzFont::ComputeKey(unsigned int characterSize, nzUInt32 style) const { // On prend le pas en compte @@ -519,5 +532,5 @@ const NzFont::Glyph& NzFont::PrecacheGlyph(GlyphMap& glyphMap, unsigned int char } NzFontLoader::LoaderList NzFont::s_loaders; -unsigned int NzFont::s_defaultGlyphBorder = 1; -unsigned int NzFont::s_defaultMinimumSizeStep = 1; +unsigned int NzFont::s_defaultGlyphBorder; +unsigned int NzFont::s_defaultMinimumSizeStep; diff --git a/src/Nazara/Utility/Utility.cpp b/src/Nazara/Utility/Utility.cpp index c12459277..04f7af2c2 100644 --- a/src/Nazara/Utility/Utility.cpp +++ b/src/Nazara/Utility/Utility.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +50,12 @@ bool NzUtility::Initialize() return false; } + if (!NzFont::Initialize()) + { + NazaraError("Failed to initialize fonts"); + return false; + } + if (!NzPixelFormat::Initialize()) { NazaraError("Failed to initialize pixel formats"); @@ -123,6 +130,7 @@ void NzUtility::Uninitialize() NzWindow::Uninitialize(); NzVertexDeclaration::Uninitialize(); NzPixelFormat::Uninitialize(); + NzFont::Uninitialize(); NzBuffer::Uninitialize(); NazaraNotice("Uninitialized: Utility module"); From 7fee649b49bd4320152d4caf06c5fdbbc6d2b831 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 22:42:33 +0100 Subject: [PATCH 177/233] (Font) Added default atlas Former-commit-id: 876f42110d4053b09abf86c6158b3ba79fdea201 --- include/Nazara/Utility/Font.hpp | 3 +++ src/Nazara/Graphics/Graphics.cpp | 3 +++ src/Nazara/Utility/Font.cpp | 16 +++++++++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index c0bc61a40..37b2d5ab5 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -74,11 +74,13 @@ class NAZARA_API NzFont : public NzResource, NzAbstractAtlas::Listener, NzNonCop void SetGlyphBorder(unsigned int borderSize); void SetMinimumStepSize(unsigned int minimumSizeStep); + static std::shared_ptr GetDefaultAtlas(); static unsigned int GetDefaultGlyphBorder(); static unsigned int GetDefaultMinimumStepSize(); static bool Initialize(); + static void SetDefaultAtlas(const std::shared_ptr& atlas); static void SetDefaultGlyphBorder(unsigned int borderSize); static void SetDefaultMinimumStepSize(unsigned int minimumSizeStep); @@ -130,6 +132,7 @@ class NAZARA_API NzFont : public NzResource, NzAbstractAtlas::Listener, NzNonCop unsigned int m_glyphBorder; unsigned int m_minimumSizeStep; + static std::shared_ptr s_defaultAtlas; static NzFontLoader::LoaderList s_loaders; static unsigned int s_defaultGlyphBorder; static unsigned int s_defaultMinimumSizeStep; diff --git a/src/Nazara/Graphics/Graphics.cpp b/src/Nazara/Graphics/Graphics.cpp index db8e9c619..9c99f11f7 100644 --- a/src/Nazara/Graphics/Graphics.cpp +++ b/src/Nazara/Graphics/Graphics.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -66,6 +67,8 @@ bool NzGraphics::Initialize() NzRenderTechniques::Register(NzRenderTechniques::ToString(nzRenderTechniqueType_DeferredShading), 20, []() -> NzAbstractRenderTechnique* { return new NzDeferredRenderTechnique; }); } + NzFont::SetDefaultAtlas(new NzGuillotineTextureAtlas); + onExit.Reset(); NazaraNotice("Initialized: Graphics module"); diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index f896c8674..e6498a2be 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include bool NzFontParams::IsValid() const @@ -14,6 +15,7 @@ bool NzFontParams::IsValid() const } NzFont::NzFont() : +m_atlas(s_defaultAtlas), m_glyphBorder(s_defaultGlyphBorder), m_minimumSizeStep(s_defaultMinimumSizeStep) { @@ -318,6 +320,11 @@ void NzFont::SetMinimumStepSize(unsigned int minimumStepSize) } } +std::shared_ptr NzFont::GetDefaultAtlas() +{ + return s_defaultAtlas; +} + unsigned int NzFont::GetDefaultGlyphBorder() { return s_defaultGlyphBorder; @@ -330,12 +337,18 @@ unsigned int NzFont::GetDefaultMinimumStepSize() bool NzFont::Initialize() { + s_defaultAtlas.reset(new NzGuillotineImageAtlas); s_defaultGlyphBorder = 1; s_defaultMinimumSizeStep = 1; return true; } +void NzFont::SetDefaultAtlas(const std::shared_ptr& atlas) +{ + s_defaultAtlas = atlas; +} + void NzFont::SetDefaultGlyphBorder(unsigned int borderSize) { s_defaultGlyphBorder = borderSize; @@ -356,7 +369,7 @@ void NzFont::SetDefaultMinimumStepSize(unsigned int minimumSizeStep) void NzFont::Uninitialize() { - + s_defaultAtlas.reset(); } nzUInt64 NzFont::ComputeKey(unsigned int characterSize, nzUInt32 style) const @@ -531,6 +544,7 @@ const NzFont::Glyph& NzFont::PrecacheGlyph(GlyphMap& glyphMap, unsigned int char return glyph; } +std::shared_ptr NzFont::s_defaultAtlas; NzFontLoader::LoaderList NzFont::s_loaders; unsigned int NzFont::s_defaultGlyphBorder; unsigned int NzFont::s_defaultMinimumSizeStep; From b699d068059d5bc87f0ccd725b9f2519a401f104 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 22:45:25 +0100 Subject: [PATCH 178/233] Fixed typo Former-commit-id: 1482a9580b19f657cccaadbbf4eacc9724d0a1e3 --- include/Nazara/Utility/Font.hpp | 8 ++++---- src/Nazara/Utility/Font.cpp | 20 ++++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index 37b2d5ab5..db675ff8c 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -72,7 +72,7 @@ class NAZARA_API NzFont : public NzResource, NzAbstractAtlas::Listener, NzNonCop void SetAtlas(std::shared_ptr atlas); void SetGlyphBorder(unsigned int borderSize); - void SetMinimumStepSize(unsigned int minimumSizeStep); + void SetMinimumStepSize(unsigned int minimumStepSize); static std::shared_ptr GetDefaultAtlas(); static unsigned int GetDefaultGlyphBorder(); @@ -82,7 +82,7 @@ class NAZARA_API NzFont : public NzResource, NzAbstractAtlas::Listener, NzNonCop static void SetDefaultAtlas(const std::shared_ptr& atlas); static void SetDefaultGlyphBorder(unsigned int borderSize); - static void SetDefaultMinimumStepSize(unsigned int minimumSizeStep); + static void SetDefaultMinimumStepSize(unsigned int minimumStepSize); static void Uninitialize(); @@ -130,12 +130,12 @@ class NAZARA_API NzFont : public NzResource, NzAbstractAtlas::Listener, NzNonCop mutable std::unordered_map m_glyphes; mutable std::unordered_map m_sizeInfoCache; unsigned int m_glyphBorder; - unsigned int m_minimumSizeStep; + unsigned int m_minimumStepSize; static std::shared_ptr s_defaultAtlas; static NzFontLoader::LoaderList s_loaders; static unsigned int s_defaultGlyphBorder; - static unsigned int s_defaultMinimumSizeStep; + static unsigned int s_defaultMinimumStepSize; }; #endif // NAZARA_FONT_HPP diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index e6498a2be..a2b4bc645 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -17,7 +17,7 @@ bool NzFontParams::IsValid() const NzFont::NzFont() : m_atlas(s_defaultAtlas), m_glyphBorder(s_defaultGlyphBorder), -m_minimumSizeStep(s_defaultMinimumSizeStep) +m_minimumStepSize(s_defaultMinimumStepSize) { } @@ -182,7 +182,7 @@ unsigned int NzFont::GetGlyphBorder() const unsigned int NzFont::GetMinimumStepSize() const { - return m_minimumSizeStep; + return m_minimumStepSize; } const NzFont::SizeInfo& NzFont::GetSizeInfo(unsigned int characterSize) const @@ -305,7 +305,7 @@ void NzFont::SetGlyphBorder(unsigned int borderSize) void NzFont::SetMinimumStepSize(unsigned int minimumStepSize) { - if (m_minimumSizeStep != minimumStepSize) + if (m_minimumStepSize != minimumStepSize) { #if NAZARA_UTILITY_SAFE if (minimumStepSize == 0) @@ -315,7 +315,7 @@ void NzFont::SetMinimumStepSize(unsigned int minimumStepSize) } #endif - m_minimumSizeStep = minimumStepSize; + m_minimumStepSize = minimumStepSize; ClearGlyphCache(); } } @@ -332,14 +332,14 @@ unsigned int NzFont::GetDefaultGlyphBorder() unsigned int NzFont::GetDefaultMinimumStepSize() { - return s_defaultMinimumSizeStep; + return s_defaultMinimumStepSize; } bool NzFont::Initialize() { s_defaultAtlas.reset(new NzGuillotineImageAtlas); s_defaultGlyphBorder = 1; - s_defaultMinimumSizeStep = 1; + s_defaultMinimumStepSize = 1; return true; } @@ -354,7 +354,7 @@ void NzFont::SetDefaultGlyphBorder(unsigned int borderSize) s_defaultGlyphBorder = borderSize; } -void NzFont::SetDefaultMinimumStepSize(unsigned int minimumSizeStep) +void NzFont::SetDefaultMinimumStepSize(unsigned int minimumStepSize) { #if NAZARA_UTILITY_SAFE if (minimumStepSize == 0) @@ -364,7 +364,7 @@ void NzFont::SetDefaultMinimumStepSize(unsigned int minimumSizeStep) } #endif - s_defaultMinimumSizeStep = minimumSizeStep; + s_defaultMinimumStepSize = minimumStepSize; } void NzFont::Uninitialize() @@ -375,7 +375,7 @@ void NzFont::Uninitialize() nzUInt64 NzFont::ComputeKey(unsigned int characterSize, nzUInt32 style) const { // On prend le pas en compte - nzUInt64 sizePart = static_cast((characterSize/m_minimumSizeStep)*m_minimumSizeStep); + nzUInt64 sizePart = static_cast((characterSize/m_minimumStepSize)*m_minimumStepSize); // Ainsi que le style (uniquement le gras et l'italique, les autres sont gérés par un TextDrawer) nzUInt64 stylePart = 0; @@ -547,4 +547,4 @@ const NzFont::Glyph& NzFont::PrecacheGlyph(GlyphMap& glyphMap, unsigned int char std::shared_ptr NzFont::s_defaultAtlas; NzFontLoader::LoaderList NzFont::s_loaders; unsigned int NzFont::s_defaultGlyphBorder; -unsigned int NzFont::s_defaultMinimumSizeStep; +unsigned int NzFont::s_defaultMinimumStepSize; From c688b3f363443050950a3370a4f55dbc35587a6d Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 22:45:36 +0100 Subject: [PATCH 179/233] Fixed missing include Former-commit-id: 9bc1621e951ff5d9cb4bd15bffff3fd477104fd4 --- src/Nazara/Graphics/Graphics.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Nazara/Graphics/Graphics.cpp b/src/Nazara/Graphics/Graphics.cpp index 9c99f11f7..8ee1cf1c8 100644 --- a/src/Nazara/Graphics/Graphics.cpp +++ b/src/Nazara/Graphics/Graphics.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include bool NzGraphics::Initialize() From 722fba5d0c0876730636e4ba361833ae52f612ee Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 22:47:03 +0100 Subject: [PATCH 180/233] Fixed compilation error Former-commit-id: a88d418a78a1fed1606064898f4f191a3ac9ca53 --- src/Nazara/Graphics/Graphics.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Graphics/Graphics.cpp b/src/Nazara/Graphics/Graphics.cpp index 8ee1cf1c8..0048404ad 100644 --- a/src/Nazara/Graphics/Graphics.cpp +++ b/src/Nazara/Graphics/Graphics.cpp @@ -68,7 +68,7 @@ bool NzGraphics::Initialize() NzRenderTechniques::Register(NzRenderTechniques::ToString(nzRenderTechniqueType_DeferredShading), 20, []() -> NzAbstractRenderTechnique* { return new NzDeferredRenderTechnique; }); } - NzFont::SetDefaultAtlas(new NzGuillotineTextureAtlas); + NzFont::SetDefaultAtlas(std::make_shared()); onExit.Reset(); From cfe1bcf107acc6b285fffc0482be41578656a569 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 22:48:27 +0100 Subject: [PATCH 181/233] Fixed Font::[Get|Set]Atlas interface Former-commit-id: 7670317dc2684fc0f9240a1f188e4ba92592a263 --- include/Nazara/Utility/Font.hpp | 4 ++-- src/Nazara/Graphics/TextSprite.cpp | 2 +- src/Nazara/Utility/Font.cpp | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index db675ff8c..99ef0555d 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -49,7 +49,7 @@ class NAZARA_API NzFont : public NzResource, NzAbstractAtlas::Listener, NzNonCop bool ExtractGlyph(unsigned int characterSize, char32_t character, nzUInt32 style, NzFontGlyph* glyph) const; - const NzAbstractAtlas* GetAtlas() const; + const std::shared_ptr& GetAtlas() const; unsigned int GetCachedGlyphCount(unsigned int characterSize, nzUInt32 style) const; unsigned int GetCachedGlyphCount() const; NzString GetFamilyName() const; @@ -70,7 +70,7 @@ class NAZARA_API NzFont : public NzResource, NzAbstractAtlas::Listener, NzNonCop bool OpenFromMemory(const void* data, std::size_t size, const NzFontParams& params = NzFontParams()); bool OpenFromStream(NzInputStream& stream, const NzFontParams& params = NzFontParams()); - void SetAtlas(std::shared_ptr atlas); + void SetAtlas(const std::shared_ptr& atlas); void SetGlyphBorder(unsigned int borderSize); void SetMinimumStepSize(unsigned int minimumStepSize); diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index 3b34b1ce3..59630ab57 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -132,7 +132,7 @@ void NzTextSprite::SetText(const NzAbstractTextDrawer& drawer) unsigned int fontCount = drawer.GetFontCount(); for (unsigned int i = 0; i < fontCount; ++i) { - const NzAbstractAtlas* atlas = drawer.GetFont(i)->GetAtlas(); + const NzAbstractAtlas* atlas = drawer.GetFont(i)->GetAtlas().get(); if (m_atlases.insert(atlas).second) atlas->AddListener(this); } diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index a2b4bc645..9052c15a1 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -104,9 +104,9 @@ bool NzFont::ExtractGlyph(unsigned int characterSize, char32_t character, nzUInt return m_data->ExtractGlyph(characterSize, character, style, glyph); } -const NzAbstractAtlas* NzFont::GetAtlas() const +const std::shared_ptr& NzFont::GetAtlas() const { - return m_atlas.get(); + return m_atlas; } unsigned int NzFont::GetCachedGlyphCount(unsigned int characterSize, nzUInt32 style) const @@ -277,7 +277,7 @@ bool NzFont::OpenFromStream(NzInputStream& stream, const NzFontParams& params) return NzFontLoader::LoadFromStream(this, stream, params); } -void NzFont::SetAtlas(std::shared_ptr atlas) +void NzFont::SetAtlas(const std::shared_ptr& atlas) { if (m_atlas != atlas) { From 9662f4167dcf84a980290cc2f2a7d3ed91a8f1af Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 22:55:50 +0100 Subject: [PATCH 182/233] Fixed crash on Utility uninitialisation Former-commit-id: ef9f53674fe21c4d7780e68c62f7981554663a85 --- include/Nazara/Graphics/GuillotineTextureAtlas.hpp | 2 ++ include/Nazara/Utility/AbstractAtlas.hpp | 2 ++ include/Nazara/Utility/GuillotineImageAtlas.hpp | 1 + src/Nazara/Graphics/Graphics.cpp | 4 ++++ src/Nazara/Graphics/GuillotineTextureAtlas.cpp | 5 +++++ src/Nazara/Utility/GuillotineImageAtlas.cpp | 5 +++++ 6 files changed, 19 insertions(+) diff --git a/include/Nazara/Graphics/GuillotineTextureAtlas.hpp b/include/Nazara/Graphics/GuillotineTextureAtlas.hpp index 04197a41b..fa82c8056 100644 --- a/include/Nazara/Graphics/GuillotineTextureAtlas.hpp +++ b/include/Nazara/Graphics/GuillotineTextureAtlas.hpp @@ -16,6 +16,8 @@ class NAZARA_API NzGuillotineTextureAtlas : public NzGuillotineImageAtlas NzGuillotineTextureAtlas() = default; ~NzGuillotineTextureAtlas() = default; + nzUInt32 GetStorage() const; + private: NzAbstractImage* ResizeImage(NzAbstractImage* oldImage, const NzVector2ui& size) const override; }; diff --git a/include/Nazara/Utility/AbstractAtlas.hpp b/include/Nazara/Utility/AbstractAtlas.hpp index 2d290153b..3dabff1eb 100644 --- a/include/Nazara/Utility/AbstractAtlas.hpp +++ b/include/Nazara/Utility/AbstractAtlas.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include class NzAbstractImage; @@ -29,6 +30,7 @@ class NAZARA_API NzAbstractAtlas virtual void Free(NzSparsePtr rects, NzSparsePtr layers, unsigned int count) = 0; virtual NzAbstractImage* GetLayer(unsigned int layerIndex) const = 0; virtual unsigned int GetLayerCount() const = 0; + virtual nzUInt32 GetStorage() const = 0; virtual bool Insert(const NzImage& image, NzRectui* rect, bool* flipped, unsigned int* layerIndex) = 0; void RemoveListener(Listener* font) const; diff --git a/include/Nazara/Utility/GuillotineImageAtlas.hpp b/include/Nazara/Utility/GuillotineImageAtlas.hpp index 22c50fdcb..bf65129f6 100644 --- a/include/Nazara/Utility/GuillotineImageAtlas.hpp +++ b/include/Nazara/Utility/GuillotineImageAtlas.hpp @@ -28,6 +28,7 @@ class NAZARA_API NzGuillotineImageAtlas : public NzAbstractAtlas NzGuillotineBinPack::GuillotineSplitHeuristic GetRectSplitHeuristic() const; NzAbstractImage* GetLayer(unsigned int layerIndex) const; unsigned int GetLayerCount() const; + nzUInt32 GetStorage() const; bool Insert(const NzImage& image, NzRectui* rect, bool* flipped, unsigned int* layerIndex); diff --git a/src/Nazara/Graphics/Graphics.cpp b/src/Nazara/Graphics/Graphics.cpp index 0048404ad..32388e252 100644 --- a/src/Nazara/Graphics/Graphics.cpp +++ b/src/Nazara/Graphics/Graphics.cpp @@ -95,6 +95,10 @@ void NzGraphics::Uninitialize() // Libération du module s_moduleReferenceCounter = 0; + // Libération de l'atlas s'il vient de nous + if (NzFont::GetDefaultAtlas()->GetStorage() & nzDataStorage_Hardware) + NzFont::SetDefaultAtlas(nullptr); + // Loaders NzLoaders_Mesh_Unregister(); NzLoaders_OBJ_Unregister(); diff --git a/src/Nazara/Graphics/GuillotineTextureAtlas.cpp b/src/Nazara/Graphics/GuillotineTextureAtlas.cpp index 0963eddf3..baa477498 100644 --- a/src/Nazara/Graphics/GuillotineTextureAtlas.cpp +++ b/src/Nazara/Graphics/GuillotineTextureAtlas.cpp @@ -7,6 +7,11 @@ #include #include +nzUInt32 NzGuillotineTextureAtlas::GetStorage() const +{ + return nzDataStorage_Hardware; +} + NzAbstractImage* NzGuillotineTextureAtlas::ResizeImage(NzAbstractImage* oldImage, const NzVector2ui& size) const { std::unique_ptr newTexture(new NzTexture); diff --git a/src/Nazara/Utility/GuillotineImageAtlas.cpp b/src/Nazara/Utility/GuillotineImageAtlas.cpp index ebce4b01a..7f12b2e38 100644 --- a/src/Nazara/Utility/GuillotineImageAtlas.cpp +++ b/src/Nazara/Utility/GuillotineImageAtlas.cpp @@ -73,6 +73,11 @@ unsigned int NzGuillotineImageAtlas::GetLayerCount() const return m_layers.size(); } +nzUInt32 NzGuillotineImageAtlas::GetStorage() const +{ + return nzDataStorage_Software; +} + bool NzGuillotineImageAtlas::Insert(const NzImage& image, NzRectui* rect, bool* flipped, unsigned int* layerIndex) { if (m_layers.empty()) From f9345dc5fe5ba4e52f1a2de8dad9af1b2ef9f9b5 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 23:00:56 +0100 Subject: [PATCH 183/233] (TextSprite) Added atlas storage check Former-commit-id: f9d222e196a0ef1aebcfd2baf8b425f55f852a9a --- src/Nazara/Graphics/TextSprite.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index 59630ab57..356327d5d 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include #include @@ -129,10 +130,26 @@ void NzTextSprite::SetText(const NzAbstractTextDrawer& drawer) { ClearAtlases(); + NzCallOnExit clearOnFail([this]() + { + Clear(); + }); + unsigned int fontCount = drawer.GetFontCount(); for (unsigned int i = 0; i < fontCount; ++i) { - const NzAbstractAtlas* atlas = drawer.GetFont(i)->GetAtlas().get(); + NzFont* font = drawer.GetFont(i); + const NzAbstractAtlas* atlas = font->GetAtlas().get(); + + #if NAZARA_GRAPHICS_SAFE + if ((atlas->GetStorage() & nzDataStorage_Hardware) == 0) + { + // Cet atlas ne nous donnera pas de texture, nous ne pouvons pas l'utiliser + NazaraError("Font " + NzString::Pointer(font) + " uses a non-hardware atlas which cannot be used by text sprites"); + return; + } + #endif + if (m_atlases.insert(atlas).second) atlas->AddListener(this); } @@ -233,6 +250,8 @@ void NzTextSprite::SetText(const NzAbstractTextDrawer& drawer) m_boundingVolume.MakeNull(); m_boundingVolumeUpdated = false; m_verticesUpdated = false; + + clearOnFail.Reset(); } NzTextSprite& NzTextSprite::operator=(const NzTextSprite& text) From e495c1094ab10b42384e6a84dce94ce06bdfc5e0 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 23:03:50 +0100 Subject: [PATCH 184/233] Fixed first atlas layer being resized to zero Former-commit-id: f38c09255df40d62ddfa943cbd89353ff9a18cd0 --- src/Nazara/Utility/GuillotineImageAtlas.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Nazara/Utility/GuillotineImageAtlas.cpp b/src/Nazara/Utility/GuillotineImageAtlas.cpp index 7f12b2e38..96d52f12a 100644 --- a/src/Nazara/Utility/GuillotineImageAtlas.cpp +++ b/src/Nazara/Utility/GuillotineImageAtlas.cpp @@ -112,6 +112,9 @@ bool NzGuillotineImageAtlas::Insert(const NzImage& image, NzRectui* rect, bool* { // Dernière couche, et le glyphe ne rentre pas, peut-on agrandir la taille de l'image ? NzVector2ui newSize = layer.binPack.GetSize()*2; + if (newSize == NzVector2ui::Zero()) + newSize.Set(s_atlasStartSize); + if (ResizeLayer(layer, newSize)) { // Oui on peut ! From 9f40fe12b10d4427888a85b8e0b70826acc77827 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 23:07:21 +0100 Subject: [PATCH 185/233] (SimpleTextDrawer) swapped str and characterCount arguments Former-commit-id: f009a36533158c37bcf4c996f62967df068a18af --- include/Nazara/Utility/SimpleTextDrawer.hpp | 4 ++-- src/Nazara/Utility/SimpleTextDrawer.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/Nazara/Utility/SimpleTextDrawer.hpp b/include/Nazara/Utility/SimpleTextDrawer.hpp index ca4b11845..47fa31517 100644 --- a/include/Nazara/Utility/SimpleTextDrawer.hpp +++ b/include/Nazara/Utility/SimpleTextDrawer.hpp @@ -33,8 +33,8 @@ class NAZARA_API NzSimpleTextDrawer : public NzAbstractTextDrawer, NzResourceLis void SetStyle(nzUInt32 style); void SetText(const NzString& str); - static NzSimpleTextDrawer Draw(unsigned int characterSize, const NzString& str, nzUInt32 style = nzTextStyle_Regular, const NzColor& color = NzColor::White); - static NzSimpleTextDrawer Draw(NzFont* font, unsigned int characterSize, const NzString& str, nzUInt32 style = nzTextStyle_Regular, const NzColor& color = NzColor::White); + 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: NzFont* GetFont(unsigned int index) const override; diff --git a/src/Nazara/Utility/SimpleTextDrawer.cpp b/src/Nazara/Utility/SimpleTextDrawer.cpp index e16161d69..855a2ec0b 100644 --- a/src/Nazara/Utility/SimpleTextDrawer.cpp +++ b/src/Nazara/Utility/SimpleTextDrawer.cpp @@ -89,7 +89,7 @@ void NzSimpleTextDrawer::SetText(const NzString& str) m_glyphUpdated = false; } -NzSimpleTextDrawer NzSimpleTextDrawer::Draw(unsigned int characterSize, const NzString& str, nzUInt32 style, const NzColor& color) +NzSimpleTextDrawer NzSimpleTextDrawer::Draw(const NzString& str, unsigned int characterSize, nzUInt32 style, const NzColor& color) { ///FIXME: Sans default font ça n'a aucun intérêt NzSimpleTextDrawer drawer; @@ -101,7 +101,7 @@ NzSimpleTextDrawer NzSimpleTextDrawer::Draw(unsigned int characterSize, const Nz return drawer; } -NzSimpleTextDrawer NzSimpleTextDrawer::Draw(NzFont* font, unsigned int characterSize, const NzString& str, nzUInt32 style, const NzColor& color) +NzSimpleTextDrawer NzSimpleTextDrawer::Draw(NzFont* font, const NzString& str, unsigned int characterSize, nzUInt32 style, const NzColor& color) { NzSimpleTextDrawer drawer; drawer.SetCharacterSize(characterSize); From c02fe6c8ff1945bbc908d63b6776b42bdbc9a651 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 17 Jan 2015 23:42:49 +0100 Subject: [PATCH 186/233] Fixed streaming loaders when used with memory streams Former-commit-id: ce39ee03f40682c00c78b08ac285b9ea36240fa5 --- include/Nazara/Core/ResourceLoader.hpp | 7 +- include/Nazara/Core/ResourceLoader.inl | 82 +++++++++++++++++-- src/Nazara/Audio/Loaders/sndfile/Loader.cpp | 40 +++++++-- .../Utility/Loaders/FreeType/Loader.cpp | 41 ++++++++-- 4 files changed, 150 insertions(+), 20 deletions(-) diff --git a/include/Nazara/Core/ResourceLoader.hpp b/include/Nazara/Core/ResourceLoader.hpp index c2139cfec..83a3f8ce5 100644 --- a/include/Nazara/Core/ResourceLoader.hpp +++ b/include/Nazara/Core/ResourceLoader.hpp @@ -20,6 +20,7 @@ class NzResourceLoader public: using ExtensionGetter = bool (*)(const NzString& extension); using FileLoader = bool (*)(Type* resource, const NzString& filePath, const Parameters& parameters); + using MemoryLoader = bool (*)(Type* resource, const void* data, std::size_t size, const Parameters& parameters); using StreamChecker = nzTernary (*)(NzInputStream& stream, const Parameters& parameters); using StreamLoader = bool (*)(Type* resource, NzInputStream& stream, const Parameters& parameters); @@ -29,10 +30,10 @@ class NzResourceLoader static bool LoadFromMemory(Type* resource, const void* data, unsigned int size, const Parameters& parameters = Parameters()); static bool LoadFromStream(Type* resource, NzInputStream& stream, const Parameters& parameters = Parameters()); - static void RegisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader = nullptr); - static void UnregisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader = nullptr); + static void RegisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader = nullptr, MemoryLoader memoryLoader = nullptr); + static void UnregisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader = nullptr, MemoryLoader memoryLoader = nullptr); - using Loader = std::tuple; + using Loader = std::tuple; using LoaderList = std::list; }; diff --git a/include/Nazara/Core/ResourceLoader.inl b/include/Nazara/Core/ResourceLoader.inl index 8e4fef13d..e716434d0 100644 --- a/include/Nazara/Core/ResourceLoader.inl +++ b/include/Nazara/Core/ResourceLoader.inl @@ -117,9 +117,77 @@ bool NzResourceLoader::LoadFromFile(Type* resource, const NzSt template bool NzResourceLoader::LoadFromMemory(Type* resource, const void* data, unsigned int size, const Parameters& parameters) { + #if NAZARA_CORE_SAFE + if (!parameters.IsValid()) + { + NazaraError("Invalid parameters"); + return false; + } + + if (size == 0) + { + NazaraError("No data to load"); + return false; + } + #endif + NzMemoryStream stream(data, size); - return LoadFromStream(resource, stream, parameters); + bool found = false; + for (Loader& loader : Type::s_loaders) + { + StreamChecker checkFunc = std::get<1>(loader); + StreamLoader streamLoader = std::get<2>(loader); + MemoryLoader memoryLoader = std::get<4>(loader); + + nzTernary recognized = nzTernary_Unknown; + if (memoryLoader) + { + if (checkFunc) + { + stream.SetCursorPos(0); + + recognized = checkFunc(stream, parameters); + if (recognized == nzTernary_False) + continue; + else + found = true; + } + else + { + recognized = nzTernary_Unknown; + found = true; + } + + if (memoryLoader(resource, data, size, parameters)) + return true; + } + else + { + stream.SetCursorPos(0); + + recognized = checkFunc(stream, parameters); + if (recognized == nzTernary_False) + continue; + else if (recognized == nzTernary_True) + found = true; + + stream.SetCursorPos(0); + + if (streamLoader(resource, stream, parameters)) + return true; + } + + if (recognized == nzTernary_True) + NazaraWarning("Loader failed"); + } + + if (found) + NazaraError("Failed to load file: all loaders failed"); + else + NazaraError("Failed to load file: no loader found"); + + return false; } template @@ -175,7 +243,7 @@ bool NzResourceLoader::LoadFromStream(Type* resource, NzInputS } template -void NzResourceLoader::RegisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader) +void NzResourceLoader::RegisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader, MemoryLoader memoryLoader) { #if NAZARA_CORE_SAFE if (streamLoader) @@ -186,20 +254,20 @@ void NzResourceLoader::RegisterLoader(ExtensionGetter extensio return; } } - else if (!fileLoader) + else if (!fileLoader && !memoryLoader) { - NazaraError("Neither FileLoader nor StreamLoader were present"); + NazaraError("Neither FileLoader nor MemoryLoader nor StreamLoader were present"); return; } #endif - Type::s_loaders.push_front(std::make_tuple(extensionGetter, checkFunc, streamLoader, fileLoader)); + Type::s_loaders.push_front(std::make_tuple(extensionGetter, checkFunc, streamLoader, fileLoader, memoryLoader)); } template -void NzResourceLoader::UnregisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader) +void NzResourceLoader::UnregisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader, MemoryLoader memoryLoader) { - Type::s_loaders.remove(std::make_tuple(extensionGetter, checkFunc, streamLoader, fileLoader)); + Type::s_loaders.remove(std::make_tuple(extensionGetter, checkFunc, streamLoader, fileLoader, memoryLoader)); } #include diff --git a/src/Nazara/Audio/Loaders/sndfile/Loader.cpp b/src/Nazara/Audio/Loaders/sndfile/Loader.cpp index d60d4e2de..918455ecd 100644 --- a/src/Nazara/Audio/Loaders/sndfile/Loader.cpp +++ b/src/Nazara/Audio/Loaders/sndfile/Loader.cpp @@ -106,13 +106,21 @@ namespace bool Open(const NzString& filePath, bool forceMono) { - if (!m_file.Open(filePath, NzFile::ReadOnly)) + std::unique_ptr file(new NzFile); + if (!file->Open(filePath, NzFile::ReadOnly)) { NazaraError("Failed to open stream from file: " + NzError::GetLastError()); return false; } + m_ownedStream = std::move(file); - return Open(m_file, forceMono); + return Open(*m_ownedStream, forceMono); + } + + bool Open(const void* data, std::size_t size, bool forceMono) + { + m_ownedStream.reset(new NzMemoryStream(data, size)); + return Open(*m_ownedStream, forceMono); } bool Open(NzInputStream& stream, bool forceMono) @@ -185,8 +193,8 @@ namespace private: std::vector m_mixBuffer; + std::unique_ptr m_ownedStream; nzAudioFormat m_format; - NzFile m_file; SNDFILE* m_handle; bool m_mixToMono; unsigned int m_duration; @@ -243,6 +251,28 @@ namespace return true; } + bool LoadMusicMemory(NzMusic* music, const void* data, std::size_t size, const NzMusicParams& parameters) + { + NazaraUnused(parameters); + + std::unique_ptr musicStream(new sndfileStream); + if (!musicStream->Open(data, size, parameters.forceMono)) + { + NazaraError("Failed to open music stream"); + return false; + } + + if (!music->Create(musicStream.get())) + { + NazaraError("Failed to create music"); + return false; + } + + musicStream.release(); + + return true; + } + bool LoadMusicStream(NzMusic* music, NzInputStream& stream, const NzMusicParams& parameters) { NazaraUnused(parameters); @@ -342,12 +372,12 @@ namespace void NzLoaders_sndfile_Register() { - NzMusicLoader::RegisterLoader(IsSupported, CheckMusic, LoadMusicStream, LoadMusicFile); + NzMusicLoader::RegisterLoader(IsSupported, CheckMusic, LoadMusicStream, LoadMusicFile, LoadMusicMemory); NzSoundBufferLoader::RegisterLoader(IsSupported, CheckSoundBuffer, LoadSoundBuffer); } void NzLoaders_sndfile_Unregister() { - NzMusicLoader::UnregisterLoader(IsSupported, CheckMusic, LoadMusicStream, LoadMusicFile); + NzMusicLoader::UnregisterLoader(IsSupported, CheckMusic, LoadMusicStream, LoadMusicFile, LoadMusicMemory); NzSoundBufferLoader::UnregisterLoader(IsSupported, CheckSoundBuffer, LoadSoundBuffer); } diff --git a/src/Nazara/Utility/Loaders/FreeType/Loader.cpp b/src/Nazara/Utility/Loaders/FreeType/Loader.cpp index 1bf65dcbd..435ec0023 100644 --- a/src/Nazara/Utility/Loaders/FreeType/Loader.cpp +++ b/src/Nazara/Utility/Loaders/FreeType/Loader.cpp @@ -9,6 +9,7 @@ #include FT_OUTLINE_H #include #include +#include #include #include #include @@ -260,16 +261,24 @@ namespace bool SetFile(const NzString& filePath) { - if (!m_file.Open(filePath, NzFile::ReadOnly)) + std::unique_ptr file(new NzFile); + if (!file->Open(filePath, NzFile::ReadOnly)) { NazaraError("Failed to open stream from file: " + NzError::GetLastError()); return false; } + m_ownedStream = std::move(file); - SetStream(m_file); + SetStream(*m_ownedStream); return true; } + void SetMemory(const void* data, std::size_t size) + { + m_ownedStream.reset(new NzMemoryStream(data, size)); + SetStream(*m_ownedStream); + } + void SetStream(NzInputStream& stream) { m_stream.base = nullptr; @@ -303,7 +312,7 @@ namespace FT_Open_Args m_args; FT_Face m_face; FT_StreamRec m_stream; - NzFile m_file; + std::unique_ptr m_ownedStream; mutable unsigned int m_characterSize; }; @@ -357,6 +366,28 @@ namespace return false; } + bool LoadMemory(NzFont* font, const void* data, std::size_t size, const NzFontParams& parameters) + { + NazaraUnused(parameters); + + std::unique_ptr face(new FreeTypeStream); + face->SetMemory(data, size); + + if (!face->Open()) + { + NazaraError("Failed to open face"); + return false; + } + + if (font->Create(face.get())) + { + face.release(); + return true; + } + else + return false; + } + bool LoadStream(NzFont* font, NzInputStream& stream, const NzFontParams& parameters) { NazaraUnused(parameters); @@ -383,7 +414,7 @@ namespace void NzLoaders_FreeType_Register() { if (FT_Init_FreeType(&s_library) == 0) - NzFontLoader::RegisterLoader(IsSupported, Check, LoadStream, LoadFile); + NzFontLoader::RegisterLoader(IsSupported, Check, LoadStream, LoadFile, LoadMemory); else { s_library = nullptr; // On s'assure que le pointeur ne pointe pas sur n'importe quoi @@ -395,7 +426,7 @@ void NzLoaders_FreeType_Unregister() { if (s_library) { - NzFontLoader::UnregisterLoader(IsSupported, Check, LoadStream, LoadFile); + NzFontLoader::UnregisterLoader(IsSupported, Check, LoadStream, LoadFile, LoadMemory); FT_Done_FreeType(s_library); s_library = nullptr; From e30c447bd5ffe9d1a630a28dab4b06979d0f92f3 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 18 Jan 2015 10:38:50 +0100 Subject: [PATCH 187/233] Added default font Former-commit-id: 84fc15f2c6d46bcfb55236863611f2fb96961a6d --- include/Nazara/Utility/Font.hpp | 2 + src/Nazara/Graphics/Graphics.cpp | 23 +++++++++++- src/Nazara/Utility/Font.cpp | 35 ++++++++++++++++++ .../Utility/Resources/Fonts/Cabin-Regular.ttf | Bin 0 -> 188320 bytes .../Resources/Fonts/Cabin-Regular.ttf.h | 1 + src/Nazara/Utility/SimpleTextDrawer.cpp | 5 +-- 6 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 src/Nazara/Utility/Resources/Fonts/Cabin-Regular.ttf create mode 100644 src/Nazara/Utility/Resources/Fonts/Cabin-Regular.ttf.h diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index 99ef0555d..6a87d71d2 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -75,6 +75,7 @@ class NAZARA_API NzFont : public NzResource, NzAbstractAtlas::Listener, NzNonCop void SetMinimumStepSize(unsigned int minimumStepSize); static std::shared_ptr GetDefaultAtlas(); + static NzFont* GetDefault(); static unsigned int GetDefaultGlyphBorder(); static unsigned int GetDefaultMinimumStepSize(); @@ -133,6 +134,7 @@ class NAZARA_API NzFont : public NzResource, NzAbstractAtlas::Listener, NzNonCop unsigned int m_minimumStepSize; static std::shared_ptr s_defaultAtlas; + static NzFont* s_defaultFont; static NzFontLoader::LoaderList s_loaders; static unsigned int s_defaultGlyphBorder; static unsigned int s_defaultMinimumStepSize; diff --git a/src/Nazara/Graphics/Graphics.cpp b/src/Nazara/Graphics/Graphics.cpp index 32388e252..bbfbaf47d 100644 --- a/src/Nazara/Graphics/Graphics.cpp +++ b/src/Nazara/Graphics/Graphics.cpp @@ -96,9 +96,30 @@ void NzGraphics::Uninitialize() s_moduleReferenceCounter = 0; // Libération de l'atlas s'il vient de nous - if (NzFont::GetDefaultAtlas()->GetStorage() & nzDataStorage_Hardware) + std::shared_ptr defaultAtlas = NzFont::GetDefaultAtlas(); + if (defaultAtlas && defaultAtlas->GetStorage() & nzDataStorage_Hardware) + { NzFont::SetDefaultAtlas(nullptr); + // La police par défaut peut faire vivre un atlas hardware après la libération du module (ce qui va être problématique) + // du coup, si la police par défaut utilise un atlas hardware, on lui enlève. + // Je n'aime pas cette solution mais je n'en ai pas de meilleure sous la main pour l'instant + if (!defaultAtlas.unique()) + { + // Encore au moins une police utilise l'atlas + NzFont* defaultFont = NzFont::GetDefault(); + defaultFont->SetAtlas(nullptr); + + if (!defaultAtlas.unique()) + { + // Toujours pas seuls propriétaires ? Ah ben zut. + NazaraWarning("Default font atlas uses hardware storage and is still used"); + } + } + } + + defaultAtlas.reset(); + // Loaders NzLoaders_Mesh_Unregister(); NzLoaders_OBJ_Unregister(); diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index 9052c15a1..0ee48cb92 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -9,6 +9,13 @@ #include #include +namespace +{ + const nzUInt8 r_cabinRegular[] = { + #include + }; +} + bool NzFontParams::IsValid() const { return true; // Rien à tester @@ -325,6 +332,29 @@ std::shared_ptr NzFont::GetDefaultAtlas() return s_defaultAtlas; } +NzFont* NzFont::GetDefault() +{ + // Nous n'initialisons la police par défaut qu'à la demande pour qu'elle prenne + // les paramètres par défaut (qui peuvent avoir étés changés par l'utilisateur), + // et pour ne pas consommer de la mémoire vive inutilement (si elle n'est jamais utilisée, elle n'est jamais ouverte). + + if (!s_defaultFont) + { + std::unique_ptr cabin(new NzFont); + cabin->SetPersistent(true); + + if (!cabin->OpenFromMemory(r_cabinRegular, sizeof(r_cabinRegular))) + { + NazaraError("Failed to open default font"); + return nullptr; + } + + s_defaultFont = cabin.release(); + } + + return s_defaultFont; +} + unsigned int NzFont::GetDefaultGlyphBorder() { return s_defaultGlyphBorder; @@ -370,6 +400,10 @@ void NzFont::SetDefaultMinimumStepSize(unsigned int minimumStepSize) void NzFont::Uninitialize() { s_defaultAtlas.reset(); + + // On rend la police non-persistente et on demande la vérification du compteur (pouvant entraîner la libération de la ressource) + s_defaultFont->SetPersistent(false, true); + s_defaultFont = nullptr; } nzUInt64 NzFont::ComputeKey(unsigned int characterSize, nzUInt32 style) const @@ -545,6 +579,7 @@ const NzFont::Glyph& NzFont::PrecacheGlyph(GlyphMap& glyphMap, unsigned int char } std::shared_ptr NzFont::s_defaultAtlas; +NzFont* NzFont::s_defaultFont; NzFontLoader::LoaderList NzFont::s_loaders; unsigned int NzFont::s_defaultGlyphBorder; unsigned int NzFont::s_defaultMinimumStepSize; diff --git a/src/Nazara/Utility/Resources/Fonts/Cabin-Regular.ttf b/src/Nazara/Utility/Resources/Fonts/Cabin-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..7c57306e7934854251fde05ba725444db47c63b9 GIT binary patch literal 188320 zcmd?S2Yg+{nfHIry^^j~Em@K!Te5T|*^+ycCAmxPHa6IRn`~@TY-2ivYRD!|77RGq zg-teLH_4l@2`L*AAp53(Aqh#AK*&OzLJh_AX54LTithXUJ#*&jxR?snP!Tb|%X#I50APDCL!GddMow#V~ncrSIGzgCW1G%1^ zxA4T-+t+WpAc%cqAbCpWpEzRlS!;{?1;Gio^Zew+(~n)ccjQycgV^t%4}$#7r=4@k z`G5TJ_WnU|Vr3A-A3p7pi;{VdhebiKcqjP>u08+sb8o0jG2)}q^5FE%l`@GXm z8T09nHwLlK-V_9}>T^!H?EH9R)_pG1FG^#rR+(l_DLhF zU0Feldo0K+KPd>0*=Bjy1&;??!@glM{A74n_+a>Gtaog6?5nZw#C{mNE4Dp$AU-^P zQ~bZ;kH(+P%F61U_35myX5F53fA+%ck7eJM-IcR0=a-4%#LUFJ9(g^gdwe^$f9|=t zH|72^@9ez)%6mS)K7V2UC-d*h-(ApAaAv`c1zm+B3(qaQuc)SIbvw~GK~d0>x<6=3Jr;~j zy%Nky?GBDjy%j7+RI*VLY{sHg<*CsTXNyAMNa>odaMvJheS&3G#!spg0&CIrJw&d@%_xb*_3($wQY87Y;iM;X%+FzQ7wd#0h5)Wh`uA^QI;`0fJF z9pL#Kcy3eQ!RaY*Isi^jgVW34^kh&P6sPW?hW+&XF?#+yIKB>EkJHm9!R>xt@ zaC((qzCKJh947mym`{~f6my$ea(0cG-_Z6W!3Qm%!%+o1PYa*rp^1WHU| ze3x^b2fedY1OM-!hkL^{2_A;&AOKX2%e0R~B8;PB%Z&3Ta z)cywJ`*T`&2>#j(5C1Z#fF`?XZ96T!K?}QsA++!0ZX2y^rxoebowTqAD(s_`ZM5<# ztw>L82md$Vpx0?ZlJTa=WCHz_E9{{PbO)Eh)UAyD?~G^4X{C-d$;LR~+1#c5ucANS zMHX*?i=@BaLPNgI^Hl1G=mqKe7V2yxr|b2>2&V(!bO4+VfYY1wT;uo#HAo+6oJN4f zF2<$+EFJ=j2cYb0)c1S1@NsO%0XXp~IPod4x(BRYWDI-J=a;DeR^yR{q%R_UN$R__ z@k6-r+l*&96n+`3e?%+K!I4;oR9EmFF2|WQ;P6QBH4L#dT&wfSE zz5$0m1MPkf?e2$m583GSNc|T2Jq*{r04=@@hTo;v>QRao8|cp-`coYB=U0(Mc!K`C zNIwqHkB8{TYxJWZ{g5>M8qM|?eUOdWO&@mAhduP6AAQ(IAO4$GcEgvs;69WQ7)Wc6 zg7U>B`(E&V94t12_v_%i7hUQ&zXWWafx3@C*;l}17g#(E7CXSAFIY&9 zB-4AqKr;OX7#swHYFhs-txGDhqSpJU21Ujgq2BaYY)?!N@5 z7b#gx$wo?!FpB(`KHdW-rc$?{!6l*P(4>Oie3^Q04syudkK6;u{Tk9;!g!T~mGe># z;4O@TCVSC!y|F{J*r6)yP<1dD43CFi3!&~JY|s*DwG_A$ow^)db`>p&m%mC~H)FZK zi(b7Y7)C2E!C`NM)62nq&}lDpIv6CO*E7)TQSjUby`G}Cf26mMz+r!+$B(1mpNGSq zfWw}~B9>5dFGftZW(YlQK}Oo(&#^XQJHh5Duz3l~^f0v-QQH&Lwujmtqqb+M=@F!> z7j)?hB^uEdL%4>+iDQt+7Nn*XPHId2j2eH3o%=d{IY=*hL8DSIucVia_!dLB#4%&I zx1?^Slza!3`U9HcF-m?D3;7(S571sY7|CO4q|G5*($`}|+tg1eDNP{_wu@4aL#MZp zm;_H7)km)3U^oVfwNOJVa2uG8rQY%6oIqMpgxx;cc#%@OC?%b>hf?xt?u<(PmQoLa z-5yHbLdiYoss#NiM0SgzNI7lR(Wgf4L%4>M-U_zLIh&DN2_N0ch|7ZP#V%w+|03Fa z25tNprR3EPqttHN+(OCyVEP7azDb*J(&l!X1asQ^=#X-P9mDeuGkPQEDHh z-lD`~=ui2_(%txf)^0xaW{z76n76`fZR8wFE#v9)B1$h|+?H~$pw#PV_Lu4BbM*5W zH2X{RRsQaMw0l2&ewiBg(C0m1{~~yN&HCNO_p$U~9K1B1avIOc;3Rvzk``}evj&iS4QX}}-wFmhp-N9=?>X>!5qy3LF55G3Q7^w0 z^>TYgFXf>=Lk-)IrgET4+UlmwK1%(XQafm0Ub`qQI^bELW1t3C1+p;&Z91IP7U>~<(R}ii-ay-Frd5Zw8%j;DqU{c%$Bze~^)|HZwy4enXwKL0*2|%I1^p=l z=TgeZ-@ltOuh6?)l#!3H2gxhLPmo1BKpn3cg=M+kqW5o;Hw8ZOLVK8Bv>$wSGKP8d zvM}{MxZ+8;LAFw!muAJn=7DJ39%gQ$nk602Qv0u{^%ZJ;i`w3_S;r3iw_VskdHM2~ z_d!2-%x^JQ+Q&%mrXQ2RW+kav)cS-$zf1ihc!*2SnCtK?#+cS%8>`8ck9D0)?JLnm zJAn(JUq3WeKc38EG@F7+XpYH@iTv8%V()&3Kl=yn4{_fa9FHZ;hh|Ca+a&6kOo^4` z-WiNE-SmdZL_TyV1ZVl3lfY1ZooKicn(m}eiWLl??F1u`FU^P?*CA>0S^fhJ{GVuC z=dV=57hBB=?gVRBF6UkIgu!*-mkl+a2a+$IZ{w~pFAZW~q_GiIHD@mct4jEwFPJ46 zD^XB#zLFMqQo_xhw!?LM;ky0ND8IrezX>HZ16BVf!#gYKV;OaCrS84-WlaP|h#=p-~!vSh|6Z{?c*3=_k5W$?Hu+k{`27SJbm6w zuII@03Zwrd{l1$~_zk1JkCE8SsQ-@9xQ%)37I?Ch5h#O7l}KnW`WS1SNovsg;MlD} zXK*Z0*aNB0q@GB&RCC-s@5qmcS&YW>ll{H;>qyr;U`LLT`b z1^WMIsYl_`1F79`=^Na2Jp)a*BQt-44^r?5Sb!ZGK=>GL-2VKlK}|93MFE1-rwaSk)l)2i8Wmqz~#8rw_+c)Ego~cMV}7>NB9Un z`~!84l1iC_9|RNCN?WhH+SLog0n6yxXY3BRzB!z+O^5W;w}xhY9=$5Y+~Ie=8>~F37mtus8&h(M5Swo%(U=W_+_> z0{={zQa`a7iqVg6ccLr7Jo7`1Px{$2If&cwmjHUiqL42Vufyu5Kea>{17<8wr(Wal z;dJ_8fSdIw5l(*0?)&ku_o+nWIc_zL;4S8BvQURsf_BK5O>{rA^a`Y_vfI1oX+_kE z)$;zw0jwU^%*;xwKmD!eHo87dv5vp*2VQ?dlbH)Dr7e+iMVRe_$J1pj z{Rgb9raz`@BR*6ja<$c@<_(@m#v{FM&z?gknI%XUPXpa;r;{SU#R8~F9@rs%3K$=1 zEg$u~cz7M|J3dv^L-|{oql9HJAN1(u-YfO!-T)RVvMTRY_RoFRJuXM9=};+l+JG_H zb(jVGF)IOwd@{?yUr)2P60iyqn4cI$1XKXq!jljBfj?egrfd96G{@pQu8u>;@`Kj< zm&yMwqj}g^LX#)|GVNv7lF2bg>h8lvZ96+aG&_*|YrO@pULS1K?WwO~!5+r5X9i$4 zKkfNqbGDidv4{-0Gu96nmq$s#>+&D8%1hB)B16iKf?2wLS2FVTb|X`|GIhgl=XGTE z)VKCQ@0sz5qm@nbJNhRR2j$JwNqn;z(9!Dn>!wN0B3hYFWW)})0e^Dl_+c>2)Ea)? z*K8FLQA?2^+w*U6eE%@Wa&qO??-S=?~cd=isx0JWca~R$h$HWCOIykuhtA z10RA54)LSVB(IzQ_rdtg?4$9R<_8fkqg#HPx(V<1aWFn2ss}$l?L9KHPSLzuy=A`t z2>%~u2ac?xn^sopRr>#X`Y*r#^-RlqsI9X4GpzKXwft?rp)WEh4Q9V)H_y9%$h}p5 zt3EbLnOfte4`TydUDPJ4awsNg9&&l$qzsMZ%l$R)jOL@7uX>B;+d7;Nm}71A&;B-d zWbx^g_OI~q+-~q8J`vBJ^P}}Q!pmtd?XfsS()pI*Q5vROZH4hKj22qynQksT%uYUo zB_t|hqZ#q=hoKoeEuv4Rgj-E7y~jN65WnFNzsmce&jRc z_Rn>PviJNY{GZG^-y1%3UMURTJAd~$|EYW*{JB|4?cuVIr&siC7dvOuD{ay2)3}T^ z;a@O=e-S&R$k7{ULdCeALmwWM%J@;HlRh|pz68DiYk!dssk!hU4RdN$&Gg%mOMJV3>Yn;ux8_&0mUc7aOGhovF53s2G7#sf4&CY z;Y+QjA7Wc99f`=ycQp9WQmJ!&9{j9Zm^r>~JK$bT{UCL2>OMUDZ>IhWAOBpl0Xd{R zLhC+G|4XFuaBpo7mgAwL%n%)HM(>Dz}} zrj?`2X#b>!{4nkKGT54oIiyeh>)kWg(By+^o<-_z?`yc#= zT{z4;|2KU8l6auIBfDx`kzr$HZ{U+dW)*+B_r5meG~fS!N$dh_wsd2!I4m~jT|6A( z8o%n!`?rUPer1e9cl*rZ%^r29{NBRpJ0PjZ4zYgknf9aj=%!8gfI+y)* z+WsK59_}B0kg|XIyxm?8Hv8$r<>W8l-uthy+iygcUOF^__5N%5%jeAGE3*NArhojG z!;qL?+KXo_pX{C$|K-~Fa5ee)gi6~A!w0mxAFkDOsTgmZ#`z1_g`#&iIVpxWwR&=D zM1uEGYj`8Gj`Jw=2JUcjj^ZyFH1k$zT`)D6%{!&@c$=#^I5Akn`@~CvlX#o>6#ga$ z=LY8m?ZL7`z=U z4M8I~DU5}A!HTdTEC|-}R#_@Iop)q=r*Tb?DVM((_!jGpIKA!7+pm?pGg$|IxwLo^ zXGaK|DZyF%O$DcOgK5F#{7nb1&jmAr8-gDMD}o;dKM6h>{4BUHxH9-n@Nn?y;0bX0 zS8&=Fd_H(1I1qd(cr%OzUkW@F#$_q=EeGn&uA1KTpbylqg4+F{e=YQ`&yyt!7XS^j%IP!s|OpMYe={?KzUlDyM zivH9G{c(;5*!#Z#s4Duag&*2EIi>rri9R$%f9iq$I-(w^7sF{)eQ|%S^tsjW7($y( z&}WpiDU9;8=>P7A;{)G|?zE#p)8Wk7!JJ@ba14*<@)y9RGvLv=!F*B| z@c;3oodCZtgyR>(@k>cR7G8*j`IM}Pstpb5U>w9F8f!_|G1R8B{Q`Jp8vh5Bon`lc z(aM1zH0o81ySrD>u4tHuzUx^Hl&g)#zY-1z809HZ9VO7Ym;DV!3PkgE{%?VUlBBw; z6iW9ot{4iJ)mh1I{)j3{-^vU+8rSH-)O5aLaQAq<*YIek)?TKuL>JdHkDz!}l2ac2@6vm6E6eDG z&waG}cx13Q*YxOK4`0-qwp4mSlsX%(odCB@isVowLaGz~$fDS5*gZ1-pXX!Jc3*I%>b^sDtRJ0`%uQK^KKX z^k*D>l^y1UiLghQ8|DQmc$5jq1sOIPlmO;ytus|z=RrEn|q2C9;!U8=W zJQ6$_{5tq!@ZZ>?pOfz55we@InvY?pwgeAiq3*#_{etKB1-}eV#@3x0oEEGO)&y&@ zm+OKvf-|vvX9wqC`2sBR`N0LjM}iB3i-L=TOM**-%YyY-!zp zEBG-sI15V~K+_~pU-0>7>bwQ6EeuD6Cx)klmxUh-KND+<-5Yy6_C&HQ**95}tWP#3 zM<&N7&rhyTUYq<*T|J(HxItxa3~s}J7!{rno=n+)u(H3jvZcw&WOXuWWyewWqT~iw zmX+{v!C+$8KP8%ded_$w>eO+mV^VEhpY6(iXU{vkx8Ak&j;*(E{n6I%Z@qcz*S4O! z^{lOHwoZHcLGj{;{`~*7-_pJ_v83bS+}TjCC{+~n2s^l54f2rvqS(kFKej!{zMTVR z=iVOVE?D}#F#PAv+r!jVw+GYv-GPM1SFId&dk_vyCTE;6{kHIAzQl%-Ft`pVJ~TP= zw)lXVCoFB~Om0eUnzMRSa%OVfDXVYG8en%Gtl88#B6(YI;?gttf8o-)+d4X{(%_oT z&hgZfrFtkr_D!ACaAs5kcS{=a4wO662L)~o~Hf^ff zL_ebMw+DA0mJkMqCv-#!P=Y$3#Ejd+4GXA@TSHxy5*q3n>cF#eI&J3;oqOWa8DLu1 zIZVtPleIyfq-kfPm%kdW1FnX`Bc{addANeApFoVm5u`pba#UMGOY>KkEqfDn6GJx! z!H*cfI3CPRck*8r1}$sI6zl|Fin(HxPZTq}Tc#A6``nvHja+i~W^yg&%DKQw$Un-l z5;>HJs|3T38xY6b#}V5&3OCO25^+j^QZQpF*+x{|K|-&|ol!!T62LA{a`I%?J}To~K_&f~GhcX}QYIUib zp@e@P=Xn-rW$`=*T>Dz79;Ehh751?Tb76r#_NahI`Lx&DJ??FfHJj<3eq8PzmD{62 z@GQ4Sg_JC!sUn&Z_DbE1%U2#0*z*#e_u_dko@*kc)Xg>($~Q=cx`#p4X{aAgmwQ?h zp|BZ;(&6eyp|?h%cTkib`+OzjYwWwLzdfiBiF?vsxZ)06*4SRYeg#0h9ow=QkJ9(C zMmeu1!Pp**YZ&)DUn0+vb4bpoLp`|XaWCXv!@Zb$Kkg;mE4Y_&@6EkW^u0=~k!VOX zb2YTt)z;kBz}1}K>KXDVc4NPbMs8@le93|(S1nnv__6^Pj{I1^PaL!0n5*V4IOc*Y zM_w7eweX6C&+*~*Gd>HifI&m-+1Bu>*tTFuZ0BaCPbEQo2puT~gsb8>5)p8{2X6Dg zd1SUc^F5$Bt2ix2mJ%Dj*oZr5BWv$wYb$0073X zl30}_9#0al29II|Y!M@?sf7x0LWKkrsagQCCv(N?^=TxWBAl*?NBl*czxRdKxQ2=PH4$Z`0_ zaWAE;Kzt0qbgqS5tGO=XqB!OV-!9Wm>KStH7a%^Fp*toZDf+_h8IkD9Y+&Zwfn^G^841v$xc#<%zD-?y@U z%;4&lLDkt8Uz}5W^2qU3$%@LxNuzp?8d8S{K#7Lb?)ZS%&tLvSbgvRC*24a>Sz`M-B@{E?Rl*<= zCb=AwETNf%X)eb!61-|G5dRaxNvp<~5{Oi!6B?D!=Lv@y^(I)sEFBnc9lo9Ry2goVSS_6wRv<+OiUWDFX9d#x5CJ=_k8&J-0l9rO>Ik4 zMa96jex>z&d$tZ3*jm)LF8sy2J}QXa*Yz(emkysbvQOpkX+ww48r3K4DD6L{cH+#r z9sNeu_j+f|dp(8Y`=?%s9UuECT5U+s96x0<6ZJf2Z=~jp$i)W8Jl;VtAWQbPm~7Je z)g)B~*{IZ^JgSlsjWdZAm1Kyi%O#y|Mp#y8Xi!7aW@wxjRGS19Awj*x@*B_+DyLAT z>0>#I=1IlT+X6PjD>w+Q&a3%i_~m)v-#xI_0~Z^xnR;Biv~mq!gnALYU$17rg0eCm zY6qClwTdf#!Dhlw9Ia|7O8pN~-v2-cSew@yu$fSU%i{&LR8m)(A(z=oAk>@|)KCeb z5@ZxhgKTS|3Of`dpGc^dT{uro{p<|BID+*LhFQT%GC8P^#)UKlat%Gc znCmL8xQ$Dnz*)aihOagVZTMUoEuL<}$NY$gqj~65f+G1wrKPC8bzGNmnKYll;24J2 zdLYjO%RF$o2RhLkmO0m(#mG=98ehiXmN{j>QFqFhjY=y=#L8XjQX4yoEj@AdX!>9k zUhWa>1hF%?)_Vk(`o=HwfV^ZYl*WCj$E)1qrRj_1Df4Pzx(7JT-#r@OfmRPJ_P`=T z6-;M&;9484x`w8ru%UiKgA0z}d5I`bjczeAc9GLngGfl=Z6|a^{xf=gwI=ys@@w)bv3Y zb}paaG-+tXjB%H){l%cqeQ8y!_n48BrVT3TGqi92rgwI18MmZuh7^1-DExWwPc}!Y z$9UluYIfu~IddkanWE-e|J19amz(}r`N65ng4ZeEGx$6{7h+t19gz>_=N=(&4s29} zihvaSo(FVO12USL?nQPDzs_;lMtm+KdYcDs@W4ij+oKx{5EJ~He|D`0KJPPKZ9qlC z@VNO9&5-i-`87kUi;DUU?Kl65Ylf{j^P_X;ee}$ehTXS^1-y{Ar7sKqXnpw{69P>f zh-J72&o=;ppm&-bs)yNV1obYT-o@XocR3RE9C@v-cmIZnTNkeNz*rnIQnHycW)Yg> zM{Ud~-Qb>QqpY&%rIITeFeFXQHE|i2)8}7t#e6zKZ-!iR@7_K44Lj+~kItL>(KA=r zxYUK;3a^d54%vUU8NTj;KKG;ALn!rdGu@apT8Br)09+FFE*K$%vt@r-jKashfSiV_ zfakr*T<-v3pAYr~t7VhhXg5^8IRdOda-uA$1xgzQzUhG%ePu5}DIO)jG#{@bpLl9M z3MOnyG_^IgRp14-RU|6H32Rp;&;C-yzZMQJ{#?bEF9>hG>YC)mQwA;m(w7zwZoiOr zsCam=HoP(XZ_0lUUq@qk9W=CdZ}b4HP6~tQOn}g$-}-XB>fno=WKpnYy zd0W6U3pN%LD5rcs-HA~oAZmhHN`hGmIue@pP&Ff*(#f`Yuf7;nZ?#nCGv+a;9MDkS z&_YO~rMbL0yzyTa{0slKUvtgk4I5nF#-%<>q;xUFT6HJ?DR@qVMi$v2DaMRxUa#Pb zj04;mNIka0CU+gii@WAOFSnB$a4PAQS z{`C?SvLRhBNM~Q-#0;X|EwMgio1K5xNx`ZqXU-iw{P=U*C!cxjkRkKW8#icnOYPbv z%g^rDJhN!@NuOMB;-^k)Ygu{aaSN|Kr6u;sren^YaplJA{<&k#i~-_p+|(fGg75Q# z&%c)}A&kg)Hq%xd`XI>A1xN5!rno5@mPH|cyDG?%Cz&1SkoUK^=y-xwWB8ac<_)lx zLcaF{JkAv(E(iC+ip>orIf8b!mthp7%~k10d^T454uC)f- z0ETQBR1A*W4lWo3bBsaS{=@0U63Okmk0(pMp^<6 zr*mD(#V}{HM`kEPJycQ=XRL?1{$JvOB{(tSru;)zZ#=hJWO0+npq18UaxLas%XJCY zMlQo3$6*i$zbJZnh6gV9z+&HOx_LJ<1+%ODqh*E=DV-LOsX*U0wbj6WlbK%)j|~ai zEC6Fn89JuSNig3kioIAfsii4VQ9XD-V?|Bdz{--Q_7QXP1}vX<>7vmk#V58;J#j?I zz~+kv&R9{zxLmH>+ zmmUl_%|H620iGwLxkq<^Fq+R<+=1|e1+Qt`Es;16PU}k{?4}^O!!1X8O9;FThng%5 z7a#@t4*>rpz7?zJ7wZh0GX<;|If}HC3^aeXE^IErVM~O27p?C4eK>XgqC5WmCqMZ~ z*wwYPs|y_nshW}bSD;;O_>kfvnKCcI9zlw=Z-5i^C`G%l>`{jYPBuVmYIk6}r3FeT zuFwja827MP?%`q-gpbMgg8Zdqa#>21g^rh#+8Ze>c7xKym+pw{5rLjex6IZbM%o}c zQ|N@;FFuq;Lf#u8FE&~$5F~2Nrwa zQV;0&V=VJ53&?2_J;yh8wQp>iue!wnQVW%+g-VTeF7ebp7}h={_8}3cRSb}BVXSXq zoVCECc?LMqB%C41Y#b7n*0FFF#Y&&(-8yB#e0}@GuygS(eMTQUX6#8*`-^Y%dn~(S1@KK(Fd}x0mI))y+2I+c z)&oxFKuG?%5kaS-8F04)vQZ)xOx{==LbK*`ca|d`hLD3^XZ}VpQc}UUA$;@Fc7!99 z$qjO(Oo|Vhgo+nfJQWXin7gP|)?UUEB<&Gf;y}q6a9qPL>>6JrP;#-fLvPONCK9Xz z%l#l;<2_vczM?&v;oaA?XWQyiBF{D(t|~%57ioO;rHn5Yhs(xPltG3lD0el0)wvd_ zFkqtxF7?0?IKmz+PJ8j!I4qBX|J5Gb93Osr)1y7xBYBwz&ho(JU}{Y)L1Yb(?*njH z3{f4i#~VHH9(cRZA_K7O5YN4>q9~qd_3n%d>emqDclIUhGkU@J+DXgL7&2wxys2%a z!&ePEZd|gVqqDAGb7MtW|B+R7qw7lwYep2+Og?$)so%O{X4u$k_>9%F+pC)AjU2VG zy?=O0S^wtRx>0o{l>^80s~pw3XJNStfX(Nu-?%Al@0vsDD{2+E>dqsjd zN%yu2FT0EXYWy$4-toRMJKBn|trPr1PWX3`3JSllj( zYIj?gXg$ip+!7T+RxoWY6Y9E_a9h`JSBJS>_r&gcXL@X{wur>}Wvtz?0kL1<#S96? z#inHFd=pr;AIYgE$_f&judaD? z;8Zr4c46~~U&z?xy_q{aFvtL*-w+Iq(07p5E$(2Ty>b{GDF;n^BVDk}1De`GJ_VZWSaqQs_jGS zZVfI`6WUT-S?>yqs5jK-R1}fqtxz~{V&{Z@8&_10K5lI5yipbTRm19!pIg_l>e~~W z$4?mF+B*5tsmIQmnrt1|dwx;f*g1nPnl<~R{vE@sFhE9%tJn;yvXG(~?p8oUzrzD}dtieH z+U0SGw6zAvB=tVbBsoTwNz&GY!5NGj@o6{XMmEYs)XdTT40BW}b2J|rQOK|u-jvj6 zhU6KIrTfS`x!CiUwpkf^8$F<~UX&8;y~yzzexnB}93a*!g!Kx=JlW|@7sg3T%?5%{ zTESoAHTZh3>2onSeYmW^8Q%JA@<1odY?ySKJ(8od)?=AQcZpBA)C1`bRC;u;^?+Vp zu^QKSJETaLrOfg`8u3og#Opl1mji6#GJF?%?A$6*82LdB3YBPe$QFi5BO}vbE6Fvn zFgbYsqydvU*9@F9=){?$bIaxpS$%&0j?QFFb7SxFhRD|R8xgy|a{MWC&i&3MlN(E$ zXRU0ns#&|bdC}yCuCJ60XinCescEUM99~~8{v5|xe>TK`plsG=?D^ANIzjhbWSaec zKBBA@9i|B~1?lZMnTwp-0AxXRR_4vYRz%ty;&wU2gl@HCuf&CKmn{oVUEDQWCPBC; zwr#lN1=rlEuoEVU<;(-;_f;4>r(hybI!yrTJtc*KLR`LpwqlZ zcP;Sfo-1K!*LZtuqfq$j)fNmF&a=*T5pl#Dzwo$lDSKeEgE@{U+H2ur>vup{3sTX9 z0?|b4_Xd5Gt5QVd!nYJsabRs>5}a-808Q*93zx2X^wCw19{1pb4?>@*!HwbfL(Q-g zigagd?&jnEzDc(*MfbIR%f^BDvynOq!nX<9$ItGvdr!6=V;wf63;cD!his@ThaG3xfXMoL&v^P zm*;c`WD~xrvbs#K4D@wf>w!ML(oF`mHAuCvuWEQqYK2gpkBamRi^AFvseE=qymx(L zJsM?r-`+zS`eyejUEDhI*w%gxeVY3=guRw8zi(i6ZOf<;quP=+!)uER%PRAy^=qta zomST{FFB=dYQN`X7)GW3GxoLEAl|H*7yctVjl@YK@wOziBZ(>}fJfR;YHO~^^jes~ z2%wF`%GV)DpU%Kp>OCH4^+1aNd5YOSbbP6&G!7acyp9CmXm}>tfGw zuxEn%Yz^;i_%6h_z)8zPL&OgJ%Cp?RItzx^1w*W04EHjRM|Jisk8iBx`28-QuokIp zwFiFTfl&_7lBiq$Npcs%YS&~1)l@TfY61o?)MQ%`AQQYlD=w78r;ax%iakaVJfwpSbRtW5=)PsLw90t8S_qkXKxK z-iSobpwA^4_*;zvm^H7Gs~@ z2Dqg_sOgtSa}iSQz}7kkZ>ZW}%D@q+jq`eICGm!0KiIEY-Mpfl?*2JC&xUu@LrWkGHr~)yre$)58#z-9z_?OekLzZ+|mJ6_Buy zr`iQf_H6UTWXBaYm$fPe%5;pQKxp@XWX|X+=#q=TS1=e%)d(II5&>zjmbHV}MdfAo zx?SQ+J$qd2Mn#%Ga)8;A=}5iN0~HR?M#OvuDT<(8;={OFiL|j<kzFQ^nu`I}azV{(M!eJ(i<~03%42zn2d?rsUE+WQ9FjwCb1;y$;Zxh?q6yl1 z4_xCByxaq8JYI`EkjC^{T|t-^7EGLW!qA?v(;rOq9@<#fSeo7S#OsO5p^XhA`V~sff+pe;vzV_nhPP-ZVibE> zX8pCi%a`PQ@GoM{>uIp#O78mW$$L-bnqZrU)S} z!UUQafXh-3RQgHMQV*nEpfi2SEE`y9pGsGCHsxa$wlK+0H@FlLwCXE-^-^4yqs& zCiblE*{4ToMRs{b-jbp*CvQCA_>CvG3|d-NG5DCZ6DO>lJ2)244imhU+hgfK`K!`- zx1#e3f**2e{iLbrMV-Q`j?czSI0K(PR6y1QM9oS7c9VcnFI+XE+8 zU!2zKX}lx#CNA<;<~@`e^9nM!Xs;9zY%X-Qt;q0Rj6sNiNc^R& zEah|$u#1co4XEnjnVivVoKZO*q%QH5b^6NA@I{w-;0gl%+{AJ9_TQDwJt<5YYUeqPtb}fC{)WK#lIueBfSaWh%NY;n;HuUzsO#m?Uo5L@UU+lY_ro4t2f{_MyB0sNSm#xS;x}SQT37s< z;=x#P+1Kmz%o$LbQ2H*aceqqNj->RbUV09FiBCHd)j2nb^Ak|dPtlyY+ek+1i8hHA z^D*n9b9&=Yo6D$%&N1-fEbC55LrGou7M%%F!K(1)*xCmcci}h)JJYe}pkw=o^Ys>( z>DX*0+}T8+BIZc~*br?Xg8@ka5|ehH68Mw_KE?9jA{UV0g1`j~q%>}s^|cnLI)d~D zgzxQps9djUom$1kkE94iN&jo$5a%w`(0?t{JD)ABG}8++olwg9p^&Np2@I{1pLFgM zU8Z~{efdaLKGK<=b`$JPo0;@YyGOM5N-o1jE?akZwPh;73?0~}9fc)D@$h5EeC(v= zF)KcC>?O-`&saWbWqY!I+G$f~4?FjPvI$eB6}6!IPT06=%)k=|44QNLr1sNi4=lZ9 zao2tMr9GwOBwt@J`TA|fy2KXGaXfY-l=MJ{0CA<*Q!_g0AMM2>>8E~#dkWCNrWfdZ zOv5cCh)MN!p7#0V%3OAsi|5Dg1Nzsjc2J-EYwfm_f87%jhAZ$m>fqUC{%?+bVO7^f zt5$`dUKLL1`YGP-(_x+XRvnby=k2SE{Z_K6q;r`7a(8_`-vN3Ynjx^q=kvu#q6!UI zV1)49c@M2(`>C35UA4-@C) z)$Zu1Q>1?UGKpppgiOV$fS)3kapo*&J+lkM&9W6Yi@}a{4Y|BX6o(CClUB?6@!zLl z#0$eYT|esjr)b>G9_%#wenj;|b}sTY4x{e%Y3imopWNy?ql|u|s>l94+z7AUu~-O6 zxU=hIq=OZ`FHj9_jD+lOgHwL&bJ7jW9%Q2=F_F@a#^^>;ZsTH%^d@HzoUAX0nz3#@ zA+k^nFP^I!jc|++W{xa6*IdM4DSKD7d&L zW3SDfS*)+IeyN&!04Ua{h(JP1tmD9C4wqgsVbi1DL6Di16PRUj1jAMio!l-dEXP*1 zi6%Xly20EHs%r)Cx?XWfgwkG29=+{SvaO0M_+q5&v{Vg-2-m}GD^2;;Jh`T>vvg@8Dq}U* zMO-GQdjYJGFL+>v1G3Y34ZUef6-hs7k6o9%lD?Q$t&+=4U&-tIsF*^?YuVchrq?-z zIFIz6PA+pD6d=)z{5Zjks<1is_UfrW`T5kCQN>Cr6zb>4BsGp>25>cC9bN4Okg=u8QfhFn=N>%7sU6Js?MH z9fbshW)5h=x9RadVu8JT`-trvhn*+K2EFqLI%03E0J56j_ZWU(uV6s_Sf~4|4MXR&h~%Hd>;DDN(fc zoRrt3wk{B$$6En*`o|kwYMhyp9?QUM=Bq)_CR{~|yo!6bS83h4D4AV=M-DtYEF*s| ziXv);6EMRujivc-#AaszthX@+!=+BW3W#{+G7p^LjqNfAC?;1#oki4X8*Me0Vm(3B zy~G1O(Rj{JTt~z9Y?%ixcYs7Oi%4K3t`YldS7hWxFZLK*>Hsa>=ix*~PCyj5QTH4w zHoj?8To7jfVPUo_Z(1G5caUiQNZLt({85$G<9&U=hY^bF!LIi{$j`YGEC9TO%Yr- z@@Y+RI!`aZy zeX+ZGj#xZ%`tr64)&ie9cGiHFWY0`_E$1YPDs8Pnqia020`BB8E=gKk2YMPHBYhhw zcl*cZyT_94Tx2_+ROs2JQrwM2? zi&`8kL3Y|-Z!289)JwSrsn@YVgVPza1<;z#Fmziy2au<~^7OQwHhwsd*zD6Cs~2Wj zwqwU*26mW;a=6t+@3k=p|0EjZB#_Wc+N;cJyLXVZez~@3-(IrQ#+_&)(CN5AJu!bq z@*8nNr*jw-FtyNy1ik=)w>NPV$SFpci_sYzttsV^e%$=Qkrq7{_Llhe zF7@sCNoS-Pik;}F!EnWZMAKoqArVHK7Me%v)C@`Tn|nTp~Q=f<)J9kX_l6ve=WlUB?q+URw0g$LaGr94{eQx+E&4)KoWyw}(mh^<{zLT3=Uvvdl`RLM8biGOldE2r4;T^ugdd6n)QAsIfW zY83Tj9UxLQYfa+7VYRnG8$HllfNZN?O)wH%>VZzU)>8aCSyENGsH#YgFZLN_N-Sf# zjtZry)gEwPfAXkbm7Nts2oyPIy)@s!X@iH z>bS8}Pp=MVbafRcN7YT5hNSRrNNf;3#JKo5o7woq3ox2zxSdM?=Q(wwnMbre>_!i4 z^}yW@$i|s#!N+OwdMqjs*kj3iY0%;{5kaIDsHte6wkOc6rS~IUs%SvQz(xB9x-CNY z>XK&AsK@ges|{QxNyw|C+fD=A%tvuFjcH)V574V?jknw;gBmSTU*~thr3`Qz5uC~y z2p=gVB@2_!!a@u^7-Q`)h8}g{c8eD|Rs@}~u={K-LuZp0f-_98X=%3itY-VAn(-b; zzwDOYeswMC(70f|=bJM@W6 zd$iUAml~kAQwG5(S zs3u1>IjYh4)$Wa&i#&Z3p1x~65fdJ0^1vCMh}U}Hau4KsYM$wVD-6i4w^MmsXnsUE zoD&M1BWOqS*mi=7ns{wk6Y8p9gF#sNFAED-ezgCjVSW0Jm^NtUqB)i0PC2HgW5Vc? zypPT8H*RRv+DZ8h=*Nu=8dXRt>7E9+d1`R8f86xSCm$2KFfI zmAj_Bpl@T<&{36%tnB=ry%KrZeJjT{)l3@?S4mQ0IoJUV;hlU%tFmhhEh`1g)(CA? zvNxM+O$T}v`yOw|Xu|K}9n#fEl2lhiOIbeM=U+_!pQrw0N7(xiG>*lJB$iZd;^A2KaH zjgNfaj))>gud6W0(d1N4irlNBXr8Eb8>={dj@30@pRevFx~@wyewSqfguLSSxGNdYkA7br4x{rOkd23^=$Ur0MJy}7 z6dmre&GNuT54c&5Rb@I$HN>bvQ872H7Sz1fTNd{=(H#;BtO~ZpPfB1uEdf!}e2cDl z<~d?g6LFKxkhPUh0+kc7&PLabLOW*tM|`=L>k+P(xZdF6eLrn0&)xx8dRTqm}n zYwv3Q{qZq-&ET$gz89NMYi!Vu|BP`c2%l7V&1NuKLz27V)^==@M&v67c)B0q^JT{P zv`m+vH3bxN@jK$&)w)(j^11Y^AR3c_))}x8Az^@#<=SAkrvqks;0h1) zHO3@!z6Zv6sqgE70t1Me=Z6h(1^BAM_|G0V;WqA3ks=6}WRW+%m6iM*N`{H`_NR?fZyNiB3lo1tKB6!2=Z@XceGR z`+dq95A-)69ifm&XmYC4pL9Z|8&+F}X!XQ@!~+UU+qfv!W5A0J&?3GYKO5q2SgH>; zI(c<5TB6vBEg_J!DL!>=y2UlQpIR6rOV9USWIHq*DeT<@gp!{(u2SWM_vnyx4vc7B za~$l%LhriTi=qliT3^oez>(hAMSlFX{lhX}2|L3dU3~RccWgFzGt{qG+zN;}vy#o)7g9my9uXOtj^x#%6Kgmcdm?t5s ztoMVs)&q?mxYdscuVjE>V!hRw6)Zuu7IF5`j0l&Ji5q$FpeuD^2Ek%JMHz=n>Q2rzPjtj;k0ml*OOs` zdV@Fzu^Q--2=CL#Mr%18est1-x079p7Lj6RgpBt#SSrdLtW1>LR!g^tlC=f>Dx#d` z5uM=xE&GK`E^RlrX55jPB)j^N&H7)+`ky&a*^GI}m`8c{16WsynmD0j7UF>Z9{7mQ zv%vtz=(fkR(ho{{bjB-1vU`kwG{mR;gHK7XRiEus`no*XMA!8?3nofc9Q2QK-DACP z8`b_J_b3~I$>#8N*)%`yM_7Vxag)R7RdT8wkGYeOCFt;h}8mBFt6 zSWVZ};k>TO@UpHSpbx*W*!!_FQ|rT7?7>e2$3b%K*1pbFr7($Kt%Ypzr!|HQZjSAr zz!up$XM`e$U6F%a(j*C1jI-<5;lgY`oYj>I!&`2-I)3r=cX$JuN*g%0=S}!5^V}ZI zj|1k%upm3s6vY)MIZXz6(u>nkbIh}8LdP$@xuR?1ibb5+6Y{$}>-jka^@VpB?Ck3; zj#K4+N!K_G#h`lSL+UZ1_gU-+S?&6c=IquNEo^1>hYbRCdVeJhyHdB@65Iavr>1k% z7N0N}75*T6Aod0XU&X3!mVX;U^~+qVdcks`vbBv!yNvW!hI>_n&S{15EGoK!>r-6X z7A`E!q5FXuMHOd4(v)Z+TKfQRP&^p^;L%6VeDqOePi>4f^P8(|k#Lpk9T2q`qeZ=} zBZt9ZlF>T;PXZ4xBsv=sKaqo`QDe5#{LYrx$jcX7-^Rxl2K!>F`(qjfig>n2s)!_1 zuC2bv4YfnYyI&uXD0HZVoQtFZ>N(lMWMSJMdepsdV zYOirXHiwQ>;v-ecS=SVxihk-C=ql%9<`BAYs~bnwKG-*-x6+N0S9`!6=?UlPB|064 zU`8i83{-EdR?(~IU17DQ@U#}L6r#5G>e}2PHTF_>zmS(fn_BczC@Uo4qeY3Dfz_qC zlb6mop>5H+QO#pJrW8(HJ!0yh(z5=aIeW#t{?jJUPLx!a&7R-hJau46ICaF(In90A zmQ7hbe%REDvqrVe?GH~*Ozn^9cM!@sVG;M|&~;AnM=jK_UX2i-6z$E6ghPP*dB6M6 ztP~+VJx?G!CCv3okS2}=7t@{Wo=CNk1<})+AXPB2#xgT987+Kvvr)t~rsa&$GDDS? z(7ks>P8{KKcvQ0}R&$M8#i?$|L!L`AZI05*2kBSvm)MkA3($-3wl#IPVM}iq*TN(H z)4E0(4wK%K)Lyox1eT-Z-QT|-)@$(K0R?#rmW^3G>V)yh`iaMn>(?@{vSMIMO>#{C zva$hV^749Bl}zT)%6r=f&0NvkvSP--@Ro{UQw9&2I<$B7$c}~q9V1{8&hg(L-i#jU z6JC|El8`p@+NB77x#?Yst4KJH%LG5YThVRuw(+#h;8J!Gu*Kw^N0y?IgPu0j+UC~F z44rm_SEgUGk9H+?4_M~-Xp{@lm)h)&4n<-$1peg&6iM_h&@%W@el_G4aeF{qoN+au zj_j;Mh>Z8vp*oyIrWcFSF8M-=S*ElDex=R34j<8lzMJVIYu5Obs~nKPL#hO)O6H%H zj)y<(Fc5-$K(J3V`Yyz10Y-NeY8!jF%O@;jAMm8*6HaX@nmpzB1q+U!I=P@NuW81L zwy`Uw59oJ%&9a3HSJccN0Db9ql5yP;$zqe1>mvJboyD5WjOobNa)yO@DB@EN8QpGC z+jsY};;V2cNe1*rT;5A5`hZu7wT9w_#} z0s-vI(rYn=ru1~st81KumcSa-jDteud(?1(4xpmdH`7~IHZ zvYGatB&Z8WJy}m+NbR%DqTIMv!^A;da7&N{C!Ar620oPPgnX(SPuSxcJh?{grnO_cmA^lO&tF@n(LP?^fM{$olQUX(eIUX8`S6* zO}d4>dmiTwY+$m+C~88bLk1Jvb)Ybl6kD~;WwMxyPRxafxx^lFWo-yV0`%n?%r)K; z15))4UpdzRt`@GW6>im{t+{0k1~gix>BmfI(v`~=70j8?*3nqhuePKtKkLfyrmmC1 zn`VA=(%iy%xrsg_2kQ41`R$oh4!;w(m+Gbj$HlkGyJnY?q;r+`#*!Ym(ExX>x|`rQ z*u^U;5_o6(WDlfW^bI~G>4CdF;5>6#kYl0~YOvn>x6wt9iAgo`2gS#UaJ6b^L9?EE;w>u%S z&OP{z67?3IBf>V6MP&I(2*P;29K&UTphNa#H-^&QRG2`X`p{siDVS2QZO|(3c|il2 zDB2D%pUa9~=TbG@;4!MHfV(^7M%!uJn~Hid9b-N|Lq@7JXsNcSr`AxnYUYU`V! zaINpspif^1M97~^l_5`I-<>;O5f_w z(Wz*iz?lv8?#RT3dYwpL6JwoM>$`SXJ=$8Qe#YxL)!zTyMQZ%wan(ykSJf`6YMwh{ z>Vz@VdgNEsRt>9eo-@3uwlcqN!l=5L;~Hc2?I+D`n>b}m>*S7t63%)%ZpQ5SZ&nU! z?RQ+Vvaw`P&q=2Zp50Q@zj|V#wY_O(YcjW}IJYn_KR2gW&4`BDv4i`>zA>$B+_c$k z<0f~FFUT9+w_(_bT1FIx=65F1_r-eqKzsR2XFY8qNpF)L=rF)BeB?hoO>Sce+o2|J zVT4iy*gil+wtIiCouaeBkMs`jMAdrWHy*gv0Iy1pFcZ$Y|NCU1D7u!wc=-C&XQRjU0=^ zJ}knIwQ=ce&=#&4T-hsl9d>fuRakq*zE3`hid7>Bb%wV{UZN#G8 zW1Bgb&m{z?-%V1Wj=*t3fn)iES}oHH5FDf3T*7HUr43D=U$*S~=idLDbMHV9YoC0! z>%c*cRce3m0%KJWoF{!3y|b?0RgFd_0!FB#;>DEp7{CQCoCBnVCz6W29lzB)I(lRW zv?wgzz51jfmV?lSacDH&s)@Z&*l+5jW!c5GlV?wBj(zf-|Eg^&cTr+=MZ5(+vR|x7 zySk&_vy);r{8Aop8WtQnl!8ZYr#s0L>M*|ZjO8^j4^m$HCOv?=WuvKSvO5C0jJume z_koE-WD2e#2-of1MZYiCJv>#K##LoZ&~zGmJ6T6gD-d%y21l`DFDjo1^IHO?F4o7`9S8|<;BXgB-zblg2fwQIPD0IECr)0laYcgE7^WTubxyh+}qu(%4~ za~_LJT&ngPA9^m4cJM^rn+x+&^7Ev8!{a3c?WIduoN_Eq+VXHzAF~yipLol%)=8gS zHeu|_{>x_O4V*gY{MP0TcZJCr?bmcY9~Lc~iaiQn9n-(>si*#4{3x3gz5$;VhpRH| z{>g{Pf!JRkBVLDqbcz5=k<*#fBQ!+D8>`oOK20-hTFa+-*|G4UPJ&koN0|A@5$NW+ zceDFa5ALliHxu%PU%s)~a>c#11B^(ZkWX89XV^*krsWeK*c-{}>Oya67kY_Td83P5 z2?Np|Li!w!8|+c0t6*alzOih=j8ipEGf%oNESfK0fw7tVVibdmG~F*=VT9b z7$BAF_F=p5c?~MjkKPgC^KNbE!hhZG4e8WGC**64i)hgn(VR$UA=1%{I-O1rEAE-c z96!$qx|d6x+M-7Rk07H4cByyfqWvE_;w6uujg?d@(Q1hcryu^tj*i7}fmD3<@V}>= zKWtZi9r#nDvRAs2x=+wuwR$XFxR>G*o5M$QpR1J-1 zPsTHnbD0+^%^p`u@KR$KW5zM1>!jwkmD4!@r*hboK|`ku?Oipzqp_)D zcwdcwU8*SD8I3=u_UcuA8~!h@4emWO_~{LnnrC#vPRV^F6x#g7d6}9hJ|IDSOLpLK$b8SKBr>HwM5*z!6=Z&nEVIln<6cxwL0pplq#201Mdjf8*oUHWd>05b3X4gk!m!BW zsmhj;wwC(b0~-qlHZ6>Qb6r7sb>Yl=;vZf%qH3h?c@68cJ8_xfGjkl)x#eB}QFHm^ zWDaXj^V}vl5+IUzCghwjz=_Ai7mJOfG8#mbN4g=Oo;vb*r$uUV4c%4)0=c+I50J$- zvW{RBh7hbxNwV*`3|aFC?|=^Z4iz5fht-@PfKv{Txlld_8jtngY`H>;Xs=ZBIdH?{ zB-JcTi3Wq3o3!R#&H4P$Ee$bps=}iHs)4owR`vOql02yPs zn?7u{hig8JTESGgWI$CKP<8Rh^*?83`Ob zw!V}HS5twDQw7#;6?jfmIEndorf=>YIaHg&3AvRMGWcA*(#<5+(u^Q6&oxeA}6()`@2w#DtW+*7PQTFx3?mAHu+d`1_g zdi%SK%$>mDwAG2%GuA5m12?B22YM<}DTRVgZ-Rs2usj=F45>n%7G}a3UBusHtxVi$ z&v7~IBPe06UiFpgZ-Gf5@+4U2U_Os|bneL9;?0~)u*x@(c9V{h=9x(b=SHqeA04k6 z#ym`h_VLQpWveEyoPX(_-~au26@6VR*RNR=Ppmzj_v*DXGwnTWjr99o1XXx z9XoCLzTW|g>y?jG&|?T^hK*Vmy_%iY(XnBX_tduhfjuAHbK92oJ!4bP#7#55IkP0b z$!GzHIEuf=IOoQ7pVIEsW)vo!;)i|dOaL@1mh+qePT*$JJ+ZF#Bx4`V6o$7waea=8 zt;|#a#ARp!XAIvmVIAJe+Oe{-4bvqVa%rGVNK5!BHjXz9M~hPvhsnc_hmD~t7qcgR zKQCEMVlF#B*U5n@?hB)PM*tKU5MyGlL>+F3CAfTWBC zykOQ!Ddw~QHnjjno!v}2*W)1Zk8CyEIrAVZLc64Z ze}uaVV)W1w*BWnf2GH7bVOY8xOaKZ%Ti#Y`Zj3tHUe#gMJQ0A00&rIVdINAc06z2TeS{Um>#7K6Tve1qD4ATsb1`mAzHF0I2)pyV`$qhenQvTw>sPLS+o|}69BSsr z-Kt*z*{{`?f0J%BPU0q6)4M=VslefKD~@LN#X0{4ioI$rwku3yRDs=pFM5#C=w0r#Io}(UD|CwnU@^Zd zJ-kq6@29z+L+V@v?vHdUT|$h=y6c=xN%erxD?k!A2!j z5A%1ial#_$)o%Jua?sO>NA6-i>we1`$AKEvIU)EJjvphP@v35O_YPOr*hSxVw5S@0 zuSg`5>7K5(WHNEh9itQVIRs!&m8a|LTg!6+=Qk}Gy8XK1RL?+P{@8R~{q$IV-@=~M zx=r(@|k`7al?*_1*@AC zG@2Z!Y-7&3OqoH+Xkk6S#GoiDVA=5L-Mhb@{H(p1U><619zLMR|BNDo)WzVmGe}Zw z32xH(Kf*!u4Cx$6kgI)4Ej8Ld{xzon~#IhfyDk{xW_fuIJqT4i*^Wm!eZzmR0<%3|==xf6ha4QiOF- zky%OZ=kGjWQfbUiXqVmQmVGz|Y75xCbGJyGdK;xAX_Z`6wrtuMmHy&)d1+1~*g)+v8q<&ce0@>HN|1j@;_TbV*UiK)R@}p{-!)UzS#s zF3PKJt0^d{C>hS{#{?%@JewPR5Lt~PkG%I&G#GwfrwpyXxk1ykfbbdSNCF2Lfl(qF z7lC3Tcr(ts!hYgNB#aEC1ecj2CR?%YpSvtZ zQ#MR7o4baH_(_hei<_sKk6d}>uM=G_{C&dRZQeHfPx1Q`|4v-nmuDp7l7q^<#)6v3 zj)0nkpwl+;08a~04sss=QTCKcfNU!&TbTTl{FP2!2A`6cYATEQE8OVpjwStRHOXl} zTV4jv4yAUl))h}#1W)O&T^a&VI91(u*uh^X@$QiO*H$vX=E9LKV)$qI>!tEMVV&tb z(7{(rG(>0o=~_YsN!cp!kyi8>civ|40Cmt+jc3@>W{keuNGCHBH1?@Fzt-O zWv(h|l`yFMRqa`BD74<5<+S_V%Iz}5i?2xyaEX$?;zFx36;JLd8`!cW-8i;&xNJ{p z|3uCF=9TH*6}?rvwyan&zieot<<8u`)w{29*g zXS%evHE?BO77ij%xPxSD!6?8qX*qSt+esKzBmJ{K%y+(X!l+G0Lc%z0hqh5Pd|` zi!E!ay*Qb|vypqVBulc8B-J(Xnc{^FE$!v=9xwTLGAF;RD9)L=rmmy5G-rSD&Z4gA z@##y86BA7hrES9<`*w7VEn3vNqkYYWD;Dp#y=TKj+oDcz(+aE=MiXyma}C6s5pX$= zH_1E;XqnD`ber*#y>7d0O*vRC1cGYGv9Fxv-5ezuE6H?vfE+<$bxT<;=15#pE+|aY z$$pgb171}>WXxMH8Lo=;aO_+{vN3oFzy{ZwL*_)?v}inxR~OiBjAUgW0I;$TI@7@% zkY^vrv(G(#kO+`&{1v}I0o(1Z|K((7x^biwU5B+O3A-w5Z);7O*4XqYG?Aa!Zay`B z!FNS1`e=>+-2DI{T39z%YT=G$(ZSI7kJre?Fm+K(!I7q|Yd371-rBf%>$WY8TP|I* zZvD2#EnByZ_HFK7-dkPWyS!U}M{5svbserfbotFMzv2*Z_mSGem%sd`9r2}OO~Y&Z z`nY7KX=H7$A`3J0+&7iDAA7Ir_{K0YDN6(-lMdU_ME!TenDOs-`doKv z$)%W_0-Sur>JbWaiVq=aCul|K1uSc?;!>6eaE18s-8vm;Gt>s4+W_Zy=gK+z*=u3E8(^i^Z|TNk^+c+*QdX=OFu`_vL>iay1@0+CZ&4GOO;0Gz{{)$D&tXKY^c>=`kQQ(W0WY9G}uC0W3Z`)6MG zP}QG&xav<1kUm`Xj+qzsJwvq6nG<6x$KLP;{)tb_d^H}{oDscZb|5-qJgRvp=Q=Jm z#Pb!4#D`B9b=9OfnYY;u$_duk_$Hiq^v%xM zKabzVH%FqWtsDMH?S^8={6Sg$U0hfw9SxUZCk@a?d zV5lh}#bH@d0!2!A$sg}0a()L<6N*gF-W$Od*TF|@Y^vM6! zRpWt^(SULk5_JfH$B=7!l?$$=4lSZXi(Kxy5OV8q0JcZVcw2<6mbUkh=(&cnkmh(F zvb#bbG8Y?f_-&n$7me$T4d5w$SZhy)_E(1XcLv}fi@}%iz_F0?fa{u!hjcV$@D2sw z6`=#Zqax9ZLKzRJ+xFHK)=6IP3_vf;q&?beKxeZZVlff4*kOtS$<=e?A$C}B>}#G^ zRf)q{Ri)k18ZWD=DNI)OPWAV1t1MbGIW*q0f*@co>#nQlUD>~5MbVm-3rD(_O)u+y zrntSi^3OW@K3!Vh&|KM!L3nl9WN&X@dv|SB=Zeu+v^EYmwJ-0l>zV9d+|klm4={Y) z*W!Yjj=IbG@|SjAraithu`Ax{?U>iHA;s!A>83*x;)#SP=IPjFPt$=3oie~7SBFbP z1EBI4*``SG*0pOtyml?7#@EZHHp#ekCf=F&C_BCzZuVZbANzy*36pqed8YT~0O+Pd zp;a;Z;xn|(+PQ#kAvFmper~i1 zj-lhMsoB4oC;HT4wIm&4#6<=W_>dYFQ^UBPmMBad=fxf}R`5W7Cr#pk^(vz&0lzKL zUI3E?-2iZx%at5eWKJq?>dGi)I<>vU=EzB0m;TsZk)Nree%lXSBU>GQNDwcNdHwZMf8@Iy@;48x*&SwB? z11jnbLnW)HdN+XQ-N}2wARcAhiO z3hBF~dHX6dk*tdmV_+v`C&sMZRMOmGWSbKZ70xcWCN3Jd;W7IqG#y5g5@JicRaaOd$28}8gW zG_>P*e0}exBa@RyHud&xI-Zp$D-Ew!|_Do zn;`r4_)h8FnD_%MYi-(EZOhX}5I`1BJDei#uO=wJWA=0sl$N=IQZ5!m1sFm`)SxmQ zSE~4FH}oEGt4RV6TUL@z2oPSAB|??I?5CI) z=v%ZN-JbWrcU(>plw*FhiL{q=Bk69^Ye@uxOM;iYYOKxJ4kS9G0MjG|l~w4>J4h!< zR{SjhqPi(`IH^eHL|-PE%;N3tdr9Wrx1cN3-C=L7D*3H-znKE5eX>K!#*o00GS!Wd z@_7Ly;)ztlP({m%&c*E`OKTFt>EYb5@t5V59c&-(X^5X+(b6)|-PBc+ANN%*ueoVk zb7A3RTvwe2qbIkT9bKWP+0;B9M`u!xw7|DZ@jI_ezNJr!3 z2>F@`a>b8HPX=quFF6qtYL2`%!{^}$nIM|H1uRvL#Zk_F1 zOk5J{-&CUD;2Ym~@J+W~|He07|Hdr}M#Fz}hsLeOqoz2PtbeuEB;U1s&Fa%Cz?!na zGb$@dbDAW>K+!u39%IpR=!;}-oy6WG9!>H1%#HC^-tsrgDLWB;KfXC$12I`one%1V zd;`YD2$c!157-A;=n`HNbw*UqBhy;|PLL8#uji5tW?74#>9h7|DjD9g=1gJr|(b(Ki{xxZAQQB1)+XJul`M#GaIa zB0Zy^3oGj!HPaO%l9Tgt9i!W;5thPh4**xRkUfV|>jMcs;2EKA0N)@di?(J;AWg1V zXQR|2FcgmQ&YJwKYS(b2tta;vVA96+Hm<#XLG$7dmwS7G+>My2}2m3Z1UAgk;rMMvAs!yR|Ts}_zAcbvLzaji50jBy)LB>EFS z1(&qNFZZ1K&o%aJ1rtzjbwVxiu+A1#EW3q4dRPQNllwftEGdEB#4*j_3_Buw$qGkg zk3eRvYKBJN);F}t%UJBPTB@_fo`PIPOt9jK!~F~MmGUJl2fN<&Ril|Ru@mj zWr@FzYT`R&H0-0zxH|<9tx=zaKitMMo2s+{5}!%QEtXAqmpl3UAjyKMkAo`Lk#>>}ljQSm55_Kd1=s%S55?5tYz2Ij9KUJ_R^e_iocb$y4o(K-!a z)8)Mz!F?F>WNiB9K zbQ$_8>;?_7Y~3a0cl|c1>8!*DyL~qz-B(6+>0#| zZ2{i7g|&EsBt}AFXZTRQSqeFE8p2XFuSJX-8X+R~u#jAQIR^=`s!=E%X}0tpI=^~Z zn*!Y1h>QndX8?`_po?X0W!4#>m2%KMlUerpf$|M|9Sd*vhBr3^V5tEWoaRgl#p39X z$3>ew3onBU7vSJTS$lKMyz=ytEiL^cxec3_FRCu6U)3?xRMb6&vrN1sH!nYDb^Shy}{fpnSnel|wpQMQ@GRE|1u>|kRnXUfnOKso^8ezgqDDL@x_ zw2*Az6$ViX?xUpRq=!gvBjpJ9v2V?*oj{NZhxn$c-u-IB2K=)YaE@q*elsVU(!<*O z!tzl7(grw3RVfu7g8)^BOVl4`PJM9?NKYW_AZI8=oELfw%jqJ&#%u&DPd?|`JR3dr z#^&aYd-HBcUo85`oh`aWZlIg$I;=IX~$aE?SK2M?!`a?o@>{I5N+V-gD14U#$urnVpKOXTQuhuqm>=00y!p#E~qAVc<|m zvZ0W=R0C#5GqjBqBLZnjJRVo?8dx)SGUq-@QfEy(6}_DxVFl3#bpI*{*jbA_%#YI~ zW38W3Q4t&cS4v8g3=uv|`O_p{Ol*S{n{xp58%xT+9MCEvSVMSWrF)0n>~wi+5vZ#) z!AuWm54&v(s;xu0G#IFtautGMeE98~(iORRwN>TG3AlvH;^gwUsI*cnnv?NdhKvUv z+2{wh$|U0vOXm1W=a?$~K#uL$}9+G9`vKgyMT_jO&d2404OaG2E9#UBQN@S=} zO_J5ni&P@kQMPZAvI!5L@1fe=JKesdySl1-qP=}dPt`S*?d?51r1-miHQl2v&7<8l z{B2%wckQCiuA!kW>Fs-wqjY#V%HOc892VA+(Cjd+GCMm!^KK!X2+h=DlJ!tp8Q@~^ zg<>YfD~bNeP}yxjZRmVd`x2%wO*|LpKcBx6f1PibjEE(Yh()!T-5e#uMs`b#-{eVL zBYdvfwAu6cD{izv$^@0UHejxDya8y@x zCyTx-D(#EnRP=0o&&=mIWzY}>aJXpwUc@eXw>67uP|xSB?hfkyn5!ETA?of{-M7Z? zo_QQr<9Dt*8!^Gxo1XnZ@(S@<(QVY*%?x~liK5ksj=8PAh+XNE!m@9U;(MVo7P?pr zqiS^`T1o7(zrePvBkGCqQ>}_*ts~2mW$$&vg7q-@q2HbQHW61cE~!2+n9;UQ>gy4AJ;XaA^7@FRvm8NLKD9iq^!&C& z7=~mYaDW2aSHs0s!xoEMrV@pHGn{pljeMN+kT$fQ^aS^{Is-%p?+o=l6zZFxo(-hk z7t|+ps%Oa_3_x|Lu-kx&Vb1i$=;@qzTsBp1&H(t;?uVr-6;G*$#^FT{!QDtqxB~4weBbT(dUz%Rk zx~lnmvZ`P$gS!*gB>y7O1>dXnuqyhK=6$l(7u2YfGbUx*M-Zj^h z*Frh%-97= zB$ePIwNl)rBV*1LnI2lHd`iK#S}F1Wf@JSk#`MU@`Y63VuAXZm?od1S^~R&^sdm}x z%fGX#wX-alTt0K@x31b3?})!Q^TdDrN4$FG(hq#(BZ*J%{K}61^H_WZmvR^#n@X%p ze3|vt!8~%=siu?sZ7hO$h7-CxPWV06-9`p7*syM+iG~cFf`gVQ$EHX{B&gN8_WRo6 zH95TCcJqsTi%nM14o2%={><6i98EaPcon@oaBlSjm46_CHYmUZl zz8*U_Q7b2ctVdQaIOu1r!L#6?(x@f=L&YfYIOtwOH1@8J@&MXk0riOElQPSrA2FJR zY;rHHKcQ+gRgVWiG|qCK3xJUxaiuU0HO6;VP-hJru!_IZ-iGkgbix=te*(|${%rIC z>470ywy!H(hdqtS5S#r*b!2Q9~|NOeUS6sWMGvJ(ClA_BTRpCRvhOF`HQ5|i41RQsUq?T*RsIjaP!(Ts1e8<-N zkjGQnU(K#qm+Mmt``Pak<=8&y<{rVh@7>OoXkU-SlRPihQ7fb*0A~Y`Ho(;lPww}U zyJy|@l54}0(VtRRn^n=Py0iv+S%X;V_zoz0PCL|R_wLu2A&09}$~3*KYT^=pmoM_cH>+s}9V`7VZj+H-ww336I-_)35txjm z6@Fe=MtzWq7D8=xMI5~4KjPN4j&3?siBjexP{Q%n2s+=hoya4dyHa*qcNbS>T|jmI zLK&Qrg)(;+W0@S^)p0lfzq{kEyF2cAy8-Se%t80;KPSGE_zL^7HR?~Ebi2#^0u-FU z+9~Ic{Ulr1{<`e*ZpqGp5y;%AEzDZM$#m}Z+8jU>2|jx-c9Kp>A*dXND)852TaOoOca)9#=Pq*%(2vFX!x zzw!iW0+P+0oeBI&2zn*qY3vQ(!O4IT>|2;3#dgoZU1}dPb?jC2j)P z9-47100#pq&ya*nn6k{JE>a=c>$_->0Y?L{Cp74;0NfZ__F!nx!O)}a`a#m&QePaK)~`t07Y-=0`6(xql=vG&9}QyYb-i-+QC}y>@^6Ng}rh z|J!}A$-iJS$2|W3|Gc7-8t3Z+T?`^r9qgmO#qv!MhL&&A$)H*f7V1AdgS`*?&LH2xzxt*c4+O_ zqY-w66qGu|+j=blur{6zfShvNTFj7R*fj<@N^}^{)(~%Vp8H^D;eZ54&Kqew99Him z0l38gCp2}IR^?y=J3T%gzPK#_3eiAgRH<_ivL-$k9$U-kzFdXo`fqsO!z|vKdqfj) z^KKtjd*V z70HD+a|`B`p?3Lu`DecNu28$KH>e4BH4 z-o0|+!s*3r`SWXt`${ z;L!`;yM32?@7};^&jw(d0Iubu%FOqEkon$|Wl>ZM`neYx^DxO~@L2%Q)4T6{CR6@v z|Kh$gYleC>D;r!(&zX^Ntix<$i!;upw%=JICJy(B{2StuFsmsMAYN(`U@OVSM1bXf7T_tDo1*oVw7!y|qZTd3GhuHG3DCSf7nbo9z&4Uq z7g_FO_6^xS;tK&n5V?@*aMJ7{Ie>sN5Ehvi7bV!R(s4KPF^8@jdEQQG_e)ZOArMJF zTYQnB7Fh-@ap=TQNwZK1_Z((WNsltH`paZ^hS-!i_KLrB${Yh@6}85i2ILW1c7{ZU zbSjKl3r_PZk%I7$)4{rw2(ki|b8ZNek-(8tV_hoq-8` zC;)dlhD%`+8^Mc>;KfF|M(|QCoJV?&ELjYu=YB@(8kYWJJxo4&vmfT0t&A4M`qIvIf zz0kqY+lAZ^`gJ9Jxt=7K!uwpm^1#kb(IL_?(*30KJ9{wF%vvA)0pVom{sW==N38pu zt+K-)wuUZva^@MMBb@{2lFXQ%t3_5O&3rVM8=rvH9mSf7)^BRPUC?;qIFF zXM6S~^NI_mdv2XrK0W!tk`*IOYr6{?20B_6HWwc`P|$e#)?3dOHZ5$ODr*~VE3O5{ zwqn1)eSqMoHHOn)iCCioq?Tq(hDcMSq&Q;A+8t(w|JOSFf7s#U=P5l)vSqeSI|~&4 zBIR#CqVm!hLDaPmp9OfHB&+mHdEt9k|C8w`YNdP$XG1GL39yx9A9}=c0}gj>6ApLp z9$7#?aIkb-cn3}TM3fe00qbIB%pL6{nth!DvUIskp-hfOvpl40;KpBaJ4OONs z$J$-Yn_rq!-|eV($0_?Pyn}CdF75VugV~U)D?m<%+_dFd`)0pGeX|LTgKOWDuaBZ8 ztIs4YqGKL#4ikP1W}oN1e@$o%+9KLFPldtQ8i33=-5hdmp}1`p7dC>=7@+TMvqy^P@JYBKnHLm7 zC~A4L)9|(KxvJ*3u(z!1I-^=3UX;0?jsRsmmO#c~Oa+0c zz!Ct(D)^BYRyif(bd}L?U!;F;62WPjqkqpzmubxt)>Y^p_`eKnR%b1eY)Mk<3Tsha za4h#N%3*ajfM#@Wt2)`>$&0S4t)-qcHA%=qtuzj?5Q8HLG>#Bn0)0H3+-`J$lv4A- zZ{9D!$Jdrxyugir<}RuS9O6`1GYMLSneV!&vN?wMNy3)-I<61E$pE~LhT8O=3bh`$ zTB-B~1F{jHYltC>VGwsMwU2Y*0XQ+`{AH7d_M~ao)k?n_x@=i%{pOa&ftrEzXlGUbnk(Cz23pI@TL&7)R<9~dPiz_JyKJ(1ymowaVc}@r zcwYZl-*{t3Ve4?yWmg{>-h5RjQ)oHlPBQY(1Au$`e z&pIH7E!hSl5L%o2ZS8;e?I%av{RzQfNFsJD;| zZ4PRB9Da7?g)dzBBU4e-$i5WLd^qf1?LYA|twNqjIRDB-aRNgPP*8#F>f~Nuz-drE zc`^}_5s)(xbH8(fAC4@FWHJ~+66DEVI%;PvfQJHb0?N$>XHH}cby2|MEEZFn|9i2q>Uy8!{{jJv$dIQ`~u0FJo z%7ql&>HjK6J|&9HcjdgKS29`g=e)Tgd}wVL!JPrv2up8erjZB$C^pSP_|1jv4xz;D z7uC8q)avT^Ekf6%7rJ77ZD_5gqAPB09j#cGep&nKeM>urDmJ#=+`jti;dk{FbuR6$ z$}KFryJMoKYT!@1iVC_`U-r=0)zdwNJ*%&L5THB$qnVH8HZ5M$T{Y0#I@q{)x_8aC zctZ-@WpSYmFJVL^ymT*TO4{u&2$Iy*U7Ed(zjn$yXQ(>hhzsApo%fez-xr<&vkSoq zQ1oZR8qZoK@P*RGpC(BeANWF7r|^|))00aaKb6@<&xSqoZ~*L)rYf`d+-@{}%GD>l z**#Km;{wA{2BUDC|K^4WScb1cw&LE?pmSEr#tR?2! zxXjnPDrBvGM1a;|8bHO(=1b+pvPyj?c0xDfq3n_baEg-FvI7A)VL;gL-XbO|g1hL_ z5HEr=%RNI87h(j-0NpJG5l~Q&%afYeOr8-r%K6!vaVYQvb8bWT%z;yPXj^4U?{%-q znteWpMbEbE2z6xc2ieW~lKZ`_zBj{##axu`Y~06!Ahz4A-OURoHy${=XwRON2gY|z zwzW=P^_`8Iw`||OWy^;A)ici|pPhMPrEX}}t?09tA3S*ZWmjL#UUKV0>&&f>Bg8*~ z{uODR$%fs!r>KLPWGPE|NBZk^$&d0*2Wu*YpZ$lC+qW@)3fL!gv$gn~oeb4;qqpvS zV|TA7{)KnlS?encqo|T1EexxDONTB~KiK^h(Oa0we=;vW@nsq~l=vfwb-Yc; zIh#+YItx`sTlsPu2v(&w6sH45HGPGeesjnv3BYF!aJ7_6GkeZPf=Fvr8;n0>7UE(6 z$`?#e6pyVA{zJ@io1G-oj0LLTAtN3jtUQ1^QZLCg3h#4IB$t@0UA@Re_#&T$?DdPD zvd-0GBsdKy=m?*_%1wy86gfkYkTttcXLxoo-ls@5K&!3uvT-Xh_a~~jK5*4?DYMBv z8GtJsfN2mw1&Lsx)b7{{d^(}MHNvvA1$7g0x_UcBxWUtTLOyX#mZt*{e!G4{-|5y! z3Sy|BLMaXv-u@_aZ{hABdCy#nn+Z^qk=WeHrq$^}x5Kz=5Ui7Tx!UE!o8oZdtpxNb z>)tLffdM4G-H)_Va$tp z`7?*6Z(q6To;`~e@408=%G;;oKb-mUkA4(SzHkdV(U#`ryO&8f+OmB26{8DA4%~nF zrn2yHz> zk_C-4iilEZn@$$dqpDEC7Hc2=2mMG$4iemGwVAek-R%lh%4E*Ha3R>a5S(vdjfDY@Sl4E zustxMhXQcKod+eY^e4n)Y)`BCfdCw{!!`5pKmZ*3ul|L2;=Nq( z`fR7HcY55-V-S$OdvV7O*>MI@sw4y^N$oOGYSxd&q^RajgA{cjZp~i$)|I?|=6&g* z@tP~w<*&bN-=Ui7mtQimcdD&@)xL?wWurX>MSY9L8-})yw|wiy+85?c&0M}^+tw|c zHgEme#Jb+%&dur3vEd~>Yxj?jUA4NasJ^SNwyVCladgvA%iC`qTekPg?R&10tj;sUQ?bXpkC$9ww$*`Yc6fg>ybV{zi@d-vO% zw3X#2x_@tY^I5&AnJ3Pdy$BG+v;R0-65kG=k&gR61yh(KgxT)|eWLb~GANpu;Q?TW z+1zj0iaXJpD=)sm1Z(`Q&3KNtNT}B`N2qtvRW=@F8GEeQf?T!%PH~ZC1PN7CSe{x@ zP3?*yQ^&|jJAKlfPvxMTi^MV)i64=y)X_ukNe%+I685iG%j`BzhsSprpylyEC^!M2 z(5XzLg6fsP)%dquBt*(eKSOAO6rSMR9!5O2WO1@TM%q?^x_De_hWPeWQAKlqbLIRu z<-To4ZbQ1QsHkY7c-z&f19`cvi&nIkB|bYozqEU5aLEfl=~>cIHd(kko?Wt{dwCxd zsX4KGqu~RKqj$MDqQv&q8R`G|tp@y~;AC-yg`B?ePz3(26h(~XBS_9AcOzr^0lFYmbF2F9K??xKzV z;@cR@J|gS^Q8_v8CD;#w=gI8o#hkD85o?85Z(S0n(}RV>P&;-0aE{pK&`X6@nWS?+ zrmgCkPN6ank5k>FHRHaGpSte4-b*h9O+z>QCr*5URT$im>TKq9xka*m$i-WZfI?7 zsBdl6+PW&SGyYiOGx!_#fx~p_4Y!ZKNFaWmPVwBYcmbT0Um`TWJVl%*Meq|!v9#=t zZJQkGn-ts5$wkpeoEAqjCBxcW(0;CAP%{*jYwi+9IOKC%zz?&JlL)$kGhqcZ5{xXV zRR|j*X`T*$xiBobQ7_3q&Sxl%c*%&T01WMG!pPVTPKrwGKU&RqI8h1t_VR3kl-L*J z$a~Rk0GkRsdea5E4WP2wZUbn~x7z>`J1@EpfN`IQeiZ+e#q>f$X%4e4Yyw-EwQAwH z{%Yo)_&!D3*E~@^QD^0mPS^%luA!U@Urf}^q~qu8#W?Cu^hb{%+sciWI;tthU`4ny zG{-q0;9HMgO=RTat~unFLvt!H46mtb@843>-gbTB_g_}DGj9i9@1yRAU%c*lk)%eU zZhvaNsBXnOtB~pW=&rTfpBO{>nwkkLe^4{4+!QcXJ1Lhi|NKYkz!=Z|kuO+ln#UZ)t0xMI;Gr z^(p|H1L^XdbZuDYn11XyhdCuoqi?M z%v})Q&n}D50bO4d#U~TGV&re(hShrUy4q`yH2F~#LRk}g< z86k`+LK>eFQMk|x?-=C78l4w=I!d24)nvFr4= zL5*#ZvXaJXN?VmtYTA97AS>>(mB9Fy62oL%;!0d%87i@fy0()x0q=LE_uIqmWE^y* z50ViE>mmmpAE`fU8Q-PDDF?@liDOnE@Aif;ruIlRf3K^JyhL8)jjULJeasTQZLEg z`;y7$sX(ESsX$dPqH4m6ll-?v$rvSLG<-`|hxVd+Ld{h_P?<9lJLau|m!bh*-qsaeF%99yZxfN8A zI>RV_{-RNo=R*yt+l``{Y=fp->%0u`3t>3E;D#d^J!!^ouV&)I8-ZijpsIGS4k_7|n77=i;qGP0G`PxlWO+#(vFC2WSr!$Yg z)KlTt;%G};k4z&c`kx?&LCD*FFxSnbdr4BRaqN;B*q!Y;(Fw#4S>zz``>n(} zJVyMTil`;=kO;Q7W6T(JX3Q5gyw>BX0Gy+^ zh}r?tN|BQzREOY$HK_CP2576aZf0fRW3J{9tg?_`mFO$A=DPu`s<${G2X%E3*KVRW zPz|{N{w4xB$9VnZ#~hFY7AvO)xr|fxEdYISCn8|hm(KHk%_EMC&EcwPU3 zjbklMBkTGWZX9X)?9|HD)03C1X9#lQsd$jMad~v)jK;*T^V4CRwruQqmANNFB5N%hQJ_^*ip zw18h0YPJHmy7tjjJh*7%*-x!pboa*i(Zh%1iobvP%c-a~o`|dIPi?$T%(_|TNQ>YE zsWw%o`EizH3)h0pYG&l+V$)g*pvbfK*h0|iu?tEou3v6&iZY7iEvmFeE7Y70kz%rn z7!(-eAhG7$Gkd+)Ok?)pKzdM1Hp|It)H3mth zKA;-g@^bE|VEdW&O+v*A_69nfunR0)z>*)!d;8Si7waf*lN zkB%rfXsVrC1m#2a>avcO>azBcE!VBA`_%lq^S5uV?Hwh|e}2iTrWNB~TDvYDTbdqf zlWh}AC=EVcz`WFOPs6{;0+anEeZW%y_A%jg09m#w)|8Pyi4XnbDPFO1PX*xS0Gtj$ zsRJZMtl&-hteK0HOO${-{%tp@B4 zz;OrUfMHy0VHRpC>I8L+lBP*kL&gfk+i6K1tq( zh5+??8Lzu57wro&r?9da5A_SaX%c75Dr%%=Lh@{`=G}8NuJ4?f?igKByQp;0!gR8H z@z|QG&e77AuI`$qj^=pDx=lknS9doy^)ITb7$2)&*k1Xe=BC=F&iV>}-X-Q`+{T*9 ziLfpbr(-MXEFjI&HG#T%jKwDcb^#aQ5a>!ycN5$cNG_}e03T|X>d;jLwo=!YAbALR7qX|by_QEoF3%QE*C9aXc zz;=VY6rGyIn*3RQ*!T_wU>hajCuBFK;8vbkJg!{zamWA};bG@vm??#nqljF$?u+=P z$QTMdOmRiDG?j=VQZ6B_CnXV1$&Ss5h7{9=VyssMw{_R1B!P&zOkOzJEvg=d4f9GiP_L$LbaU-VxFa0^b%8cv^rV zaBv3eSD~E(0uNla7Fjt1Ue16U`ptuRE@!&SneK9?yIe;zm8zzci!><=jL3?WFhW}6 zR)pTuGD-1XiuY3PJzXQUl(dm#3n^%C3;Ml)I@eo&zGro&!}!dtQ};t@6?VG1)6~7t z-uag(pSm-B^J~}oR!dpNzBMZ2?$!@Py@^Z3CL)hhG>>}$r1Z9JvtRVxaYZ8ZPPQ8H zNwL^LDj;}1d8XdI1+*Co=8F=7#WNZ8;&q;e%CdxgKRlJ<5)HWFH)1`G$PD zYk-}^TQT`@k@k0i%BilN@1<3>Tu7-&20Uq2Q(A3Kf$-8`Sr@3^5Z@A+g?SNdrv&;X zRMJhgCJi$hQzHq*SuzZ}=>B8?qUQoUPnsoJRfBp$Rn3lRgCo0DWXSwd7yJYrn=EC%{;JX9pB*{J#j1Bl9Vv$w<9|XRGWYd(UtgWoB;Wz;4aF%u- ze0}Y8iNx;eON%GA9h^9_zHsk`Hw?sy+W$-@ep>s5Wp`}YTe$wnp?5qpUC~-xF+H(& zvaRjfuD48Al(m*lAL+Wb4Nu=h)DmBocn2|Q3Zu$+5-B?~EBUqEE9JCmOsumY6QeWF zYtd4Sn3k`XtchwsYZz?FkCZ8u8hgMiYNbk(I!S6T!FgJJBKq zUW#oVM`3Ezg|2!~A?1n*XXaiuEM1W_L(&<{2*X>xU1;pL*BKPvaZ^@-JuJ92f3iJoCkPVlm^l5k~qa z2{{K5Iyt^wtfaT#ha|d2o(sT~9%`jW0Hq|Bpl}7bLO0LZV~s5twnJU?S9ym>PgKcJ z<+DE|OP~^_l^-&>01FxGr$XXE@t=`H%hsr!io*nWpM=sEQGrMZKs)S{m7JGdU^3P2 zd}hVXvT>FqWO7Gmib~-Usm>%!n)?G0cg(dOF|8&0`Qtp)tCcv*b@cNTfG6MT?-(0B)K&mBi&CjgengyM67@XRhzoDS-(wkPTx^Z(~>&|rZ=%$4WH;p!@ccs~( zk~&0*E$s6`P7D8Ad(`jpr^4oDHM?m)8-NS~I1onWxd5aEI2OYL=fa~Y2T15WpPej6 zE@3`RtoFBddc_TS zRuH{avWE;_1Qgw;s06s~F z9X>Ly=#w|#}}?E+@Em$k+poB5Bw`@4PdP4TxM-1STPKvRX+64l_fbUY+^ zgU4%z8#EQSkSF?HsAo3d65I+qaXh2ta_p$}kb<%+9$%OcFWShqelE){4nk&M=c6c8 z6!fQ_nRe8tp8g1JU4W$?3`6O$R1TX^VJ}$GYIGHp$`(?W0U{+Ctn@&5Rgvo`ln0w! zU}Awg_$!)X#6?mHdwL-zvZpm#qWDP$#lqYReMd32s47mz8z*nvyr6&U%U2)Tl(%#1 zwbvg#yr}Q8vt^5xObD&4UUlQ8ed(PoH}ARn=7QU{{(62%p%jm{M-t0zkKC*E<>$jK zD@Sh?4~iZ+6`Gq1XE!2-M=ViZhFbWr&Dj~q8a+|e_7Uu$-$zna2sMZ;)WNTnOHwT! zU+d^_V)?$AC-&`&m+bo`3+LHqX_;$l^eAmjMlbsm8OZOPy?REPsA6im&B_S?o0SYg zJi!a(i2n&U1ckNp5}Vn1Og_4AA774VXJ(IC8}jA9iNy@lYc}&2Z@UvV^R9p5aLu^< ztXl;dPFoIAK6}7j*+7HL#6=$dbGM^V28e`}S<~JvG^o3v8msaOI~(?$THV&27<}Qe zS9m%R(Nb&^Vy+PO7(*)PD7uAYLz4zD^sk6CHby@V0Ds-1DVHNU5J3m@=A89VfLbxe z0wj*UMfyJJ=Ol=rSf?0aPW(d^T(khpn~NauhDsltY@Mu6z)xa9~@+NSX_fy87p zEGlq700>SN%tF6vco+)P zyNm3dT0|<`LWP4QYo!2Rms@jofvaI(U6R2Gj`uCx_AZ;fPndv7=8{;QhP9-dRIL*E zH|W#y8LNzinsv`2RR*>!gjRha8=tt~7HKs%&UmlLNT5A-5 zl(-CXPIME%J$kIJUJ7uPeyHq!0az>d2H=MQkSB=R?RXw+&1?W-JNA@@F)YkSizil2s@asg^*s{yXZ zqIud(PcYclc7JY>EvJT$M_+_JaO|;E4)Lw6?FAARG{nP+KfZSCPfm|rd)bz^{?V5B zK_ml3Gk3Deeie(Xvo>^IfQyXs62(F`KKezes!_{zZ^QwT_2-<+&0H-Z*4URj0q{sD zHx$aH1*kuf0Ybvgd{k7P>~mr8p9+9<`PL-`yf@$x1DJSTWz1NLxfwpg!Da_mHfwd);GM&p5Xs%l)--HR4*tw$^$9CP?=9 zQQy{#0O$(MnLfKFOy2eYj0T`906%kpNJ|O^Q3?exSLSU2uW?0kqH6(eBZ=5L5wBY$ z+rwU7XMlu?chS02p@sbb)}U!ulOm$~Wz{J_9}!N}fr@)3%D7T?IMKLe<~#ci#Fbaa zZ=Si4#q;X;_n6Uy@#wd~qnAgW3GN&#<2^fdYzh>}rDAgx2=2B(ag{oNwPZN?`?V)D zzo!CaeJHHuObmBx1grq3d9Bv*kXr-Qkwu0rk@rgWtd~p(tz}n@ zAfQXa0Oh_Hz(4lDogf2pbZKELN+$(Nq};oaE?c>e8K9$tZcVkU2SeNMzo_l^hqn7B zC!>#tR-V`PkA+q~>Hu|3x1`tV>k_dv(IemF_k|`u<^c7ml^*$)9s{uUzn7LGET@Lf z3vNS9n)7P7bZvAb(Q?I!shhU+_iwprioXlqws@}$Ku6JGS(zv2rkF0&Dme_&*#8vx<~7nDCmW!`V!@7l|3RrV|pL}CL+M|gh$g802gM{3rV5E*;8|x#i#lZcLUHNMgqbSv2E}Ju#wdQ%5Iskd9 z8L1Md<48CRKBz3nSi`Nfj-X0-e8K%#JJ^rbpDqK!ez*u%X2lTyFE7fX$I@_$10){D z`B!6&rV^i<`Gd0?uSOGidgg^Eo`?%({@}h-rxHWEAJ}!~b^q}n;1tPXzQ?>3AL#f}Do| z^IY$XArPqo;3$kkFe^7+mDEZr#l@s|*!Tg5?Q+>drWg+jGC*4VJ zbC>Hla=LPVz?c`7mi5PcwxZRV1Ft=w&FnuR3qURh#>CFcoFx@=V&<;6^_2%cGPYxR zQ^%6&m3xjXA07YnrxQaZ-D}2{Y+6_ucRn>dF-BmbIrzN_kGWsU&I@iwC!XgV&XDd# z=2+x7yDWfn;n9fz+#HaQMIhBaI~{Ud94>OiJ?O9_w*jZEk&8~mq(o=}6FhZS!iarv z5rAaV)y-t-?(zn^r-f>6FkA@W0%(A2sHL4++ND7pjHG4&xL1JCSPOu16*{Gp>ZC>B z`Je@!0N8IpSP$ODFS{PH$0D_Ho_9ZzN=K|mOv|fS#{R7J06(;yW!8Etj#%4(`M^{5iPa5hh!tz zNx!YC%Fxm~1gOWIA;-0y3z9A%SE+2^QeB*6{u7BCM<%vhKbL4N``>|Pty-{c_=?v0 z;SEbyE*PFmx(;rOPXy9cvwUjRz$OtfHWPy)zB~yY#KAd!Se&^@+!ProkJXX~hVw@c zaoyJLa{;&|06%tsP@Q|px}LFdcV=+(SW+Ngg$Ew799<*AhuyA_qcnx&8GpWVM8OPX z7i*FZY~m=T42O%|UXWbY$pVX6(%Qw6(uR$7(YY_XvGlsAsXJzJsAN-N+%w0b4P`ld zNvNLyHeMckA83%K>b&m|qzdk0yA9BtR$9k* z!>s7?fK1ttNM3j1*nzKn_2?}JZWvkmjc+7|{_N!=zxepj!abT#d@j(_{R6!6P~sUy zyM&wxlbS`T7TwKZjh6&KDr);?=JwK|kh3j#0-X!M(+<#`feXN<3t(!9cBYDl+!F~3 z7Eqrs6_BAA#f@0Nz%jTc+@@8QUr)a7_E1E%Fh^B#OhcIcB3fBSU%I`tr@|6BIE{vG zBa;Ir4?QxH{H6f;O#v8MhHuUl(_HZeLF3llM-0#tr@|F#c5a%Eruu82Wb#<--Z&nB z{s724n97O}^VA{cspCjf7abH9;U0d5$UsGIFGB(t*e4sH^P%{6( z;`ycZ<+b&d)s=a*?ZX|lONP>Jk71r}dOYsz{uDzB#&Htba~fY3o49j)(1YATBpAM4 z85!Qh;m)w?FXEZ!$`_n$%$Pn&Xq-hxYy9~ST>XLgBj^`<;&1PA?YabA))2V7D(;qj zu$Qr9L>QR{yLIT%?T8<3P@rLVtY_v9d>~3UaKN_3FqlJ`GHJ596tdk@ zCsk;zT`L;^t*-F^90`@}rlO-(8Mok=;zGJ`?!b`_BR5`p_dWZHJC-dRT;5i=@9u(= zcf_k^{&`@-a6|Lx`o6e%=CjA{bK{*0?d)T`bK_yR4&cs&ZQVKmI52lXND#Gz7p+mw zwA_k#7V8}QPm4!IrBfCA4t=U|2ZzHjGeb70PFrOwU4k^5g0o?zh-(qW(uMFY zzJhc(=li4EUDeW&*sDhj2o!BT-4XZgZbQq?4RYel+`J_3A&rz|&cPju=~oyb=S_D5 zfA1oR{n1p-*VBA^_p+1Zvnm&870bn=j zD9MQW+JG?*1z=|Yz8HXCxmlHWnq)@`VFL>(zI~&f2=K>K0oK|aR!SZ##kRgyN**gE zkCnnKORoN}Oztm8-~z3>d{$jPtBy0eYJ1QhS?4$$YMW;m`x_Z78QQ(Xl-AbZ#Oa3#Etw3(|cE0VHrOeV^XoPP7+uRL+n z8{TyItKa%oToc!Q^{X>KVR$v9{PPRucz#@Y9*rN;GtJN=26$qxJxL@(_arl$nfZ06 z6?@5#?U0SF+tDWR%Lr39XxHci1PF3~LVU$|x(L@h`_(LtLF1pnF)zVI=rx3YZfKn% zAS=)3TlWdMYqxC&I7pJT-cZ2L!;@TqYLebg-Wn&X+DA2v@h_e{@Z@!GeJdN}E5G?o zJn~Qf!(OjA6{hCd064No6AoAok| z-X4Ip0T91y1LrYaj)n~?kByL!${K(x^+RKO8-SHPVSrn^HV+=13HS24zSJLpn`|D) zc{l*C3c%g~7|wJ2s$>yRShw4JU2hKM23amIp^?mP5gl*EK{;b7ojmifXljjHN8@kI zd^66OxhC$P`7cJlXP4&#O<$6H1!uteXkp?n=E$TK4vAh15wTfGHWudqd~UEpp^vj+ zgorfahAP9=%w73*xkg6N=5E>G?R%|zd`S#%3&|PnNoeiHS}}GiIRA+-*Rh5=j^stm)2z%Sq&9 zE38dFHy-wbYz|wCa@{fDAwy*hqa$?yOM*T{*BtvY9(Z5K>0+SmQFqkofF5YEw!ugsz|sI@WPC3sA~UnFB=^I4<TM5QI&R$bvDx;yfkJRa*O!fyI9guF8q-5uM3saQwnQ`w~0AapjDjlVkyuhAn>1 zfItOb!k|lac-zZitQ7xz=AHZE9PMbejTEn6_OqFl`%9MpENV&q8#&RJf3W4P?(f!- z+3(Ee&U=0GZ~4tOQ!fAUUh?y^aKH0D#Pe^?d%e}OE ztqJ15CD%voiR)P9AB%e9oT!gf8^0f0e#N!^b~F*c7d`Y>xT%YXQHd`{lks&?TcR*p zoZxQ4#NhwW)|&=LdFAPz3DrHdxNLA$`xaGG-Cbr!0wfXyLV#nMMSuiKr6jZxp6CxV zF%iW0M%cM~+|C{;a z?7s;#&iX9S_>JWn+xk2GH=w_7{ICD*()v5J{|5qdW?v8Nn4Jjx**AW!V`WjACl|H3>UGq3y*9>KUr}F!OjoquDF;-xWHizX@!bbujRgS>eF< z6pQLv?`yv|0^gl=OMS#I)dv1T?>G9>k#7ZR_21dEuBm_H*#9mNob_wH@%X7?_#d>b zLmEhaC$MAIOMykRjt1IhYr0Rh5)aN+y3KA;+!TA3?bdHT4*XBEDg!^9wKnj5pU3P_ zVCU>dbQAPLX;dLU{!(|g{sX^VHv7LQR=)}?{KkLOG5$>R0z2maoqyl>+nF!X!5aL@ zKWVT){}xJzJNoaR&;Er*8vd&W*5Ob8%{s5|(p#IG(&114SqDuVta#0J%>R4;zVTOz zlXZ{=fBH`v+^c{0NrzwQ-ydiHdEm$YO#|!jr~euQo3)<@t;3)GvktSjN@xF9Uh{se z?VoAljBo7MHsl{`_}~0u&Hm?^-=O{Fz^+;Tw@~k1&kgLAhu6<;lBYdYs;g4x#c-f} z*8in^xlE2MnDq~Vs#(Fn^4UiM>;LRjVBxIIf%|4{QBGy$7j+Y6tyT;+OON@|sZ*ZQ zcNS(nrCj+Suz1!k{R``F|BLP_?~-S`0xR_2vRVIUV7b=)$?X3}=l2W6=-&nEX8%yJ z{*Qq=eP^d`*3b3-x9k7!SDp5e|IPfHJYT2vzBT(L&13bys+`l`|1fiR*1!GN@(=a9 z86DS6y$Se#1h&jx75E>%u|?${>v->~_IV>P=NtOXtP8FuU60%qmo@*L-qTt4vAgaw zcg1^WlHz?c?}~FM&z-rg@&hv;h(DP5Oni{P&Y!uV^2(VH#mzIHh+Ajg7q`J$xMSuc zEor3O1Y2f4)slTI?_moO7=wAV2bq*vit(;JOeMn zOYm9NybQ0h{%h?0hWM?3&-dGb`)B-Q*#kQAZ%e_q#2+dGdhSqaep_$F`gyX2EMG)< zFT{LCUKsuVG(nDQ}*6TkCI~`JK28 z*23*3gKV6xV5+_bKDRT5jV*5`pApU;y&e_|Jp&hOJ{wb za?R@;Wcdqh?J7&I@vE0u=e3!iX`LJ59FBGlN2__ybhLVINc)=O?@)@GAYnOwtMzz>nwGOw$t%`tNN`|#?2g@7SS_n3> zJWRQXax>+YnP2O-t*Xc72D%ihxq%+`9)VF9gK?OEy{dudDtbPi37CW_n1&gcg;N~u zG)Gm0C3pxPhDYFI@F+)k3?7Fk;7Ry|{5n_8_t$@(l1t|Xp5|Om@z>Mv3_J_Z!SnC} zXZj4h2rt3s*uwK1?G@I1QO=yJ2Z9{umlPSzEUPu|S3CZpI0w$v`u8i#J`?9lM}5mj z?z&$-ba_3jQ4Mgva>QHMq%62U@Q~EJKk%?xmirZLuNi?+7=v+`fKzPYD!j&aZfWn| z)A4*JeplQ4zW7I7V}D1~cT!ZVJfI9RzoT~W0Uh%lagKhgj}_^+`lbqht=1MEP^Nq= zZqRlf&=Gzix^90U@bCHS6o0)6ud$Bns|NzNv^5PoYmfTSoR4X38z9+vh2p{zdFk^yUQ~)+?yf4o|?7@M(_x6y?+K z3_J_Z!SnC}=k*M{2rt3s*uwK1+ZEP)kvRDJVV-iwakwP~e<-(nC|1cQKa?vz7pLG= zQSbCgwI50Gcf~ny?#%C1p0DlyNOhps*#LW35`j?|gK?OE*I4tGw)0nN6F;}|+WUjb zjxWS-!78q?wK#eMwU0hJ?aC@mjiXZtoBY<&T8-86gw6F`Koh17x(Gh=La5PJNx<71Wdvd zOv4P!!by%Z2lKE1r#RY!obOTAJO+=$6YwN_O8x5jfm4)E!!z(KJO|Ii3mpG5@FKhf zpXDqr!{=G^3cSiOygKt=wEfp+{z1G>`3B|NobMf}vp^nuTf9e07RVLmJk{X~q|_a8 zjjkOQ$e(YDuE7>aky%EGUcC9eu2Nf2(Pjiw*m{4*WTA1>9SB)wO7OkBsF-*= z`_$`ONRMtIJ-USf_vjV|+@o6`t2hYO`9OpCeBD@5jWed;2%g}wrg@G&ZWg__sysa}@B*(rf z-mBj(Qmy#0I9L6LMe5<-73ayNi{xG}nJ+CCsh<2ww1@Szb~$H}JnS{st1ew655FO9 zP&>Pb7I~38{5zF5v(6SB&mt-1Eo_6ea0lGUU+Z8!+yz|=EkeOXY9C#0WPK~RD9}XN z3N8w?Q1(^%B3&c+XuBvsEMF~BE9oT>7=q!DDo0ZUQ@laDDXOp-=KVx@-5WAqdI)CGVW9H0rinI|E=n% z#k4Prm2ob+ebL;u^2TE6Xx75*^21^>Zn5^Qx<=Amy{x%UN4{9C$z9Q{$zo-n>DFYivd?sDvRK(?x;0tM71Ls6pO5VrJPuF5 zlkf@kG8ZfFe7;X}Jf~QG8lHh?;W>C7Uf?*NffwN==<%GzQo(2KQJuvBw;+p^cP_hr zTO4?qsJ;Sk>%5j|?Cvx19{q2La`2)!2hN?jrt$;oU+IM+MMKZ5!ym&3)nioMfWI{$^$NM zgSBwGa$%`F;J><$u{7X5#!`8}bRT1>`h=$Y7)#{@vytDrr?FJEvA5~|#!`9UQ?XS? zzEpYbvd2i5Dz85lyI6jZ&zcnLnsk+@H?R5|OTa-U?WBJ8txN$V_A+&&jqYRNKXkjq|#aPqHlFKFP9x`y|WMyYrTR z3ZH;a!lzX8ETf)WrkHz8_fM7u+&@_saQ|dk!2OeD0ryXq1uk&R&%lfD67==>GU~}? zin+@_gYKU!Q$6Xkcu6cH@?}K6jL4S}`7$D3M&!$gd>N51Bl2ZLUbB8^n`QE?>Bwu^ z54P#Zml1j0UDF=Rh3lGX;%N1uI!!dXq zo`5Ie<9dX2xmwJ5;*-kr<%;kh#Z&zCG&}>(!gKIEyudL(124i$@L7)hGJKvRxx)G{ z5FhurmIvJ9S{}H~dEL=tGAlH$a#Z{lya(Pl^MaP#uUuQ9F_!nm2WFlZf23cn&=t_z z;zI3lg|sj$VGvf$Jf|gV6|oh%Cd!M|>ZPpE)zCq4)66CDA@u`SNU6`oZLk)4yk&)y z`ciCUNfX?|mfd=;kW$ygcD4H}q|`a_VScqwXSza4-4^$={sc_I6imYm%)&{IGY9jq z0H-)w-)mSQ9etd~;Bj~Yo`k31X?O;nh3DXT=r(tSa=~<)yF$5OKFjf6hR<_6S6Kfl zdw&@fUV*R99Mk%*!Rzn_yvt6;CGbKD>e4wCErsXt(0nBvOsP3N@-^< zf{Wo2xD+mfWw0DBhbv$Otc0sz5Uz$EkzOhF?~3c>oRw1F$Ka9ql~UjH&~KI-SE?5M zOx!9ru9OGNTDV=_SSb&DBJO0JI>ltAYEg3+OLoHsmV{sZ(g*wD033uva2SrjQ8)(2;RH;=6imYm%)&_`lY@C! zfWGgrGH`%(4id3xj=Ts<@DMx`t2hT%~6RwnpO^*|yVTgk|6rLMI<(-L0=RO%Y)9np8VDjEB#)YzA|P^0^Il^Xl{ zP~61&9>1-WnqP>%=BkvMrpLZ2rKahttxD-=`ii?!I-0)Ps^n^`QaXBx$G$41qnCT^ zt5Q0;?6I#(>FBb@bt^UY<)ii3S0$skl^XlvUN?By(`IE#a9XPP4~!V)|L z55ptyG3c?cN@;C+?5k2*n;!eBl-52%UoTfmYtv(2mD1XO_1IUXw07BJUzO6@^w?LW zv^G8VRVl4~b{<=ygXD6MTn>`UL2@}rE(giwAh{gm zUQCc&4wB13aydvY2g&6ixf~>ygXD6MTn>`UL2@}rE(giwAh{eQmxJVTkX#Ou%RzEE zNG=D-_E(~FIY=%C$>kuq93+>6ygXD6MTn>`U zL2@}rE(giwAh{eQmxJVTkX#Ou%RzEENG=CeZ~NGs%RzEEsFu`a=W zVwKciEtS6(YZRZ=^u||9O)qiHyjp60AZ~-T(D#p4(<@tzrmN9(HJYwQ)78@SuGVp$ zt|m`cOH*&hdAeGfy6ik%trpgFe{8i{SeJcwX|-Bdmmk*guhuB&$Kn)6c#tL29AOcb z;30Sz9)XX+qwMP#JPuF5lh8HrYE)Z|YO7IgwN&#Sou{j%nveE0JOj_dbMQQLk7%`2 zGu+tWlPIt+FG(M*W#jM7M)$i1Qli z!!^{0Yl!n2a%YX=>~%cqxJD5+J<_;F`QokZQEj|N5%v<_M_8i>e=2scU*Anwqdf8w zkC?5Ilf92bw1iiYVLX$>{f8fv69)JSV|rrwUn4Ah(Cr8 z>ItqY)mMKn`r5OKYtJgxU4Ky7SD;lI=QkhHlR8!M^A*uit&*QliQ8Z;+^*}CD#iIJ z(fy4o#rX@-qhwXYxr#VfDbB~WBm^7zZJ2Ts*>eJ)B(xMqv!bVFLEfoY!xCg8~#zg8LdnRu_VY^@w<&Q-0rR=&C;u9WN6s-^o{ zbdP1N{NwfAV_8d&WvyB_m$%C^YvmuWv9Wa-*aE9ob@)_*uHDUwepYI37xZR)#~|I5g3Ir7>5bi3;itUT6#EZ>EWzZ zd*|)DhqG4do9^MPReNW;hqG4go#`IVTD5nkdpK)VOPD`}PY|UiDZA!eEA@R;?%}Le z&1t%avsUe$=^oBnwRh$P)_(?GgqPs6oa1wB=Q8D=vA%mdYgMb5*VwP?mbGf{yyPal zCF%pW@E&QcFD=Lkni5ex-gVO2<+&Q=TgOwNn&(U-Me9`C{6YM&qO?vuSg$i*Pgbl` z4fCnE6s}b5v`#gQmjvNMdLn(D9P&$XtHx*6$s1-Z^xeaC^2X1_2KEwyjr=uCxruT! zW#1)SryBc@Vk=A96peMNJw6gUIHOM31s`Vb`&jc4Ic;6wQTEuwkw;(@#$X&KU@!aK z&-xQE2~#i)GcXJNl*>B#$7foEC3pxPhDYFI@F?3q29LuN@FaX(W4Y_pH(oA2sk=(+ zRBw38PjfD(Sm!i61JA;9@I1W0n$N(C@DhBM$UH~+GUewv{ww_IMb&}p)E?O(FXM+- zplghE@{f57-ewEG=C^nB3|uv%(A8?c?pOIi0#`&)pF6V#BHz^`VLyPT;#vj$@A5!Tg(PM zLsG5w$ZTZIFy$u7&6Hc%`yQQdwH)<^==){Wa+KM@-rd)#R(s?nesZ!}?a?2^9)25v zQ5b`9n1H=AuWHTxY-a){VG5>U24e&oH7=@FE#&jEi>g%%nRZdNY9aF|=W+}l zhbQ1k__(gBs#Oa)8un7PytGjC9p`F!$&t~UhT>^>2A+lI;Cbk`398krG5t0{wR$zC z`)}3i)p$GZzg4SO<9$8Pxm@A5FA@hoom(wOd7W3_>p0{lyoEz<6IDNyIS(k zC!*g~Subyxe&1xhTw$)!zSgS`^Vi~5d1<{|Vb;R!isX8^Lhsc{eJ^i&hbQ1k__&_jUN0?tj!){@j`h;wkK!r*dK#XAXW=<`9{OI!dZ}RgUdDQkr~mxKc-0Bh|bl2sbGL zHK_W+8Z`1yqbxQX`D>VR6Xj;gEqZ#PM(x6{#nze2 zVjE}Ct{kaR7T*;8tZ9w1_$|?QtZJmPkNFXf>QVWyMj7qnkH9F5!8lC7UXE%%znXwa zn1X4TfmwJEPIIP3Sb~S(VR!^S29I)H$KY{z0-l6^*QQ4PSu8%O5zHFeg&O6u<8z92 zPQx?sEIbF#!wbac8F&$1f_{p%M!D=b_*vE(WwBMe!mnOb->*jPf}{5`K6wScPMmMT zTktkf{WaV1Q_CCVt6zz}N47y;x+eZWwZR7Y!lrVUA&+oU=g=`4@3N$2I|zFa^^v1GDg;GJ1pRa38<#?{8qldjlih8&rpTiSO@k zV8nZaY7C#@8WnxAIbz?JC+sc&_z@Y@%O+e<{|Wz>8H-X=b-Pc};5cfO48ca0hgAn|RGshjn_1q%7WU|@H%k3qh;6DLHcEYOxr1Zq zWJ#CWtc|J-eB==rg)tb13D_%FZOhQ4TTv=Fvtu#Ak5~9)~C3N%*+lvKASYM`b)8f@*Z93Y?5BT5!-cko0P5p zB<|<86EF!=Fby*>3n$rf4(4G2PO<%G+1h3JJnLU&`D=>dCXEx`)C>=P197w3&Cf)? zhq#$hsm;1~{I<&9W66(Hv+3<{`G2$SAm0%esx8~BJIF3ChD+d5mM^1R2Fu}cxB~hr zd$ZoO^=~U#e--5*<<*q^M8{^0RX!oEl_xhVdOs7Zb>CsLqW74%iL&o2ZPxYp*Ww=O zwOR4}Q1o-Nn-$OZML)g2Sv8*byPv)Ev6p^000-d^9EKxs6pq1hIKdW@Fa^^v1G8|F zqsqZNEWjy_`~cfIsQ%<;^>ciLehXl;Y9~k4Pit(}IHAw+RrLWjYjpR#c%AYM%6HU? zZ9%&&^eVTY-4<#0hL+zW4{uTb=W}t6wA&&b-xI&j@_BOm7OD9=(c>Olr0ECZLe^hI zc`;l9m$G~rfS9<_L#VVv)IIvhoJS{B7MISeJ!&^`g%!+wB90>KNI}~;1+4^vwM_vJWjHOagr^% zJK(a%Nw(Y)9;aOQ7_u`dt_VG zi#Gk7$rioSYWg{oEqbTboZ@^BupN)pY>^*)E|=l+{PqR@dX+V=5gFG@TjY&%;%hUf z#n)MKoh3I|a+4*uh{Lbp9p$p7xIpV~l^?v$ zBFc;566jHpt@^gF*C~VLa5-E7eRp`P{NQywa z9D$>7430yOjck>srpHFMN>kHgBU`1ZImy2Kp7K`SQ{KvZ%3GzWkNg1JIm)pegU8_s zcoIHElul7T4bQ-{@Ekl3J({sq{T4^y1y*KAxE!v4E2YjhsqA(9HpDim?6Tj9 z*d~=-ULzlFQ%&wAe*bQpRQ^izn=;#^^4H=9{@TM)MPL-hU>qi(-+I_4WxeHoH~nwHe6PX0*rmA<}S3=rkL5p6kFHjVd@U|u{e_B8trYQg z7Q-cQDa)5pE`#N8Ia~o(O6yuF;@?)X{wm5r%Bv}_fmOP;szs4nDe|hy)pAR%>S1r8 zX68w81LaNX`P3>0%{KL#YE|p{XglGIIfxWu0rB^{cvW ztyMN%6t7dhLD^3zZI{09iTA2Uv|Y96JK`M5zMHUJHR`A0gQ}6XOWD`O1uR(v7sDlR z87zb4a5-E7SF+6t%B$dNxK?$`cGTIfD~PXE_Oq1RRX3V`mU6qUCI3}yr0l0Cx9jTf zTjD;Bs)wVBz$lEtI84Ak_SFvu;2<1=!*B$S!ZA1wCpp3#%)?bg{>yCrzCos3` zj)UnZFt@AbG_CA*UFln|SK#YJ_$IssZ!11Ks3&*m3Ee+ed9J>GutVAUd+{ggjqITQ z)R)PW#XFRz=3=-6>Z|u!QU=R)<+4NHnembpaHVRG9m-HISp`?aD&5c8p?v&YT&Gy= zP(J#rXzO8(dJ8+KCwFL+>4z%U>s_H8()2Gy*PJ_)eWq*99qQ+pt~qz8pJVp1mwq?^ z2jLJLh9htkj=^y_$x-EC9v0vfM|FU8{QS}m)r3Ay*MvLNKl!crn#QkoD1%(Sq4G}V zDbk1jwB}C5`7_batnO5wf`rV z%1&LUcss5$cS>=`!HVyc;+MqNW-f@=Dc_)cN1E1=Q+3kuuFCFv)X~GNqwi5C9lgYT zk2+mVe=54~QAgjSF5tdLo$|EhI*p}x3+`3c(W|VZS6N4|vW{M59ajo+# zAFcZyb&9{Y;C^78;_u~-zs8KTq@D=Z6XALyTu+4SiEup;t|!9vM7W*^*AwA-B3w^| z>xpnZ5w0h~^+dRy2-g$gdLmp;gzJfLJrS-a!u3SBo(R_y;d&xmuR7|kj?)pYR~=xpnZ5w0h~^+dRy2-g$gdLmp;gzJfLJrS-a!u3SBo(R_y;d&xmPlW4yJ&xR(f;nD{oO_TyNmXB7wzvZwZA@wWAHdU0Z+oG)Pvon_Sfs2hG*be zcn+S2&%-P5D#!3LF?Ww$V>y&R$zOA#~t(M{o(ca#zmcr$Gl)t;>@H?VM zqIS#SE_)k*M8ryXldr-EzC>k*M8rySLzxsNHhA>5-`2a=Yn~sNHhAk30wS zumGnxevd@$mdZZbW6v`!%AaY8`vVR12O8)PG|(Stpg+(+ zf1rW>Km+}O26^BUt?&Lo1O0&pdBA1&2O8u7m)##|kOxfn2O8u7)9pwD{ecGh0}b+k zm%BgEAP>0g{y+o$fd)C@ZI#_0Xpj?bitZ0I$Pb4__Xis24>ZspXrMpPK!2ct{y>AA za98WNKhQvbpn?8C1O0&p)s0_ix%&eRsvAxB2O3m2`gq(QXpmb>_Xir}7SsKK2D!y_ zf1p8bG2I_%kXuam2O8uS)BS-4`U4I02O8uSFL8gML2fbKA81hBXu3bppt{l9aettJ z{y+o$fd={m4fF>Z=nphdTQ<-iXrMpPK!2b?J-`e4t@{HZbPu7s=1x`ILg*es_Yk^= z&^?6iA#@L+dkEb_=pI7%5W0uZJ%sKdbPu6>2;D>I9zypJx`)s`gzh19521Sq-9zXe zLiZ55htNHQ?jdv!p?e73L+Bnt_Yk^=&^?6iA#@L+dkEb_=pI7%5W0uZJ%sKdbPu6> z2;D>I9zypJx`)s`gzh19521Sq-9zXeLiZ55htNHQ?jdv!p?e73L+Bnt_Yk^=&^?6i zA#@L+dkEb_=pI7%5W0uZJ%sKdbPu6>2;D>I-YCW2*H@H1LeeP3UH*=);~J&-yW;oM zrZj4V#R5wcZ4@8etH%fPxJyP8$-A#{FH%fPxJyP8$-A#{FH%fQY zBh`)4-DQtdH%fPxgOoi|-6-8Z6n*!hQM$XlPIt*0rTcYpy++;|rTa0_Bh`)Q-YDH~ zsO*vIM(O^g=#lD1YW_xznRv?{scvMXx=|kRd3mI|QBLsL`H8+pIl=Tub)%eMdZfBh zPVmusq`FZ~Fg;S;C?}X6scw`LOpjDI$_b`NsvG45(<9Z5a)RlR>P9)i^hkB1oM3vS zx{=;dBfX0h;6l zm*;7eph@cgR`j)GlhprM^xcXksqeC{C7Yza>1)X*sqeDKv74m6>1)X*sc*Uu&?NO; z_T7pmsqeC{C7Yza%WKp=Hc9;>;###|O;Z1tVzp`meSKR#Z<6}w#SN^#NxiHlss9Vn z_oSMnrjORwm`zgC^c7H()HHns)Fd^%M~`neNlnw&m`zgC^fhLa)HHpK*(5bhUt=~& zP1DzyO;XeJor@-^Y5LAZlhiaPIsP2X!vdV*_;mS1D}s~Q_@l4`Gt z*D2qid`I=FW`0+uG}D4NYjpGtmHid&W{r-z>~9P<>#ec3#Rrs4%~JCv@h5t+y; z?}#2RZI-5=i2jmuv(z+~K!3xzSvs2K(BE)wmX4<11!$IzF0X>CVU>C>%~I_PaUDyl zDX&-mty!x1s9cjbORryvn^k)^t8ee^_&v2|jj5V`FQZx4WiB_thoy3}`tv?(kEu3G zU(;i%&C=KOm};~1HT(EgKlIm|o29Hd1pW2qW+`j>>&?wl)*Oc(Q*BlbnjTYaRt}m| z9KXNM+^nZBeB?z~f`{N?cmzHMkFx$TcpUmk?`EF#Zq~@^EtOBPw6q6u=ll2y6;hhKN0;c&^?OhAH=P? zf3Zi|XV$_-*aRO|U9?Ae_o>*&Hv8cK9E3w~7>>YEI0na|N4EDUlBP$t_b8I4zeKu6 zk@S%tWsk?;ad-lrguaKnN15W|JPpslv+x`|53fLf-E@ysaD-n|F6@yCF5jShTW8ct ztJg}ar+J52;#RMfRm5gYm)oZ2IYo*m|B_mpC^;&85T50uKY4uuZ^;&85 zT50uK$%s~3y;d@!l~%8nRm5gYm)oZ2IYo*m|rPXUyM!c!xbgS1&tJg}a z*Gj9`N~_mOtJg}a*Gj9`O4hW}>b279wbJUf((1L+>b279wbJUf((1L+>b279wURZh zWKAns(@NH~k~OVlO)ITltF(Sk$L3bARa%>F^;)I%$D&)kR$9GQWsR4+)oYbruZwQ= zT50uKrI*WY_1dJ@hobAQHd?(l+PgNjcfZvVw|8x{bZt`bA60%({rNWO_)F2fmo^k^ zL%}u_Y(u*?v};4VHneL)yEbX}mVV_POB<@Sp;w!fI;kaVmFaC{R-2UaI_q_JsZC0~ zCT>t|)+UW^iksDNaU=`rYa_ zX==I;(}tRDsM&^^ZK&CXnr*1rhMH}t*@l{JQp(4lgLznhQyjmQYEw(+BlPz%+BAk~ z9)gGA5$Nw@v?+gm7RTUmcmke;Podo@%BSHOcov?6=iwFjB5}CNkz6B^uc~*~CT}>Z zZsXeI5HGpG61Q<}db{KeO&jZHZ`$b{waX{(sXRy5KJD_!+u~pF*Liw+zg<3gU3^e` zY?n`dE4oM2E}xk05w+7JYL`!3c8{o?9#Ok|;<9^0?efVxqI*Q`@`>plQM-I{T67KE zE}!@q?2~r+axLrPZQ+!B0fp+=iUqz30wlmtnq)J`v`onBD8yy0VZjonU--A;|&PL18J zEcUOaIocvD!9(ycJOUqs9{Fr%zJuDML;d70RQ`$9>5$eg zFO(lTq`1p|{;ETYn@d^l=dU`XyXohzI;6Yl=dU`X`&Xi$zv@uk?(O*bs}9xeF8leb z4thHsa>6l{*Q(y@zzH2Vp+g>cMN2lZrd#9=JkTKze5mp^SPOTsP9xcABpsxkgmWxJw7HHK+dbm*>!X;*Zp#_%~FgU8_scoIIv9#2s|4bQ-{@Ekl3 zpJ&Z0l-(2SkV72RmpPtS;H#=7I#hf7M!Zh>24#P>vP135T}}Sz_N9~drBn6B?^T`y zJ*!ctMn&Eb|3Vsds+GAa{zOk5cdGXAujZ?s@1*wVr1t2f_UNSc=%n`Or1t2f_UNSc z=%n`Oq?PHU_UNSc=%n`OlxL1>n{H(~7*v7*v7! zXP4A>+25(|QZ3<#y#im=6P{gC|Ci!*$~P$ACK`7X$-R14ira#TllT#x7w@sQ+_XcZlJvy|9n&Q^V@qh{^=!M zI+wl5dLOgDOukorOEU)jW%9l1TbldX+5}9(6imYm%)%*--`@|}t6cV36k!P-f`{P| z_!#t;8}~|6(_e1fD@{#*xpA*%hWf7fgx&(%t2a}Yi~hpTUcH&(v+(yD_bSItf4_0B za@_Ry8}~|U^8#^r23~}h;InMOUvS#15mayOdCtOLaonpq!N-4a5x4cj1Xu7w&Pv>a5x4chIHm|a^*L39jR8zebctoE3K(qrN(XstO z^oZOeI{v%jdY#K7I!>>-LFfL6{NVK?FbZQZ4im7KUwK}JN3=)tntuE5l?!i)KTytU z(t3@GJgPej=6vn_QT2b`6|3}(h(~n{x5a85&!akq--$J9NgvfQ{8rq<`W@QKqw?xq zu}fF$kLuXGod}G=7>vUN^t)7#DyrU^@0>oW5pwe~e1T)Q%3rUsub0@eXV!RB5&MTg zw~qE-ME421=?!+%8|It#f}{tWgcqt#iLEZf5xww%`%bZaK&Fh-kNJX>%ukty3-3t*3bY zLfplY-LQczgrLVxyH!hgUmij2RxROj3v6Xcha%Ih2zz-C#}|ZhDyA^f0^WVRqBQ?4~EsO;4bkoGbI9C|`neZOzYx;Tq9_ed(KAj$A<;SAi@gCao9;xQC+wmUS z@gCLiU#aYNyhpm2ZpVA1i|KZ}hjzS2y7>70Rj3}m3f03`p?Z|{J`2Bt+@o6E>$|P* zkuE+4&!^L)_Wd73&!^Kv?)T_By*^*hrxQW12zo`(D}r7T^opQY1id2Y6+y2EdPUGH zf?g5yilA2ny&~upL9YmUMbImPUJ>+)pjQOFBIp%CuLycY&?|yo5%h|nR|LHx=oL|` z{h7|fdPUGHqJEdl)+>Tu5%h|nR|LHx=oLY)2zo`(D}r7T^opQY1id2Y6+y2EdPUGH zf?g5yilA2ny&~upL9YmUMbImPUJ>+)pjQOFBIp%CuLycY&?|yo5%h|nR}{UX=oLk; zD0)TFD~euG^opWa6uqM86-BQodPUJIie6FlilSE(y`tz9MXxA&MbRsYUQzUlqE{5X zqUaSxuPAy&(JP8xQS^$UR}{UX=oLk;D0)TFD~euG^opWa6uqM86-BQodPUJIie6Fl zilSE(y`tz9MXxA&MbRsYUQzUlqE{5XqUaSxuPAy&(JP8xQS^$UR}{UX=oLk;D0)TF zD~euG^opWa483CL6+^EWdd1KyhF&rBilJ8wy<+GUL$4Tm#n3B;UNQ8Fp;rvOV(1k^ zuNZp8&?|;sG4zU|R}8&k=oLe+7<$FfD~4V%^opTZ483CL6+^EWdd1KyhF&rBilJ8w zy<+GUL$4Tm#n3B;UNQ8Fp;rvOV(1k^uNZp8&?|;sG4zU|R}8&k=oLe+7<$FfD~4V% z^opTZ483CL6+^EWdd1KyhF&rBilJ8=z2fK^HuBdn zWzT!ntDe7?`+JqW(&A&WRaYy$(!#%OXFL8MIMyjQ)7x#@YYdKGii^Ir8T=0476 zpy$2nRm@F)53^Ta9r1bjdzigMzE_cV*>CSNj#`E23xg+pjo(EG~tW zFbF-v&VI$&tcCs}>weR*{=wj&$Ip&=o$U?E4HS; z3e|^)`|xld9`3`#eR#MJ5BK5WK0Mrqhx_nwAF=Jj!+m(T4-fY#wqIz=_HZ8_?!&`< zc(@M__u=6_Jlv-Udrf<|4-fa@;XXXvhll&{a33D-!^3@exDOBa;o&~j72b|L+=qwz z@Nl0-q8`u^d$!S;@nT1 z`-yWuaqcJ1{lvMSIQJ9he&XCuocoD$KXL9S&i%x>pE&mu=YHbcPn`RSb3bwJC(ixE zxt}=q6X$;7+)teQiE}@3?kCRu#JQh1_Y>!S;@nT1`-yWuaqcJ1{lvMSIQJ9he&XCu zocoD$KXL9S&i%x>pE&mu=KW0C655&I81GfH)5j=KW0C659&V$5xkT?$#=Rx8;NSp_W^B{2^B+i4xd5|~{66ZnU zJV=}eiSrr27KNmgHIHcHqEV{iLQf$rbEO)V~EHPDf0fUYwRIK-evbXh7@_P>2cj5MgB9<&*~2; z@^{5f%Ko0rkRti1={>&*4`}+kXG6LVXnJ0=A;sK#aho`#n44}BhZJ-3 zakl(Z_yl|sKBd0O5Go8w1+VG$aY!ndZXbuFg6Z~gNGkZ4J+Il2R4^|=&ucb>3PV!C zWq&_;NGkYOFLH!_CV!a74-@%eB0o&zhl%_!ksl`V!$f`ksl@UqeOm` z$d3~FQ6fJ|ksl@UqeOm`$d3~FQ6fJ|#LcX;Mb`ym($rh<>_TJG)bulrV^Y(9_3T1pQq%Oz+GA4F z^p(_@)HFT2(3sS8*|Q6cNllkMyU>_)G&|V4XBQgNh{0Q;?_ZB`|9Xu3*JIqj9@Ddt zUhezXW15lVpG7}KFeb(QThFXLCdEz9tUV^h&BO2r^vv30Qrzo%Mv^fpZhCg1F)40( zZi_J~ZhCg1F)42P`fE&zo1R^0Op2SHU1&^-o1R^0Op2SH@nKAgo1TMaOp2Sn@*0!M z<`tHBcA+tiD)?MHv-X%2_mbCC6OQRg6)S#&vS-#FV@8rOjWB#37$+ac$;WZ>ah!Y{ zCm+Yj$8qv;oO~Q7AIHhZaq@ATd>khq$H~WW@^PGe948;g$;WZ>ah!Y{Cm+Yj$8qv; zoO~Q7AIHhZaq@ATd>khq$H~WW@^PGe948;g$;WZ>ah!Y{Cm+Yj$8qv;oO~Q7AIHhZ zaq@ATd>khq$H~WW@^PGe948;g$;WZ>ah!Y{Cm+Yj$8qv;oO~Q7AIHhZaq@ATd>khq z$H~WW@^M0ue=9JdeEe8+K29hf|0vE=u1zQt?}+o&qnJRQ31#9tDtn%<2{Lg)ndmKe zp05dI;)kN=`I=BBz9DXw;uBKyE76%aK_*U+i4$bvgmmqs`(NNXRJ=lPnD)~4tAnjjM=$ixXUaYFif%bw?J zLYZhqoQV@;;)F8MDmxP=m>Xz#SdBhki`#K{E)>DS^SX24_W+>#SdBhki`#K z{E)>DS^SX24_W+>#SdBhki`#K{E)>DS^SX24_W+>#SdBhki`#K{E)>DS^SX24_W+> z#SdBhki`#K{E)>DS^SX24_W+>#SdBhki`#K{E)>DS^SX24_W+>#SdBhki`#K{E)>D zS^SX24_W+>#SdBhki`#K{E)>DS^SX24_W+>#SdBhki`#K{E)>DS^SX24_W+>#SdBh zki`#K{E)>DS^SX24_W+>#SdBhki`#K{E)>DS^SX250mo4XMsui;S+HV^p{a5<$*h* z-wU3U%3q6~XKhl-dVN1%Iw@sMKVLej>%OnV9jvpHb?R7N4?WM?r1bq%Y+%bF=%-94 zrLXtpr%WfMugfizeJ6BMDto`4XKhl~eWvGGo7B~x>3P;BrMQ3Pud+-^anoOAnUvzD zzsfQx#Z5oiJ1MQbP0u7dDXmSGoq8y+VnG`lhWGsGoq8y+VnhYlhWF}2tCi*q^=Wvj-F?2QrC$t zd!DsP>2AIVud&~kh{NkF@jPpjQu&iW4t;azn?v86^8H;cx4t>_&7p4&eRJrWL*E?w z=Fm5XzB%;GDStoHZ>?`m`Ddpd_N{LYeRJrWL*E?w=5$^ErT%JtbLg8x z-yHhp&^L#^IrPn;Zw`HP=$k{|9Qx+aH;2AC^v$7f4t;azn?v6m`sUC#hrT)V&7p4& zeRJrWL*E?w=9J4{>o~1%4t;aVWuK$<&7p4&eRJrWL*E?w=Fm5XzB%;GDVKfL);EW~ zIrPn;Zw`HP=$lhUd%xBv>N8dd9=FvBgzIpV`qi-I4^XQvL z-#q%}(KnC2dGyVrZytT~=$l91Jo@I*H;=w~^v$Dh9)0uZn@8U~`sUF$kG^^I&7*G~ zee>v>N8dd9=FvBgzIpV`qi-I4^XQvL-#q%}(KnC2dGyVrZytT~=$l91Jo@I*H;=w~ z^v$Dh9(@bwTR`6e`WDc)fW8IvEue1!eGBMYK;HuT7SOkVz6JCxpl<K6!V}>=^pn#s_c2trkDq9ih0ncm9@ z>Uq$n~xlw9#E(et29F%R05?wk9VJrCNH zzNYniv4`XLJZMvLi|KjLrsNjW^Po-1Ej}vGgEpo6>}C>r9<(XlXE!|$+LZ3Io1O=4 zO1|=$dLFbX`O5S>XjAf)>3Ptm3PtmF+GZVK>b^%<3oNx8Qd)LVi$Bu6`uCUwTlU{6cI~FXf=zcvtky2nXdxFY)*B4l3H_ ztME0pbDi=H%6@ZmT6=j{^n1J0+Lz0Idv{v%B13J@9G07v{3Rd^@eT!(8^4Z>RN+n9H7n zXN=;roVhU zt=u#{2h+5k!Zq{Ib1+TIAwF_{`F2|Q`=#hPn5Lza={cCD^#vH8yXRnIYiK z+7;2Rh;~J^E23Qy?TTnuM7tu|716GUc15%+qFoW~ifC6vyCT{Z(XNPgMYJoTT~U7i zP$mC&w)b|thcp zN@!O?yAs-!(5{4bCA2G{T?y?<((dy>3GGT~S3$mC&w) zb|thcpN@!O?yAs-!(5{4bCA2G{T?y?1MhcPzE;y#&OioQO9wVzoSVdwR94aTCAj!lqTtsmvj5_i^ z=TtQfGBf_a?|Yu_d!GN}Z8&*ztM0w;J?H#>?|X0VeP3z!b!pcx?fRu%zqIR@cKy<> zU)uFcyMAfcFYWrJUB9&Jmv;Tqu3y^qOS^t)*Dvk*rCqz8)@(ym|H^-H^cY1c39 z`lVgJwCk64{nD;q+VxAjerR`((XY7cmv;Tqu3y^qOS^t)*Dvk*rCqz8)@(ym|H z^-H^cY1c39`lVgJwCk64{nD;q+VxAjereY)?fRu%zqIR@cKy<>U)uFcyMAfcFYWrJ zUB9&Jmv;Tqu3y^qOS^t)*AMOHai+|f{m_nO=F9q}_nD8<2Jb(r!T74M@8I zX*VG42Bh79v>T9i1JZ6l+6_p%0ckfN?FOXXfV3Nsb_3FGK-vvRy8&r8AngXE-GHq}_nD8<2Jb(r!T74M@8IX*VG4 z2Bh79v>T9i1JZ6l+6_p%0ckfN?FOXXfV3Nsb_3FGK-vvRy8&r8AngXE-GHjfnu4f;95PkUH133ccAawj4kRxyoLPsJ; z;2eaGT+b0W2caX8BXABvMgpQ8^ zIXBrLbX);)Zn8nBISS<5WP{43gV6LIlsPxqpnBkg(2;fKXmx|Qc3_!vlMUj!k9d=i zbCV6?x{t`Y$p)b^kNycE$L$=1%0!OaIS7@B9Jg~2Dib+w=O9!ja&EFgs7&PCWP?zd z$hpY|p)!&0p$|f3BHu$FgvvzDO*ROXxgX9=HVA!*bJ~jY>MBnsbv4LghM; zbCV51WtJa9pK1vDJ_h6rk3+cX{}GTgJPtwAr-7W|aR_Su7Rd2bhoC0Q9ARt-Y7#k~ z>JZdqnIlUKK}{k@mKcJXL|)SkK~0u9p6U?PWSQfs4na+pIm6=+)NBAb!{ZRtd>F{F zCWfHn4}qNFaR>@N0OSmhL%3H!%TDGX%YO6pr~Ygs3EP zRIwrGMf{ZT)56aP|A&yHiVZ<8?t$YZ4?!;?$4MT7UPO+QJOsU1XU_0A1igq~5pssd zA?U^ZaE8YrT+tIb!{ZRH=!u-+aR}G%WQj984&ln3$Qd4oaOF;{3OU2$5VYnI=T+XX zGG}-k!u2>6>=cRI9D(9tgUMlCMa$YLurE*>>=cRI9D(9tgUMlCM za$YLurE*>>=cRI9D(9tgUMlCMa$YLurE*>>=cRI9D(9tgUMlCMa$YLurE*>>W1Kl? zmzTr2StdV7IJ=yeNcq>St0vf`=AJs{jPmbgvfr^J}5%u95nl& z2$8d;?}H-5+f-YQ|GW<>@SE%@?Sl$D3yyEU4}XWu-G0J+rwge zSZoiA?P2_l%z^J*in(Qn#r&|C9~Se&Vt!c64~zL>F+VKkhsFG`m>(AN!(x6|%nytC zVZ;LKK<0F+VKkhsFG`m>(AN!(x6IvB15N`C&0XEar#B z{4kgg;%`@N7(;SI{EuM1VU}H()o%oUNn8u079-MPL|TkU3;e|kdmfP%Bhq3-T8v1G z5os|ZEk>lph_o1y79-MPL|TkUixFutA}vOw#fY>RkrpG;VnkYuNQ)8UuM7{4ek#Ut z9MNA7N2JJz6d92sBT{5Uii}8+5h*evMMk8^h!h!-A|p~{M2d_^kr62}B1J}|$cPjf zks>2fWJHRLNRbgKG9pDrq{xUA8Id9*Qe;Gmj7X6YDKa8OMx@Ayai_5wXLQJj0hd)? zQTZ{d1+MYj7ptRsWU2dMy1ZE)ESjJqf%#7>WoUAQK;j^9!`aSMxo9|AT!md)ESjJ zqf%#7>WoUAQK>U3bw;JmsMHyiI-^o&RO*aMol&VXDs@Js&ZyKGl{%wRXH@EpN}W-u zGb(jPrOv3-8I?MtQfE}^j7ptRsWU2dMy1Xu;$^dOJ6ivzfi`5Y+tK>7%z2P+N9+F> z(4+M}VFrBOj<)p~;HmnQBPHIB_Vh{Mow%~T9j(tJz`OMQWvyA!n!{T2L*Zj+HO4gi z-WZPlD9ZfH;~0+4GLJrnqdx@XEX-r*b^IF0d058aklz703-cHp@+6S6E{?$=#I?e8 zTF+S*$KVhmXI&hFLx`MpaZC;wgF{%}tnYKy#W6U9`{b;PW9oH`!6E%9bJoQ%IAjsX zSr^C9>-cvdXI&hVPsYFu*K-!;G2P!A!~MNyQGT2D$-mEzp$GB=kh3t4!9_e5&cZwf z7ZGm~eq4C7@K$a6x2g|kT^xgph@5qC3@##a*2OWnh{#zN$KWC&XI&hFi+Dz#6MkO! z1tDi)9)pXBoON*wE+TT)#WA>u$XOT1;3DpaPZ*A&AHw=`7UnVdirezaaSXoVH`xM? z!3k49&cZx~ehAB)b#V;+kcW(MDE=^z_W;MCILn-UZybt02;@9#`-Z*ssA&|50jYIdJ1F8EsbYB7Tp8Pm;|92qY z=pV;@U9REmd*e|5X&~S0ABP8cUN`7Fe9m(mP9X9*&v7_`$mcxAkxz)6eQzB3g!|#_ zd*g5dk+biO!wE#rzBdjh5IOtaIGjM_?0e&I0{6h#_r{S=h@5?I9QlOE+4shkPsWu` z#+6UTl~2au1fDNv-@{W0aKbp8z;of#1>}6<8T7M$(fkO@k9sLbN0P)_@NBs z?0e(z1Izd7+&TMRNvt|-YBCAp#`SCr(6l3Y=eD@t-jNvA0ESZ=!%kDQIac4az#n5D9IHi zxuPUjl;nz%Tv3uMN^(U>t|-YBCAp#`SCr(6l3Y=eD@t-jNvc_&S*|F{6=k`i zELW7}in3f$mMh9~MOm&W%N1q0qAXXG<%+UgQI;#paz$CLD9aUPxuPsrl;w)DTv3)Q z%5p_nt|-eDWx1j(SCr+7vRqM?E6Q?3S*|F{6=k`iELW7}in3f$mMh9~MOm&W%N1q0 zqAXXG<%+UgQI;#paz$CLD9aUPxuPsrl;w)DTv3)Q%5p_nt|-eDWx1j(SCr+7vRqM? zE6Q?3S*|F{6=k`iELW7}in3f$mMh9~MOm&W%N1q0qAXXG<%+UgQI;#paz$CLD9aUP zxuPsrl;w)DTv3)Q%5p_nuBgZr6}h4!S5)MRid<2VD=KnDMXspG6&1OnB3D%8ii%uO zkt-^4MMbWt$Q2d2q9RvRa6yoYi*%>OTbJtiBUa|A#=%>N^4TYe3HGI|227 z0p$FK6VUW$K;Da(fSN?!HJyN(MBX)>fSN?!HJyN(+yn2LPC!i}@0w0PO(O4_PC!i} z@7+y6O(O4_PC!lWf%onvpeB)bO(&oxk#|iepeF0j`3)zaCXw?SPC!l8pZD%2pdG)t zUuVtv4JV)-*K>Zu38;1_khA(uKsA;*zu~0xnv`CX(rZ$BO-ipx=`|_6CZ*S;^qQ1j zlhSKadQD2NN$E8yy(XpCr1YAUUX#*mQhH5FuSw}ODZM78*QE5ClwOn4Yf^emO0P-j zH7UI&rPrkNnv`CX(rZ$BO-ipx=`|_6CZ*S;^qQ1jlhSKadQD2NN$E8yy(XpCr1YAU zUX#*mQhH5FuSw}ODZM78*QE5ClwOn4Yf^emO0P-jH7UI&rPrkNnnbMCpau1slwOn4 zYf^emO0P-jRhM3M=~b6rb?H@?UUlhJmtJ-0RhM3M=~b6rb?H@?UUlhJmtJ-0RhM3M z=~b6rb?H@?UUlhJmtJ-0RhM3M=~b6rb?H@?UUlhJmtJ-0RhM3M=~b6rb?H@?UUlhJ zmtJ-0RhM3M=~b6rb?H@?UUlhJmtJ-0RhM3M=~b6rb?H@?UUlhJmtJ-0RhM3M=~b6r zb?H@?UU)YJy40mtU3%4}S6zD5rB_{g)umTmdex;@U3yJPuPNy@CB3Gk*Oc^{l3r8N zYf5@eNv|pCH6^{Kq}P=6nvz~q(rZe3O-ZjQ=`|(2rli-D^qP`hQ_^cndQC~MDd{yO zy{4qsl=PaCUQ^O*N_tI6uPNy@CB3Gk*Oc^{l3r8NYf5@eNv|pCH6^{Kq}P=6nvz~q z(rZe3O-ZjQ=`|(2rli-D^qP`hQ_^cndQC~MDd{yOy{4qsl=Q-zG|+2GdQC~MDd{yO zy{4qsl=PaCUQ^O*N_tI6uW9J@s4)$_eg))weA9UIg~<8%rqQ4IIgs=5O+&{;Am`(o z)_i=^Q1dX#oXv9@Iuh3i*9tkC=QI=~9wX#zp3_i}$XQ>fp&-l03tuMWe0uDh8 zooMb3&{ESrlAy%emd@LPUC5-XMmiKZyHZq5#ONooR4oB&s-5XAKx^T zkQmQh>U z7Or>#$Sg4nSNs;pr%Gnw2bTF%$*lSVv+57bsy{HR{=lsI1GDN6%&I>ytNy^O`UA7- z56r4RFsuH+toj49>JQASKQOEQz^wWMv+57bsy{HR{=lsI1GDN6%&I>ytLUCpbk8cf zXBFMEP@lEs_0g>Q1G9)_o*kbmnS~Zl8*>^Dd`{zm&w*R6;hbo5;D^XL(dOXx$AFv* zV-9X7z8*fDgXbRya#ZR$yy;BjTo`kB)0t(?BQS?Iomu8w7<0&Vr+?Ma+ z%^`pCo18~rPVXknfj1tPGiuG@+=-k~YYyj5g)xUW zj=3Msg)s+iS(AB{ITyy9#siSV@+RAyfl`QiOg?Y4-mPlJe*JD8w&GqK9O%I%)|Ll z0{Mo*Je1}4`G&$g^ktcED9pq8M82Ug59dDy!zV<(p)e1h5c!6}JYs~%Hx%X(BSgNT zFpn7Fe)xvMJTxWFX)FE>dLHq@?;Oxs^XcVz`!S9L*S}fFaY6TE90}st!gGY@2`>;bcJ?E79tU!4-u;T5{fM2X zP<{tuYQG|AKYAcs!*SjBV&kaQDO8M0$Hayv;Jby&vN< zuuNC)N4x)&v7okl0ls}4{$ptXa8lD2*E+|Vc zz@UQkY6 zP)=S@PF_$>UQkY6P)=S@PF_$>UVz_NH~MWsIe7s&nP;@9^~}i&Xdk}|JcK!L7vM3L zS5)S64vWYkj{seGvTG4NsP6+g0>+|7z*y7>7>gPKV^JeuENTRdMU8;5s1Yz0H3G(> zM!;Cq2pE`o7tbLqLc9Bc906kyT08*c2pEgtpU4p~7BvFKqDH`2M7w||6wxjaIReHa z+|Igj1dK(EfU&3%Fcvie#-c{RSVX(PZ*l~TMU8;52yfquGDpBzgtvJ{906ky-aZWE z2pEg-_Ah~#Vq}IzjexO;mV&k72pEgVGps*Hz*t0{A>Jh92pEgVGenMnu?Y3K6-U5W zgn~qlfUyV#i5vlA5egDH0>+|7z*y7>7>gPKV^JeuETY#mgHJgE#-c{RSVSAd^Wq2? zi)e$0906ldBVa7z`At8{906kyPk0>%PI|q1dK(rM?{W*v55AF$Pq9WH3G(> zM!;Cq2pEeR0b@}kVBjiT{BQ(}MZ_$*;s_XvXpgupN5EJ_Hh+;iwyEp)E z{2cf?;hDnM!}AB=jb8$p0}m(%9)M3CLirrwx%%dLDxa_N1u9>NxHzC3cmO{63Ciq0 z9Dq-VeD>)89P%viQq|!qIOhNy@@wF&s@p#ZKPUXW@C(9!6#kR&tGJ3h0L58<&WLdU ziW4~_#sMf!taecESEDI~b zs<0-U(D_aZ>%u7^pO`v;Tut`)+|&W(>H|=p>db4~1@X2dX6}%h2Zi^DpU3dbF`)LT-Nwm_ckVsqej{+`go~_mcYFOX_W43> zAHJl1_>%hJOUn66%K1ym`Af?AOUn66%K1yk`KsFR35C1kbRBIU#4` zT|$;17KOJXzLwBCb$yM$~&tOz+9?-H^Bk$>-4g32s&jQS-+HyJx9yc2KLEujUu z8@R0Uipuwh4UWxnhwk3oq5C#>pjCYmYfi*>?f~41d18v!?aZpD;sG}d$(GTkA z2X*v=I{HB!{h*G1P)9$gqaW1K59;U#5%s^q-gxwbI{HB!{h*G15Ph~su%1Uh2sU_J z9{o6LJX6SC+?~i>xa)y@brZns7pAG%2hLr-aiwqZ#d|q4K=GzaTc2bf!N9=ZBDUegkwF9YD`>JAq!@J30hK zSoWhYbO=3@L%<&Nd=4S=JP2GT+$7vA+#);$nf4I0!}C4R4(}F1JK~u_YIg|QjRMcc zUF$>8j(Dy zFfNhK^lQSeqyKOSEfmjvK$sN{3Ws!FIbmK{5D!I_@#X=x8pV4hhv0!nfMa4{T%VSN zWno2F71o3kI*UnRT{tD27Be$wp$?%{B1?0s|Gc(ZK>j&|{sr|~5_@+@_k+T_r2b*y z4~6%L+k3_8V|cIRF60f2@Q%DetiOfaI=u6|CopRB#a?vvSOLJJmT(k@~5}AvZ(O)7m z7cHahW38BrmeE5dG8ZkQ?ISW5Eh`r-D;MFJXsu^1T1GoaWG-4pub9YOw2WTy3Xr*I z8NFg6bI~%G|2dGkXc<0anYm~g{b91fT(pdS?~TTaa?y%%(TZ}>igMA4a?y%%(TZ}> zigMA4a?y%%(F&A$5PM)QT0u{S$Xv9dT(qKGw4z+JqFl5h?N*eFR+NiYl#5oBi&miB zBDQ5NT7h;fGZ(EW7p*84tw6iOSi@YjqFl71T(qKGw4z+JqFl71T(qKGv;sAk@O|c@ z6{tyME?R+_MCPIu<)Rhkq80RWcrMIEE9mDCnTuB7d?Itv3eJyoZR-iu1%tb58MJvihE6PQ9@?D=Y7p=epMCPIuc!0=U zv;q(CESQT{-~l3Y(F#03mY9oHl#5oBi*PqfTQL`{C>O0L7pF5I z$Xv97>!WW0nTu9%edI6>D;FJBE;_7SbXd9QuyWC1_~8kBhq>sma?xSsqQlBXhn0&C zD;FJBE;_7SbXd9QuyWC1<)Xt-g!^GGIt)dK%teQliw-Ln9ab(ntXyz%$Uty9XX7o+&(6c)sv9 zeP>AJoG>pe2#dmTVM$mPR)keyO*k)H)ZPx^3K1Lw?*+q;19`vnUPRw-fhWL$_oANj zz>}cGz2NhH;47f=y{I#;V9{6nF_2>z-isJ{7_H6G3hs1_(ziP6mPY>vbOWOY-v}^aG{{IS>^uS|};fTbK3O^>i zN%(Q$&B9yo{1xX4a{~Ehp9w#D`(+aK*8wm`%Tll*!+h1U^o@NC~{i#{jn3`w4w~-M7}?yy3IQd~Rdsv9V*%Kla1N){p(&rgfY4 z9@p6XrQ>hja^cHvJ)!62A3kaGNnboUbMiBt~m`FFoVZw_p0-?46h0eECJ&zOn7lwnyJ*eP7S}&VJv{E5CN-H?I8NmG^IN-=5fh z`u6v4zjgcQRf(%MUUkM*@4xEStG;^G#8uB;{ei2$boJcT5AO8t% z9J*o04PUz9;SZ%g^yLo+KXU6w9{p(jW52lRw2zP7{KcDxZ~oTJ%Qru8^B->s-m>nN zSKV^aEjw=g-rs)V6CeG%PkgfHlQ)0z;lHnZ%K53YK6TrtPx#D^|M9iYHa_S6+ykE< z{l^_&yzoobFP;C-&VQcxiuEhc-u9*c=c2DZ`Y*3CEQVq681KjZxYrx){0)oKFjg7u zVZ5cv-@7a~wALH=9=^`606Xwov%Csh?`oCXj5izCwaV?duQ=N(ccA>eR@sX3k6LA$ z@owXRR@rWxYI%LD>@a+mTUuqO@e#`xT4k3JSQToO-6;39${ypnRVTK}UL(W)Kt+K^%wjb9juQI&tuV|Iqj4!sozEy5F679$v+O`Ab-?qwDBhe9P zm2F0&sHxebXvEy%1+~t){nQ!E~Cfxu~ylQGRAq+{ymmI+7?=6uW^E7 z{nJt@-KR)x`4`$BY`raM8GH<;4nyou_Y~8(mQ|9{Xuiv!& z`Cl*Fb#>;AS8U(8EAtk7y7S2AS8dz9a}z$>lzGjL9U1L)PiFVFJ==C)x9##xuig6I z?K{ukcEz>WqxOGv_b=JIcHY{zK0LDPQ!?63=JZ`VEKGgQJ);!`s77l%WU71*_zqAd+X)fuHL%)s?4tU{qLUf{~lp~vi1M6Cja?{|BX`r zsZcLb<0UIza-7W@|CGSYx|eKqL|v$9dtEkV~sC*!8}>*Kggujr#4_e%ZF2d$wJkxpwE}+jeL6Ub!uE!5h!Y zoO8{#oy{+w)%?Q7%u!Pue`Ig1jpc*uP!-sHTSoQRnmO||=Vi9;JtcGH-o4kHa@=uy zF5A8Rn!S5A?Lmci?Y`o;bIv^Lzy9P!E;C+>bajpKL1VYE-MGTI(%5TcjCICk#(MnR zf)|dD$G?p6UVI~CoNH`FX$Q8*7;iML#&%or+YTVN-h{Q+>)$5)_R>!;!**9|%Pa8t zPVMC_t!;O{Wc#a(ZP@Eh?6tWa_x>6kE%So9?!nsK_~ssc`#Rv|*y6RSCy#MH)?8s+ z+p6Qy`u}IO|MPW!Blgv-`HSm)bjv@j^(m;|(b{B;({a{2P)DwBvb*_3pTD@i7wN3_ z;F!B`E*U7X35sksPJF>O$NtGVzVK)--dhIyAzxeZ|6Z`R74_H#MX26YShve~AMhwg z|2H)Lzj^fk{@DNL+bbe-+n%{u_V(d^Y1^_0Ktw z+3C+8>qdC}PiuM_qL*&pjtD%GRo3H(9(3}q$J)Kfei=p63$sbaI8)Kbym&UYz8W#} z!kFHq?JvZ(&FDJ%?F$r9d$Dgu7`JMEV+Vd-hTnH8Yh8}@*P_f=+>J78!S7yx40{%S zo`WpQ@4m1eXT4|-gSR9c*cq zUX19k8|W#vqX%w9&)bgs2Tok&xpCrN!-u~O2QbD=$T0DwQUrg&j2UrU{Uvc{HjQzW zx^ODpMvu{J^x+=a8jKgR4$a;MjBm2hI2I>zoSMHa#>p+U^E%kz zLE{6)4QTxT#`utNBi`@%y73X?!?=F_nDMajDBfat&SDtf$5;{L#xIOt;wkz24U8OW zaTs?SKgHGh5AY^@+4zQmx4-Z%X%$ag+=QpN{+1&!;n~G+TAUV_#clCeycVCuZwXj} zmXO7?ge?(E)DpAAEeT7~_>?7ONn1KCU6zcc+tOp{we(q5Th>_CTGmpZri=>^498C=;xM~X*XLopQPR3=LuYopC`6{zP$DG$oEce{jTk|Y(BZQ-O0x{ z*PpDzW4#WKpRN6!+}hvCt^J+c+TY2o{hj=Z_SapzdsqAEoAzAR{#wErgx3+yB)p#R z2ErQ&Zz8;z@EXEf2xk+{0d%}Z+nvkb&m){qxPWjW;jM&=2yY|2o$wCA#ej};wDDOe z8ZZQ+rH<>%He=N>mO27)6${@)fyrStA}xprwIB0MMCe-(F9%8V=*;Urv^{o49bs-aEPL>3PU|QB0NVQ9 zsh^J_De&_Qf9|a#ESo<+()y|O`1}qe4u0=9t)J&0iSYZc=1;7@z4i0Qt)E@3&p*=o z`D4_C-+Qk0a~FSN`;WAKViJ4&jvEFZ3zjVwxYp@p@yHTAQV6Cj2#z%ti+2mY=GfxI zZx)x+8-CH(@o~&z@vQb)EPZ`Guf^kbx-AxK+-k9Oa#v~Y&Yc9bv!un1usX6h*I?O# z#j?f8g$Lo%*ZlDkTpRRYL6qWq_Bf)}f|&cSmUW0(outLGuG?~KDq}%#W6NWE5bPFT z3gM1ZvbarT5H1_Qi{If|wQ5znwZm>*)z;SDzN&pyhqbMvwcwME_I8`Kqr=wGVYRMW zg@V=Ef#30)13%jEucHlL65{Kt?A)}iy{)6&iq&na+S<7jY}?+>{Q}zC+S)pBv{gWx zz1^xsn{}Wnt8f4=?N%EW?5kai4M*tE=luDirG1st&I;gQ?KrN!)s9nXZ?n2^N;n#p zcAQ;vvGP>fQ6(H7^}??@oetEX-QI3E-EF9_t;I(N`QWj6(j=hC2ez_y*lcZW;LT>Y z+PNF66U>kgoF>1`b6nNY=HSU-HNKCk@ubP3)wZgm-PVTFwBa-ChkWpq9W6eznUyuR z+3Z}}?c@XdYM%R1zIYDLFFNun7o@@WASU@hHBi7Ax7pk;;)B$*WB)umogAu#DyX7X zoK#1Lqup?MsG;5Juz^8v+p)@eL^B)tfXb{HD6rXi9u7PBKt1g?7Z4xw?8zM&2OnUG zWvs>~JazJcqhjCob{yP}dh(>(zz5FU37WY$Wea@LCN}K$4*kTwntV7!1O3zDLf>cE z*0IX%WCg$n1i%XMK{0F|@&XP>4vSn+e_4d;;w*SN*wzNSTdmFx!|i3A?N+Dwz`3om zLNh2s>S$@OhWa{eR=We|VRhOa_ywEW-B?XN0N|Jf9HGs{vjZQ^1E4B6eH_;gJ{;r& zJ4dC!2R^bn9Iog2;CAH0VRvxp5Mo{P{GH;1pQBnw7uK?)&ErA^Py-wTI)D!p;DC0! z7ewG_FXjU$enefIiQU29Kn#U+;l`>T$G|DO?C=M)wzkl~T(&=p zs%35Sc~Ak=pv4Cg0OJRI1ehws0*v2UoKC3Iay!lfzvA3*u5O^mYWRYzv&-%gA4qv^ zc9&w8zQqZGc^9e-3Y@O?c5LQyqw)^B%jp9mE0Yw4q4==1AK`<9+sOx9g9 zz&z`4Adakdm&*f>aPf!_FxBpIxw+WfWCe$4^5K?5?FfsUm0I)K? zgs4FvIfF`_bOlnH7HfwKr$V zYg2SMy$TQV0m7Sn5Lpc^o}+y509>>lwY0Sbyr_T!fx~=lcQ*Mz*%eYpfutO5Gg1Gh z+v!rc-3?M`cPiqu837Y@K(u(p2fW{gn8p_ThgHltO+FkhWNSo;+vD^&oesAv07Q~- zAPndwtDTIu`*>nZ*Wd#rp>@)6T?jR|73M_303YxgV%q6;`w%l+w3$PExY_0M*gWI| zhiLNQl|=j;730!G7VPaoA50HEKs=lWK9Id&*$$V<{t^xcyC4@d7m|F$?NHU_anOb6 zX#)K=BN$4x6mDe*9N_~MaHFmsE6j|V0MYG`>OA3TE7 zb%Yj|y*=c2!DdZ9P;K%-J6YWk#tm9iv>z=#Y*y|Rj*#1(aJz?gXZT}>0lN{3QbUi^ z?0UkQPuY5W{@i5v1CPG8z!3=|BUE zYyoc})NC-P4}74Z_aJEOZl5pYU|4uOL8S}&!{_sJarj9H_SNJgAc^RYX1c`(Em}Oz z_DBdh-tBDi!9YOZBac|UakL{%SC9`jRd$+Fb`NCIwL)gg0X75HG|=(PC~KpL5eF5;{4*7$gpx5IL_#()7Xhhr|8~o>iW0`L| zOsb784x9vwwfJzuTTW-dj$jSg$%mJGI6VG<+2X@g`XnC#e~^naNLH|~BYg1m$w#yK z@t_J^P)lb=Jd6r>T;#)slO-PrFPF`qVn<7^U|*06+K>SGaCv-;TJRBYH^U!7y24H) zmZqlzZqs*!4^KcI_PTwr6hZ+Zg00XL1g%!DI}`|dgI=#E;EMv$i$NEHULr9N&l)Bl z$iiTZe4sZ+N#QLQsPK{xUiWx?=q@?DfneCBJmCv7C_UmMAU<5;1BcLQyF;?Y3;7U% zZq(A%kqD#BBOgd;AP9W0aReV}^hV$bxWb7JESqkJog^#zp)StCA8dxdhv6S_8Sze3 z!Ws00eQ*>k@9OXb9cuDC;=|)ai1>W4L?8q{JZ3QD4f%YYpg)Ed0DO47pakg^NIoKT zzxW73Jn{h@U<9kn6?7n%1=UXjKj31^a69VIq2wl(96M zW3Nwqc-Y)^B%?mq%i#0zUk1YbuI14}2g1&}{)9Xm!yb*n?f{k;@h66lg)4ic>*@ z!01QX@{NfLX0>0@E|Z=%m@4;KFpY#X(AAa2DlyhFhgN3 z?l4)wI{L!niMVp5rb;(Bt{S0^lu4wkTkyacb zlhN0v_;|`OLFfSAw zfgrBaUH))5;ZgPs#)I6Be1w~Pcp`L(KcG1BdZX&Kl8&@P&yd!<097=Ks(_L_&_50NKkLIN(@Nxfu!K| zg-n~*6LAKRr+A+LK}SbP4vQu<*tdCgcN5aKXW`kPojl zlMK2+oC|!Q8y7@_iC&1u>oEI}N1Co6AMDY(oZ$$vAzXxP==UQVMqZE(Qy!yhHJT%L z#GeQu1ADx5qdjWqqYPSdd@klHf3k3ravl9qD{6U8ge2^HN zxh=`c;*tP-An4!^@Zs|#*1(6W#RrobyRd;sH0fp9426;*Zbv?%kr)?mjI0EMO&j>) z-Xs1w!iNmyM=ia!?iBh&0iO#A!2$7cb&oCv_z17Yl>$gW}j4CvTy(a3Delghd&UGAkoF#$n7!lVTQ>^ zC>BfmM2DGvo{!iOKIoEAsA&U#LcRDG@L|eO0o2lG>+M9JDCl=1AvkfexPC*Ii+rp@ zKa^MMxL^Pu?D~U`SWwxJd<2mVV}S@_59tut=`(uPqk%^2k`9v(Kl}kc&?N#NVeo;} z;ERXNa6A-@#vKkbkcuTjiLe=rN4n8NaDfr<5rW@fDmcO3N%w<~Ao?dwKJ4fsBi8&! z_`szZk{bB%gktedAJb+yoDOq4b`j#S1Q%a|F2Op+iQk`mo{wgCEd(*J1k6C#XY1=S z5q3>Ju&Tv}-x*yGBFG22U*dz;sIfTsXlBD8RE@@w4v+BB8_|&|UGyL!A+{(7piqNO*8c;3E>Y*^wIj3Gk6HL$Rd85e}x~scQ?6KDf)pGJH{$w$HiJ`%i-1U_&h!DA*8nHC>i>Tb{< ziFk^OKSh_A;T9ih@xlCpx^W51P{AR85q1HO-H-lnlMi$z1FqOHxGG1-4EH6` z1vtV-0RPzv3^U&=#R&N9!zC@@iiWbQqu>0*M`9O$-q6jfx$mdT+ z(GG+|@f7$7btcG1#7xHeB4P3o3cKLHFo}T^92smG79UB39QZ(^5ey;L0{)~2ZCz4) zM55rs8%`#>15BIIXeP?2As@*^ix0X4>tusqXMp|@AL_W8kc10r8L+SGj`%>F2MH40 z{0RJk_S7G6#WyzjK$JB3;5B<9X*OF2@L{5LNHQI=c|ZjA_>DE2&|&c<&5Za6l8+>G z42L73C^{VA11S{kK-f&AoX$w7E18a@qY*O|TOEyr-C!i*79SpEY)3cG3zv*05)|^S z!xdm}1FRC=udgk_NT;0RD48Isoo%)kyxxJ#w^n0qmxUZv&o0@N+{H& zt33Jx&N#}48AZ!y-_RQ+A71(+Y({Yx487Dq(49CAm$K-n;_93CFwiAIvy)7PpKl$) zXdTifn}=AW8|knwV65AW4xB#~?hzj$++q%=y*Q-^juf>!zz0%BES`>plbzxt)fMdm zAL+!}STy1RBheNg?7s#by*w|p(qSYhllSq&M?C2W2GZUr+A-XBbtB2+zNasmPWJ|x zHskT$IJYAo=~Ne&U>98yjkfs6JkJN~h6Po?0zTqF`!Rj!Ge<&RdoYO0z!+`})mZAgbQlQ=NyXtt zqhW>-YoS0V`RMeTNNll0laJ26=lS4v1I);U5cI&E_`K8&Nk2d)T$Dp-i z#^W zt_d0&w%`tFpfl2&KnooVIf9Nzr!Rtf#KMUfF1*44q)@br(MYPx<%)%SIy13MJRa#x zu8+r}-iS9GgGG>Qyvo?l)jTiMA`}CDcuu#Nsh!i*S#wdc_C77>mW# zpO3_$wPVxTIMR^#z-3^f#fRxhpWsDJ#0T$NqsuBjqG&D6I9i8jv@4O$sChthiFCLw zWNbVU9k^gubafK`2${I$9_{i+QIB{e8Fx5?kzgp3Oe8b0XlFP1=3M1o&|J|MDI@6ozO(tU9>5a)m+!ymjzJ^Zbv@4Gre5QUb-ZaP@auM`ostGOY`z3 zjw)b@CZZ|Rxp_UVA>v`b6MV#?N!&C=uN^mfI$w@EFXRK4Z@7VmE-P*$WxB~nIFUy5 z$1joc48POE@2t`9?cax8<9=AK$QnoH=4tU(`dTO6%KX#(HH9GeR*#(O+FIc zJ?q0wKGum3v^?%V;UmE`5s9o0^YqCFoWZ5VM-n|F=ke>4;3MKkgF!xUKMeg(Gwkg; z34icv-U&8w1NjIa@pw9l))IWgyHi~~Y97*wHSuULb8db<0#g!>pZNkpcWH80?U z-%OwiSYoJU*tumxGL%e20^q|NkEOr|dhKS!n>iVL;7=^b8m8`X@jh2~PaLgfgnY!~ zXf1nVY%bA#K=W`+*w}muI{2ZU__{QDEaD?UK9Dk==cBhX-PxOrXZqakRBUa}>g4Kl zD$(0@TsoQX#}Na*XcD=`k2cg9ac#hsN!)UZBVnWcad{(*)6R@5V)h1-X|or9r||hw zoi3jvW)*1mub9w7-yu*6Zzi1UPvX)~1sACZVR5eFYGT*8KF2o!bh?%m`EaJ#5>bXKKi;k zyZTaz9`KQlukT%x1|P}3%<-M#BLO~A$Tfj@5|QEF$b5iXPKkIQ8Y%FBPDLz^+!GD= z1yY@WIMP~Y7x)OJ`ua9T)cfi>ri6^Y=sNhkQgg$?-Vc@_A;pWu*1Blx=p@2G_Wy?x1KS3H`|fRAKfSNG~fH*yiW z56O6J6P`e~@Bw!{^2}$JgB|x9&)T2E%E#7%q16&7u2JgObO!y5LaqbyB)xQC_5%@ITg*gVe2_w!ujc59an=#_t zQ+OSbh}Re~s>91L?%b1jPlofco``Yhp2TDPCtx&;lQ2fd6L@ci_zH|H@dVxrI0@rU zyb>czJdXEhUJ3jw;i<-}Fvi-eg{NUuy2tQpz^j3$8>eARq1PI(0iGdz9mawA4c@mo z10$-v9%E=ciuZ1aZ^TF%kK+9sj+Xgmj0W=v-otql@GZi#F)rf6c;VnJz;lJ?VU(DM z@qP}+NW1`J#XN-fbT~%hTQOG5LwH~30*plQHjEYXAl}<~EASl{E9ODGzwu<9!&T<0|6{;11(T;MKpT%d>&&1{>b=(@E4-^JJ|cL+Il-@oFWux|qo8Q;bD zkarpX3S1Vh7~ezrFz`Egx9bkz-59;+J9wMxPT&tQhR?S#W(DycjDq-Wjmq+E1LNOd zbf6y_-v|E0xEuIW;|IW>0S_2IH+}^C1xEWhfcM1i1!8m=jPdd-<38X6#!rC1Hhv0x z(D)ff%Xvunu<>)0A2EIjeAKxAx&3%G=U2eTgpV5!p!|gKYm8d+r122&DdS<_)52$r zM=(0pZ;eNR&lFfPVyj3$N}x1N=))|4UB) UOHOBI|4UB)OHTj)M@~2XUs1*s&;S4c literal 0 HcmV?d00001 diff --git a/src/Nazara/Utility/Resources/Fonts/Cabin-Regular.ttf.h b/src/Nazara/Utility/Resources/Fonts/Cabin-Regular.ttf.h new file mode 100644 index 000000000..d4e6b4702 --- /dev/null +++ b/src/Nazara/Utility/Resources/Fonts/Cabin-Regular.ttf.h @@ -0,0 +1 @@ +0,1,0,0,0,20,1,0,0,4,0,64,71,80,79,83,151,54,140,15,0,0,1,76,0,0,80,136,71,83,85,66,106,170,88,44,0,0,81,212,0,0,0,226,76,84,83,72,238,121,138,113,0,2,166,40,0,0,1,17,79,83,47,50,107,102,16,29,0,0,82,184,0,0,0,96,86,68,77,88,244,48,222,91,0,2,211,228,0,0,11,186,99,109,97,112,219,189,238,36,0,0,83,24,0,0,3,214,99,118,116,32,10,218,1,14,0,0,86,240,0,0,0,40,102,112,103,109,6,89,156,55,0,0,87,24,0,0,1,115,103,97,115,112,0,7,0,7,0,0,88,140,0,0,0,12,103,108,121,102,165,131,172,68,0,0,88,152,0,1,62,120,104,100,109,120,89,143,73,52,0,2,167,60,0,0,44,168,104,101,97,100,249,107,226,196,0,1,151,16,0,0,0,54,104,104,101,97,8,46,4,154,0,1,151,72,0,0,0,36,104,109,116,120,14,254,41,164,0,1,151,108,0,0,4,52,107,101,114,110,78,121,118,225,0,1,155,160,0,0,248,4,108,111,99,97,52,140,127,38,0,2,147,164,0,0,2,28,109,97,120,112,3,38,4,200,0,2,149,192,0,0,0,32,110,97,109,101,249,131,24,59,0,2,149,224,0,0,11,113,112,111,115,116,73,171,162,27,0,2,161,84,0,0,3,158,112,114,101,112,203,107,102,228,0,2,164,244,0,0,1,52,0,1,0,0,0,10,0,30,0,44,0,1,108,97,116,110,0,8,0,4,0,0,0,0,255,255,0,1,0,0,0,1,107,101,114,110,0,8,0,0,0,1,0,0,0,1,0,4,0,2,0,0,0,2,0,10,21,92,0,1,74,236,0,4,0,0,0,104,0,218,0,224,1,26,1,32,1,130,1,188,1,206,1,216,2,22,2,100,2,162,2,172,2,182,2,188,2,238,2,248,3,46,3,164,3,178,3,216,3,226,4,4,4,22,4,140,4,162,4,184,4,202,5,84,5,126,5,176,5,254,6,104,6,198,7,16,7,70,7,76,8,10,8,28,8,170,9,36,9,110,9,164,9,198,10,108,10,178,10,228,11,34,11,84,11,130,11,188,11,242,12,64,12,106,12,160,12,254,13,48,13,110,13,200,14,30,14,100,14,162,14,208,15,82,15,96,15,134,15,144,15,226,16,40,16,78,16,88,16,106,16,116,16,126,16,144,16,194,16,220,17,6,17,12,17,62,17,68,17,94,17,100,17,122,17,200,17,218,18,44,18,50,18,104,18,138,18,172,18,190,18,252,19,70,19,132,19,174,19,216,20,10,20,64,20,114,20,160,20,174,20,232,20,250,21,64,0,1,0,173,0,29,0,14,0,53,255,202,0,55,255,217,0,56,255,233,0,71,255,242,0,77,255,251,0,85,255,235,0,87,255,243,0,88,255,247,0,158,255,243,0,210,255,210,1,4,255,214,1,6,255,242,1,7,255,247,1,9,255,222,0,1,0,173,0,29,0,24,0,17,255,230,0,21,255,234,0,23,255,229,0,25,255,237,0,26,255,245,0,43,0,22,0,46,255,239,0,71,255,239,0,72,255,232,0,84,255,233,0,85,255,231,0,87,255,231,0,88,255,232,0,158,255,236,0,175,255,232,0,197,255,244,0,244,255,235,0,252,255,237,1,3,255,236,1,4,255,241,1,5,255,230,1,6,255,245,1,7,255,242,1,9,255,248,0,14,0,46,255,238,0,53,0,11,0,55,0,16,0,56,0,9,0,72,255,238,0,133,255,203,0,171,0,16,0,172,0,12,0,173,0,65,0,174,0,43,0,175,255,232,0,251,255,220,0,252,255,238,0,255,255,217,0,4,0,18,255,229,0,19,255,218,0,20,255,238,0,24,255,216,0,2,0,17,255,239,0,18,255,242,0,15,0,17,255,239,0,18,255,242,0,53,255,214,0,55,255,213,0,56,255,226,0,71,255,241,0,85,255,239,0,87,255,227,0,88,255,236,0,158,255,243,1,4,255,222,1,5,255,248,1,6,255,223,1,7,255,232,1,9,255,221,0,19,0,16,255,197,0,17,255,246,0,21,255,217,0,23,255,228,0,46,255,237,0,72,255,218,0,84,255,221,0,133,255,202,0,173,0,13,0,174,0,14,0,175,255,234,0,197,255,231,0,244,255,243,0,249,255,243,0,251,255,200,0,252,255,223,0,255,255,197,1,3,255,235,1,5,255,246,0,15,0,10,255,230,0,13,255,238,0,15,255,238,0,16,255,243,0,24,255,245,0,34,255,246,0,53,255,236,0,55,255,246,0,57,255,246,0,58,255,233,0,59,255,241,0,61,255,248,0,62,255,237,0,94,255,240,0,251,255,245,0,2,0,10,255,245,0,12,255,248,0,2,0,12,255,239,255,255,255,242,0,1,0,10,255,239,0,12,0,10,255,235,0,13,255,240,0,15,255,241,0,53,255,238,0,55,255,244,0,56,255,245,0,58,255,242,0,59,255,248,0,61,255,247,0,91,255,247,0,111,255,245,1,4,255,248,0,2,1,4,255,239,1,9,255,244,0,13,0,10,255,239,0,18,255,248,0,24,255,248,0,53,255,231,0,55,255,240,0,56,255,244,0,58,255,235,0,61,255,244,0,90,255,247,0,111,255,245,1,4,255,225,1,6,255,244,1,9,255,227,0,29,0,4,255,228,0,12,255,220,0,13,255,217,0,15,255,217,0,16,255,200,0,17,255,247,0,21,255,221,0,23,255,232,0,34,255,210,0,46,255,236,0,53,0,17,0,55,0,30,0,56,0,19,0,57,0,22,0,58,0,33,0,62,0,25,0,66,255,223,0,72,255,222,0,84,255,224,0,86,255,233,0,91,255,245,0,94,0,28,0,244,255,245,0,249,255,245,0,251,255,204,0,252,255,226,1,3,255,240,1,5,255,248,255,255,255,238,0,3,0,10,255,238,0,53,255,248,0,58,255,246,0,9,0,10,255,236,0,13,255,234,0,15,255,234,0,16,255,225,0,34,255,232,0,46,255,246,0,59,255,246,0,251,255,229,0,252,255,246,0,2,0,19,255,246,0,24,255,238,0,8,0,53,255,203,0,55,255,227,0,56,255,236,0,57,255,240,0,58,255,211,0,59,255,236,0,210,255,236,1,9,255,241,0,4,0,18,255,239,0,26,255,242,0,158,255,242,0,175,255,250,0,29,0,10,255,231,0,11,255,247,0,19,255,247,0,24,255,243,0,32,255,240,0,53,255,228,0,55,255,240,0,56,255,245,0,57,255,241,0,61,255,241,0,62,255,227,0,71,255,242,0,72,255,249,0,77,255,250,0,85,255,239,0,87,255,239,0,88,255,243,0,89,255,234,0,94,255,231,0,133,255,248,0,158,255,242,0,240,255,244,0,255,255,247,1,4,255,242,1,6,255,248,1,7,255,249,1,8,255,242,1,9,255,243,1,10,255,251,0,5,0,21,255,207,0,158,255,250,0,173,0,31,0,174,0,12,0,175,255,249,0,5,0,20,255,248,0,24,255,240,0,158,255,250,0,175,255,249,0,255,255,226,0,4,0,21,255,220,0,158,255,243,0,173,0,21,0,175,255,246,0,34,0,7,255,245,0,11,0,11,0,13,255,186,0,16,255,199,0,21,255,223,0,23,255,243,0,27,255,243,0,28,255,243,0,33,255,222,0,46,255,239,0,53,0,5,0,62,0,16,0,71,255,244,0,72,255,216,0,85,255,247,0,87,255,247,0,88,255,248,0,89,255,239,0,94,0,19,0,133,255,155,0,158,255,241,0,162,255,206,0,173,0,52,0,174,0,28,0,175,255,222,0,240,0,16,0,244,255,240,0,249,255,240,0,251,255,187,0,252,255,219,0,255,255,146,1,3,255,239,1,5,255,244,1,10,255,250,0,10,0,10,255,248,0,53,255,251,0,71,255,246,0,72,255,250,0,77,255,250,0,85,255,244,0,87,255,244,0,88,255,247,0,158,255,244,1,4,255,251,0,12,0,10,255,246,0,46,255,251,0,71,255,247,0,72,255,241,0,77,255,246,0,85,255,247,0,87,255,247,0,88,255,248,0,158,255,244,0,175,255,243,0,252,255,250,1,5,255,251,0,19,0,7,255,247,0,11,0,9,0,62,0,33,0,71,255,246,0,72,255,238,0,85,255,229,0,87,255,201,0,88,255,211,0,94,0,33,0,110,255,238,0,158,255,245,0,171,0,10,0,173,0,24,0,174,0,41,0,175,255,239,0,240,0,27,1,4,255,247,1,5,255,241,1,7,255,251,0,26,0,11,255,166,0,17,255,243,0,18,255,236,0,21,255,194,0,26,255,227,0,32,255,231,0,53,255,189,0,55,255,154,0,56,255,203,0,61,255,187,0,62,255,240,0,71,255,241,0,72,255,249,0,85,255,232,0,87,255,199,0,88,255,212,0,94,255,241,0,110,255,220,0,158,255,243,0,240,255,166,1,4,255,199,1,5,255,247,1,6,255,194,1,7,255,213,1,9,255,186,255,255,255,198,0,23,0,10,255,242,0,11,255,238,0,18,255,247,0,32,255,242,0,43,255,251,0,53,255,231,0,55,255,236,0,56,255,238,0,61,255,239,0,71,255,240,0,72,255,243,0,77,255,245,0,85,255,236,0,87,255,234,0,88,255,236,0,158,255,238,0,175,255,247,0,240,255,237,1,4,255,240,1,5,255,250,1,6,255,244,1,7,255,243,1,9,255,243,0,18,0,7,255,250,0,10,255,241,0,13,255,175,0,16,255,210,0,20,255,248,0,21,255,242,0,33,255,241,0,46,255,246,0,57,255,242,0,72,255,246,0,77,255,251,0,133,255,187,0,173,0,25,0,174,0,4,0,175,255,234,0,251,255,214,0,252,255,242,0,255,255,182,0,13,0,21,255,234,0,53,255,243,0,55,255,251,0,62,255,240,0,71,255,249,0,72,255,243,0,77,255,248,0,85,255,248,0,87,255,248,0,88,255,250,0,94,255,247,0,158,255,247,0,175,255,242,0,1,0,158,255,244,0,47,0,7,255,241,0,11,0,12,0,13,255,213,0,16,255,205,0,17,255,235,0,21,255,211,0,23,255,218,0,25,255,248,0,27,255,222,0,28,255,222,0,33,255,197,0,46,255,230,0,62,0,18,0,71,255,231,0,72,255,175,0,77,255,250,0,84,255,197,0,85,255,230,0,87,255,173,0,88,255,182,0,89,255,170,0,94,0,21,0,110,255,232,0,133,255,183,0,158,255,227,0,162,255,203,0,171,255,254,0,172,255,254,0,173,0,52,0,174,0,30,0,175,255,215,0,189,255,208,0,197,255,216,0,240,0,16,0,244,255,207,0,249,255,207,0,251,255,186,0,252,255,201,0,255,255,166,1,3,255,225,1,4,255,211,1,5,255,202,1,6,255,213,1,7,255,213,1,8,255,209,1,9,255,214,1,10,255,229,0,4,0,158,255,248,0,173,255,251,0,175,255,242,0,255,255,232,0,35,0,7,255,243,0,11,0,16,0,13,255,213,0,16,255,201,0,17,255,246,0,21,255,220,0,23,255,230,0,28,255,248,0,33,255,213,0,46,255,235,0,62,0,29,0,71,255,244,0,72,255,203,0,84,255,217,0,85,255,239,0,87,255,242,0,88,255,241,0,89,255,243,0,94,0,29,0,110,255,245,0,133,255,196,0,158,255,242,0,171,0,9,0,173,0,44,0,174,0,40,0,175,255,216,0,197,255,227,0,240,0,26,0,244,255,241,0,249,255,241,0,251,255,199,0,252,255,218,0,255,255,186,1,3,255,237,1,5,255,244,0,30,0,7,255,247,0,11,0,17,0,13,255,225,0,16,255,215,0,21,255,233,0,23,255,241,0,33,255,223,0,46,255,239,0,62,0,26,0,71,255,247,0,72,255,216,0,85,255,243,0,87,255,247,0,88,255,247,0,89,255,249,0,94,0,28,0,133,255,209,0,158,255,245,0,171,0,4,0,173,0,44,0,174,0,36,0,175,255,222,0,240,0,23,0,244,255,246,0,249,255,246,0,251,255,215,0,252,255,228,0,255,255,209,1,3,255,245,1,5,255,249,0,18,0,7,255,246,0,62,0,31,0,71,255,245,0,72,255,238,0,85,255,228,0,87,255,207,0,88,255,213,0,94,0,31,0,110,255,238,0,158,255,243,0,171,0,7,0,173,0,23,0,174,0,38,0,175,255,239,0,240,0,24,1,4,255,248,1,5,255,240,1,7,255,251,0,13,0,17,255,233,0,21,255,206,0,23,255,218,0,25,255,246,0,33,255,198,0,158,255,230,0,171,0,16,0,173,0,38,0,174,0,47,0,175,255,216,0,189,255,225,0,197,255,234,0,255,255,174,0,8,0,17,255,243,0,21,255,199,0,23,255,247,0,158,255,239,0,171,0,6,0,173,0,29,0,174,0,37,0,175,255,235,0,41,0,17,255,232,0,21,255,228,0,23,255,229,0,25,255,248,0,43,0,49,0,46,255,244,0,53,0,22,0,55,0,31,0,56,0,27,0,57,0,28,0,75,0,7,0,81,255,223,0,84,255,218,0,85,255,224,0,87,255,216,0,88,255,218,0,89,255,226,0,91,255,219,0,133,255,243,0,158,255,244,0,162,255,228,0,171,0,15,0,173,0,34,0,174,0,45,0,175,255,231,0,189,255,252,0,197,255,232,0,200,255,246,0,244,255,215,0,249,0,32,0,251,255,225,0,252,255,216,0,255,255,236,1,3,255,222,1,4,255,219,1,5,255,215,1,6,255,219,1,7,255,218,1,8,255,228,1,9,255,220,1,10,255,223,0,17,0,17,255,244,0,18,255,241,0,26,255,242,0,43,0,16,0,53,255,205,0,55,255,201,0,56,255,216,0,85,255,240,0,87,255,222,0,88,255,231,0,210,255,214,0,249,0,14,1,4,255,220,1,5,255,243,1,6,255,217,1,7,255,226,1,9,255,215,0,12,0,18,255,234,0,26,255,247,0,38,255,240,0,43,255,240,0,46,255,248,0,52,255,250,0,53,255,173,0,54,255,227,0,55,255,193,0,56,255,210,0,58,255,165,0,158,255,249,0,15,0,18,255,235,0,19,255,232,0,24,255,226,0,38,255,237,0,43,255,237,0,46,255,239,0,52,255,237,0,53,255,171,0,54,255,238,0,55,255,193,0,56,255,212,0,57,255,217,0,58,255,167,0,59,255,227,0,158,255,248,0,12,0,21,255,231,0,24,255,245,0,38,255,247,0,43,255,247,0,46,255,251,0,52,255,244,0,53,255,190,0,54,255,243,0,55,255,236,0,56,255,241,0,58,255,218,0,175,255,251,0,11,0,7,255,244,0,38,255,242,0,43,255,242,0,46,255,240,0,52,255,246,0,53,255,245,0,54,255,240,0,55,255,250,0,56,255,248,0,58,255,251,0,59,255,245,0,14,0,18,255,235,0,19,255,245,0,24,255,230,0,38,255,241,0,43,255,241,0,46,255,243,0,52,255,241,0,53,255,187,0,54,255,240,0,55,255,209,0,56,255,213,0,57,255,243,0,58,255,174,0,59,255,243,0,13,0,7,255,235,0,13,255,229,0,16,255,234,0,21,255,244,0,33,255,239,0,38,255,244,0,43,255,244,0,46,255,229,0,54,255,247,0,59,255,243,0,72,255,252,0,94,0,8,0,175,255,224,0,19,0,7,255,244,0,10,0,5,0,16,0,14,0,24,255,225,0,32,255,217,0,38,255,245,0,43,0,45,0,46,255,242,0,53,255,208,0,54,255,246,0,55,255,247,0,56,255,250,0,57,255,250,0,58,255,238,0,59,255,245,0,62,0,25,0,75,0,19,0,94,0,29,0,175,255,250,0,10,0,7,255,242,0,32,255,237,0,53,255,166,0,54,255,251,0,55,255,245,0,56,255,251,0,58,255,217,0,62,255,239,0,72,255,238,0,175,255,230,0,13,0,7,255,244,0,11,255,246,0,38,255,240,0,43,255,240,0,46,255,248,0,53,255,234,0,54,255,228,0,55,255,239,0,56,255,237,0,58,255,241,0,85,255,251,0,87,255,249,0,88,255,251,0,23,0,7,255,237,0,10,255,232,0,13,255,227,0,16,255,225,0,20,255,231,0,21,255,238,0,24,255,200,0,32,255,202,0,33,255,232,0,38,255,243,0,43,255,243,0,46,255,230,0,53,255,163,0,54,255,247,0,55,255,243,0,56,255,247,0,57,255,214,0,58,255,225,0,59,255,227,0,62,255,217,0,72,255,250,0,94,255,228,0,175,255,218,0,12,0,24,255,234,0,38,255,241,0,43,255,241,0,46,255,245,0,52,255,248,0,53,255,202,0,54,255,238,0,55,255,216,0,56,255,224,0,57,255,244,0,58,255,209,0,59,255,245,0,15,0,7,255,246,0,21,255,234,0,24,255,246,0,32,255,229,0,38,255,248,0,43,255,248,0,46,255,248,0,53,255,209,0,54,255,246,0,55,255,237,0,56,255,243,0,58,255,211,0,62,255,230,0,94,255,242,0,175,255,251,0,22,0,7,255,238,0,10,255,231,0,13,255,227,0,16,255,223,0,20,255,231,0,24,255,200,0,32,255,206,0,33,255,240,0,38,255,242,0,43,255,242,0,46,255,229,0,53,255,170,0,54,255,245,0,55,255,237,0,56,255,242,0,57,255,208,0,58,255,210,0,59,255,224,0,62,255,214,0,72,255,250,0,94,255,227,0,175,255,238,0,21,0,7,255,240,0,10,255,232,0,13,255,235,0,16,255,231,0,20,255,240,0,24,255,207,0,32,255,211,0,33,255,247,0,38,255,243,0,43,255,243,0,46,255,232,0,53,255,178,0,54,255,246,0,55,255,236,0,56,255,242,0,57,255,213,0,58,255,211,0,59,255,228,0,62,255,218,0,94,255,229,0,175,255,246,0,17,0,7,255,238,0,32,255,227,0,38,255,247,0,43,255,247,0,46,255,250,0,52,255,248,0,53,255,167,0,54,255,244,0,55,255,236,0,56,255,242,0,58,255,208,0,61,255,247,0,62,255,230,0,72,255,247,0,94,255,237,0,175,255,240,0,240,255,248,0,15,0,19,255,227,0,20,255,230,0,24,255,198,0,33,255,238,0,38,255,243,0,43,255,243,0,46,255,229,0,53,255,168,0,54,255,245,0,55,255,238,0,56,255,242,0,57,255,208,0,58,255,211,0,59,255,225,0,175,255,236,0,11,0,21,255,225,0,24,255,244,0,38,255,242,0,43,255,242,0,46,255,245,0,53,255,203,0,54,255,239,0,55,255,240,0,56,255,243,0,58,255,227,0,175,255,247,0,32,0,17,255,238,0,21,255,238,0,23,255,235,0,43,0,47,0,46,255,247,0,53,0,21,0,55,0,29,0,56,0,25,0,57,0,28,0,85,255,231,0,87,255,227,0,88,255,228,0,89,255,238,0,158,255,247,0,171,0,12,0,173,0,33,0,174,0,44,0,175,255,234,0,189,255,249,0,244,255,233,0,249,0,30,0,251,255,236,0,252,255,228,0,255,255,247,1,3,255,232,1,4,255,230,1,5,255,225,1,6,255,231,1,7,255,229,1,8,255,246,1,9,255,232,1,10,255,238,0,3,0,53,255,200,0,55,255,236,0,56,255,244,0,9,0,46,255,247,0,53,255,230,0,55,255,243,0,56,255,248,0,57,255,236,0,133,255,236,0,251,255,236,0,252,255,248,0,255,255,235,0,2,0,21,255,229,0,23,255,239,0,20,0,43,0,19,0,46,255,238,0,53,255,192,0,55,255,233,0,56,255,241,0,57,255,231,0,72,255,243,0,75,0,20,0,77,255,247,0,89,255,248,0,133,255,235,0,175,255,240,0,244,255,246,0,251,255,227,0,252,255,233,0,255,255,231,1,5,255,244,1,8,255,243,1,9,255,246,1,10,255,240,0,17,0,10,255,228,0,13,255,177,0,16,255,221,0,32,255,223,0,46,255,251,0,53,255,202,0,55,255,248,0,57,255,205,0,61,255,247,0,62,255,214,0,66,255,247,0,89,255,250,0,94,255,226,0,133,255,201,0,251,255,233,0,252,255,251,1,8,255,250,0,9,0,10,255,239,0,11,255,241,0,71,255,250,0,85,255,247,0,87,255,245,0,88,255,248,0,89,255,251,0,90,255,245,0,240,255,242,0,2,0,62,255,246,0,94,255,248,0,4,0,61,255,220,0,94,255,248,0,210,255,195,0,213,255,195,0,2,0,62,255,245,0,94,255,248,0,2,0,11,0,30,0,240,0,28,0,4,0,11,0,18,0,62,0,9,0,94,0,14,0,240,0,18,0,12,0,3,0,29,0,8,0,29,0,11,0,76,0,32,0,39,0,61,0,13,0,62,0,44,0,94,0,33,0,209,0,37,0,210,0,24,0,212,0,37,0,213,0,24,0,240,0,81,0,6,0,11,0,43,0,32,0,27,0,61,0,14,0,62,0,39,0,94,0,44,0,240,0,48,0,10,0,7,255,247,0,10,255,232,0,11,255,240,0,13,255,247,0,32,255,242,0,61,255,246,0,62,255,240,0,89,255,248,0,94,255,243,0,240,255,241,0,1,0,173,0,37,0,12,0,7,255,239,0,11,0,5,0,16,255,209,0,33,255,210,0,110,255,245,0,161,255,187,0,169,255,174,0,173,0,44,0,174,0,28,0,189,255,224,0,197,255,232,0,240,0,9,0,1,0,173,0,37,0,6,0,161,255,187,0,169,255,174,0,173,0,44,0,174,0,28,0,189,255,224,0,197,255,232,0,1,0,143,0,6,0,5,0,133,255,228,0,143,0,10,0,173,0,11,0,251,255,236,0,255,255,235,0,19,0,2,255,247,0,10,255,228,0,11,255,241,0,18,255,242,0,19,255,240,0,24,255,229,0,26,255,248,0,32,255,221,0,61,255,220,0,62,255,214,0,94,255,224,0,240,255,235,0,255,255,247,1,4,255,238,1,6,255,244,1,7,255,246,1,8,255,243,1,9,255,233,1,10,255,250,0,4,0,21,255,221,0,32,255,242,0,62,255,238,0,94,255,246,0,20,0,10,255,224,0,11,255,244,0,16,255,246,0,18,255,241,0,19,255,229,0,24,255,222,0,32,255,223,0,61,255,222,0,62,255,213,0,94,255,222,0,240,255,240,0,251,255,247,0,252,255,251,0,255,255,231,1,4,255,242,1,6,255,247,1,7,255,249,1,8,255,232,1,9,255,234,1,10,255,242,0,1,0,21,255,241,0,13,0,10,255,240,0,13,255,199,0,16,255,217,0,20,255,245,0,21,255,247,0,24,255,218,0,32,255,218,0,33,255,242,0,62,255,215,0,94,255,228,0,251,255,213,0,252,255,243,0,255,255,188,0,8,0,10,255,239,0,11,255,244,0,24,255,247,0,32,255,236,0,61,255,240,0,62,255,226,0,94,255,232,0,240,255,239,0,8,0,10,255,235,0,24,255,244,0,32,255,237,0,61,255,243,0,62,255,217,0,94,255,233,0,240,255,243,0,252,255,252,0,4,0,21,255,247,0,62,255,234,0,94,255,248,1,3,255,252,0,15,0,11,255,221,0,17,255,246,0,18,255,232,0,26,255,237,0,32,255,232,0,61,255,201,0,62,255,231,0,94,255,236,0,110,255,236,0,240,255,220,1,4,255,210,1,5,255,243,1,6,255,219,1,7,255,227,1,9,255,205,0,18,0,10,255,237,0,11,255,238,0,18,255,241,0,24,255,243,0,26,255,247,0,32,255,229,0,61,255,223,0,62,255,220,0,94,255,228,0,110,255,248,0,240,255,234,0,244,255,252,0,249,255,252,1,4,255,238,1,5,255,249,1,6,255,240,1,7,255,241,1,9,255,236,0,15,0,10,255,227,0,13,255,188,0,16,255,223,0,19,255,245,0,20,255,234,0,24,255,215,0,32,255,223,0,61,255,243,0,62,255,213,0,94,255,224,0,251,255,227,0,252,255,248,0,255,255,199,1,8,255,243,1,10,255,251,0,10,0,21,255,242,0,24,255,244,0,32,255,226,0,61,255,228,0,62,255,224,0,94,255,232,0,240,255,243,1,4,255,249,1,6,255,252,1,9,255,246,0,10,0,10,255,233,0,11,255,245,0,24,255,244,0,32,255,232,0,61,255,239,0,62,255,223,0,94,255,230,0,240,255,238,0,255,255,250,1,8,255,252,0,12,0,10,255,241,0,13,255,222,0,16,255,220,0,21,255,230,0,24,255,219,0,32,255,216,0,33,255,223,0,62,255,218,0,94,255,230,0,251,255,210,0,252,255,238,0,255,255,195,0,13,0,10,255,230,0,13,255,248,0,16,255,243,0,24,255,240,0,32,255,236,0,61,255,246,0,62,255,215,0,94,255,225,0,240,255,245,0,251,255,244,0,252,255,249,0,255,255,247,1,10,255,252,0,12,0,10,255,245,0,13,255,223,0,16,255,217,0,21,255,243,0,24,255,223,0,32,255,222,0,33,255,230,0,62,255,217,0,94,255,230,0,251,255,219,0,252,255,240,0,255,255,213,0,11,0,10,255,243,0,13,255,231,0,16,255,226,0,24,255,223,0,32,255,222,0,33,255,239,0,62,255,218,0,94,255,230,0,251,255,227,0,252,255,242,0,255,255,221,0,3,0,21,255,247,0,62,255,233,0,94,255,247,0,14,0,10,255,248,0,13,255,221,0,16,255,215,0,21,255,226,0,23,255,247,0,24,255,225,0,32,255,222,0,33,255,219,0,62,255,218,0,94,255,232,0,251,255,205,0,252,255,236,0,255,255,198,1,3,255,252,0,4,0,21,255,220,0,32,255,227,0,62,255,222,0,94,255,236,0,17,0,11,255,197,0,17,255,241,0,18,255,231,0,21,255,199,0,26,255,228,0,32,255,228,0,61,255,186,0,62,255,227,0,94,255,233,0,110,255,221,0,240,255,192,1,4,255,207,1,5,255,245,1,6,255,186,1,7,255,210,1,9,255,176,255,255,255,208,0,4,0,19,255,239,0,20,255,246,0,24,255,235,0,18,255,240,0,2,54,70,0,4,0,0,54,206,56,224,0,89,0,77,0,0,255,248,255,146,255,220,255,237,255,245,255,234,255,238,255,241,255,203,255,237,255,223,255,218,255,243,255,234,255,146,255,213,255,243,255,236,255,244,255,241,255,146,255,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,210,255,203,255,250,255,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,231,255,224,0,0,0,0,0,0,255,224,0,0,0,0,255,227,255,231,255,243,255,229,255,243,255,245,255,243,255,233,255,247,255,235,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,146,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,124,255,121,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,234,255,222,0,0,0,0,0,0,0,0,0,0,255,243,0,0,0,0,255,231,0,0,0,0,255,193,255,216,255,238,255,248,255,242,255,237,255,247,255,248,255,247,255,248,255,225,255,243,255,238,255,236,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,146,255,215,0,0,255,222,0,0,255,242,0,0,0,0,255,243,0,0,0,0,0,0,255,124,255,121,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,208,255,218,255,214,0,0,0,0,0,0,255,222,0,0,0,7,255,230,0,0,0,0,255,243,0,0,0,0,0,0,255,228,255,241,255,243,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,244,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,218,0,0,0,0,0,0,255,226,0,0,0,0,0,0,0,0,0,0,255,246,0,0,0,0,0,0,255,232,0,0,255,245,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,247,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,245,0,0,255,247,0,0,255,250,255,213,255,192,255,244,255,217,0,0,255,245,0,0,0,0,255,240,0,0,0,0,0,0,255,205,255,204,255,202,255,207,255,219,0,0,0,0,255,241,255,229,0,0,0,0,255,214,0,0,255,213,0,0,255,212,255,239,255,208,255,249,255,221,255,228,255,246,255,241,255,212,255,246,255,223,255,231,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,251,0,0,0,0,0,0,0,0,255,229,255,251,255,236,0,0,0,0,0,0,255,251,0,0,255,250,255,242,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,250,255,250,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,241,0,0,0,0,0,0,0,0,0,0,255,195,0,0,0,0,0,0,255,242,0,0,255,226,0,0,255,246,0,0,0,0,255,241,255,249,0,0,255,242,0,0,0,0,0,0,255,249,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,249,255,249,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,249,255,250,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,241,255,237,0,0,0,0,0,0,255,250,255,250,255,226,0,0,255,240,0,0,255,249,0,0,255,242,255,244,255,248,255,250,255,250,0,0,255,241,0,0,0,0,255,227,255,250,0,0,0,0,0,0,0,0,0,0,0,0,255,249,255,250,0,0,0,0,255,247,255,228,255,243,255,248,255,225,255,235,0,0,0,0,255,244,0,0,0,0,255,245,0,0,255,251,0,0,255,237,255,244,255,249,0,0,0,0,255,229,0,0,255,246,0,0,0,0,0,0,255,249,255,249,255,228,255,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,241,0,0,0,0,0,0,0,0,0,0,255,244,0,0,0,0,0,0,255,240,255,251,255,235,0,0,255,246,0,0,0,0,255,238,255,240,0,0,255,245,0,0,0,0,0,0,255,247,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,243,255,242,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,241,255,243,0,0,255,248,0,0,255,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,186,255,203,255,199,255,212,255,217,255,236,255,186,255,234,0,0,0,0,255,217,255,248,0,0,255,248,0,0,0,0,0,0,255,211,255,236,255,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,251,255,249,0,0,0,0,255,217,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,251,0,0,0,0,0,0,0,0,0,0,0,0,255,249,255,242,0,0,0,0,0,0,0,0,0,0,255,250,255,249,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,250,255,250,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,251,255,241,0,0,255,243,0,0,0,0,255,250,0,0,0,0,0,0,255,246,255,242,255,246,0,0,0,0,0,0,0,0,0,0,255,245,255,247,0,0,0,0,0,0,0,0,0,0,255,247,255,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,247,255,247,0,0,255,244,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,246,255,247,255,248,0,0,0,0,0,0,255,251,0,0,0,0,255,247,255,247,255,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,246,255,242,255,246,0,0,0,0,0,0,0,0,0,0,255,245,255,247,0,0,0,0,0,0,0,0,0,0,255,247,255,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,247,255,247,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,244,0,0,0,0,0,0,255,222,0,0,255,227,0,0,255,224,0,0,0,0,255,232,255,199,0,0,255,228,0,0,255,250,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,196,0,0,0,0,0,0,255,246,0,0,255,222,0,0,255,249,255,166,255,158,255,249,255,181,0,0,255,232,0,0,0,0,255,238,0,0,0,0,0,0,255,167,255,167,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,250,255,244,255,250,0,0,0,0,255,251,255,238,255,233,255,244,255,233,255,251,255,251,255,251,0,0,255,248,255,246,255,249,0,0,255,236,255,236,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,245,255,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,242,255,239,0,0,0,0,0,0,255,251,255,250,255,229,255,250,255,242,255,228,255,250,0,0,255,242,255,245,255,247,255,250,255,250,0,0,255,242,0,0,0,0,255,230,255,251,0,0,0,0,0,0,0,0,0,0,0,0,255,249,255,250,0,0,0,0,255,247,255,232,255,244,255,248,255,229,255,238,0,0,0,0,255,245,255,251,0,0,255,246,0,0,0,0,0,0,255,240,255,245,255,250,0,0,0,0,255,231,0,0,255,246,0,0,0,0,0,0,255,250,255,249,255,229,255,227,0,0,255,243,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,175,255,216,255,242,255,243,255,248,0,0,255,175,0,0,0,0,0,0,255,250,0,0,0,0,0,0,0,0,0,0,0,0,255,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,251,255,250,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,251,255,237,0,0,255,242,0,0,255,248,0,0,255,245,255,244,255,248,0,0,0,0,0,0,0,0,0,0,255,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,250,255,249,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,250,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,251,0,0,0,0,0,0,0,0,0,0,255,250,255,240,0,0,0,0,0,0,0,0,0,0,255,250,255,244,0,0,0,0,0,0,0,0,0,0,0,0,255,251,0,0,255,243,255,241,255,242,0,0,255,251,0,0,0,0,0,0,0,0,0,0,0,0,255,250,255,241,255,244,0,0,0,0,0,0,0,0,0,0,0,0,255,250,255,250,255,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,216,255,214,255,202,255,195,255,177,0,0,255,195,255,213,255,197,0,0,0,0,255,169,255,171,0,0,255,232,0,0,0,0,0,0,255,168,255,208,255,207,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,250,255,247,0,0,0,0,255,197,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,243,255,234,0,0,0,0,0,0,255,248,255,242,255,240,0,0,255,233,0,0,255,245,0,0,255,243,255,240,255,242,255,243,255,243,0,0,255,243,0,0,0,0,0,0,255,242,255,250,0,0,0,0,0,0,0,0,0,0,255,240,255,244,255,250,0,0,0,0,0,0,0,0,0,0,0,0,255,251,255,250,255,249,255,250,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,244,255,250,255,250,0,0,0,0,0,0,0,0,0,0,0,0,255,245,255,243,255,245,0,0,0,0,0,0,255,250,255,250,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,238,255,213,255,207,255,216,255,196,0,0,255,220,255,213,255,214,0,0,0,0,255,220,255,243,0,0,255,244,0,0,0,0,0,0,255,220,255,243,255,241,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,244,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,248,255,226,255,219,255,216,255,217,255,219,255,230,255,225,255,230,0,0,0,0,255,227,255,248,0,0,255,249,0,0,0,0,0,0,255,224,255,247,255,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,251,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,243,0,0,0,0,0,0,255,223,0,0,255,226,0,0,255,224,0,0,0,0,255,232,255,206,0,0,255,229,0,0,255,251,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,237,255,215,255,201,0,0,0,0,0,0,255,232,255,180,255,180,0,0,255,181,0,0,255,197,255,222,255,215,255,192,255,189,255,171,255,186,255,198,255,215,255,193,0,0,0,0,255,190,255,217,0,0,255,230,0,0,0,0,0,0,255,187,255,229,255,223,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,237,255,221,255,214,0,0,0,0,0,0,0,0,255,248,0,13,0,13,0,7,0,0,255,215,255,216,0,33,255,230,0,33,255,228,0,0,0,0,0,0,0,0,0,0,0,31,255,225,0,0,255,223,255,223,255,235,255,235,255,214,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,229,0,0,0,0,0,0,0,0,255,251,255,217,0,0,0,0,255,246,255,227,255,245,255,214,0,0,255,234,0,0,0,0,255,224,255,242,0,0,255,238,0,0,0,0,0,0,255,235,255,248,255,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,241,255,241,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,241,255,241,0,23,255,233,0,24,255,237,0,0,0,0,0,0,255,250,0,0,0,23,0,0,0,0,255,246,255,246,0,0,0,0,255,251,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,227,255,218,255,213,0,0,0,0,0,0,255,214,0,0,0,36,255,215,255,216,0,0,255,226,0,0,0,0,0,0,255,214,0,0,255,215,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,247,255,220,255,201,0,0,255,219,0,0,255,236,0,0,0,0,255,234,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,245,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,234,0,0,0,0,255,236,255,240,255,237,0,0,0,0,0,0,0,0,0,0,0,0,255,186,255,183,0,0,0,0,0,0,0,0,0,0,255,251,255,246,0,0,0,0,0,0,0,0,0,0,0,0,255,231,255,229,255,210,0,0,255,238,255,243,255,231,255,248,255,230,0,0,0,0,0,0,0,0,0,0,255,246,255,227,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,246,255,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,247,255,240,0,0,0,0,0,0,0,0,255,246,0,0,255,234,0,0,0,0,255,245,255,237,255,246,0,0,0,0,0,0,0,0,255,246,0,0,255,181,255,178,0,0,0,0,0,0,0,0,0,0,255,251,255,250,255,238,0,0,0,0,0,0,0,0,0,0,255,232,255,224,255,217,0,0,255,247,255,251,255,226,0,0,255,234,0,0,0,0,0,0,0,0,0,0,255,227,255,217,255,247,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,219,0,0,0,0,0,0,255,249,0,0,255,243,0,0,0,0,0,0,0,0,0,0,0,0,255,247,255,244,0,0,0,0,0,0,0,0,0,0,0,0,255,216,255,213,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,228,255,240,0,0,0,0,0,0,255,239,0,0,255,245,0,0,0,0,0,0,0,0,0,0,255,244,255,232,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,249,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,242,255,245,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,251,0,0,0,0,0,0,0,0,0,0,0,0,255,241,0,0,0,0,255,251,255,241,255,250,0,0,0,0,0,0,0,0,0,0,0,0,255,189,255,186,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,251,0,0,0,0,0,0,0,0,0,0,255,238,255,223,255,220,0,0,255,252,0,0,255,227,0,0,255,237,0,0,0,0,0,0,0,0,0,0,255,230,255,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,232,255,229,255,211,255,251,255,246,0,0,255,239,255,229,0,0,0,0,0,0,0,0,0,0,255,244,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,249,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,245,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,223,255,221,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,245,0,0,0,0,0,0,0,0,0,0,255,241,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,250,0,0,0,0,0,0,0,0,0,0,0,0,255,238,255,163,0,0,255,242,255,238,255,243,255,238,255,241,255,231,0,0,0,0,0,0,255,187,255,184,255,162,255,198,255,214,255,249,255,245,255,251,255,248,0,0,255,248,0,0,0,0,0,0,0,0,255,235,255,224,255,214,0,0,255,243,255,248,255,225,0,0,255,235,0,0,0,0,0,0,0,0,0,0,255,232,255,216,0,0,255,233,0,0,0,0,0,0,0,0,0,0,255,248,255,231,255,238,0,0,0,0,255,244,0,0,0,0,0,0,0,0,0,0,255,241,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,247,0,0,0,0,255,242,255,244,255,242,255,244,255,238,0,0,0,0,0,0,0,0,0,0,255,242,255,247,255,246,0,0,255,245,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,242,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,241,0,0,0,0,255,251,255,234,0,0,255,238,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,234,0,0,0,0,0,0,0,0,0,0,0,0,255,229,255,227,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,251,0,0,255,247,0,0,0,0,255,247,0,0,0,0,255,249,255,240,255,237,0,0,0,0,0,0,0,0,0,0,0,0,255,245,255,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,246,0,0,0,0,0,0,0,0,0,0,255,239,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,240,0,0,0,0,0,0,0,0,0,0,0,0,255,236,255,167,0,0,255,245,255,237,255,246,255,237,255,238,255,238,0,0,255,246,0,0,255,182,255,179,255,173,255,192,255,212,255,218,255,227,255,251,255,249,255,237,255,248,0,0,0,0,0,0,0,0,255,234,255,222,255,214,0,0,255,247,255,251,255,222,0,0,255,236,0,0,0,0,0,0,0,0,0,0,255,224,255,213,255,247,255,223,0,0,0,0,0,0,0,0,0,0,0,0,255,230,255,237,255,229,0,0,255,244,0,0,0,0,0,0,0,0,0,0,255,241,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,183,0,0,0,0,255,242,255,244,255,242,255,243,255,235,0,0,0,0,0,0,255,211,255,209,255,164,255,216,255,218,255,246,255,242,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,244,255,223,255,228,0,0,0,0,0,0,255,226,0,0,255,239,0,0,0,0,0,0,0,0,0,0,255,233,255,215,0,0,255,232,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,242,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,234,255,227,255,211,255,249,255,243,0,0,255,237,255,227,0,0,0,0,0,0,0,0,0,0,255,243,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,233,255,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,241,255,244,0,0,0,0,0,0,0,0,0,0,0,0,255,203,255,200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,241,255,224,255,225,0,0,0,0,0,0,255,229,0,0,255,235,0,0,0,0,0,0,0,0,0,0,255,231,255,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,252,0,0,255,244,0,0,0,0,0,0,0,0,0,0,0,0,255,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,234,255,233,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,227,255,216,255,250,255,247,255,252,0,0,255,227,0,0,0,0,0,0,0,0,0,0,255,242,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,226,255,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,236,255,223,255,252,255,251,0,0,0,0,255,235,0,0,0,0,0,0,0,0,0,0,255,243,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,227,255,225,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,247,0,0,0,0,255,252,255,238,0,0,255,236,0,0,0,0,0,0,0,0,0,0,0,0,255,247,255,240,0,0,0,0,0,0,0,0,0,0,0,0,255,224,255,222,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,238,255,225,255,220,0,0,0,0,0,0,0,0,255,250,0,0,0,0,0,0,0,0,0,0,0,0,255,225,255,214,255,250,255,246,255,252,0,0,255,225,0,0,0,0,0,0,0,0,0,0,255,243,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,227,255,225,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,205,0,0,0,0,0,0,0,0,255,227,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,231,255,214,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,245,0,0,0,0,0,0,0,0,0,0,0,0,255,251,0,0,0,0,0,0,0,0,0,0,255,240,0,0,0,0,0,0,255,245,0,0,255,232,0,0,0,0,0,0,0,0,0,0,0,0,255,242,255,244,0,0,0,0,0,0,0,0,0,0,0,0,255,219,255,216,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,221,255,242,0,0,0,0,0,0,255,232,0,0,255,242,0,0,0,0,0,0,0,0,0,0,255,246,255,222,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,244,255,229,255,222,255,229,0,0,0,0,255,223,0,0,0,34,255,225,255,227,0,0,255,231,0,0,0,0,0,0,255,227,255,232,255,233,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,247,0,0,0,0,0,0,255,248,0,0,255,226,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,229,255,197,255,245,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,237,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,229,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,231,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,243,0,0,255,240,255,238,0,0,0,0,0,0,255,247,0,0,0,0,0,0,0,0,0,0,0,0,255,241,255,198,0,0,255,248,0,0,0,0,0,0,255,234,0,0,0,0,255,233,0,0,0,0,255,204,255,195,255,220,255,230,255,224,255,223,0,0,255,247,255,236,255,248,255,226,255,227,255,223,255,226,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,240,255,247,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,233,255,241,255,243,255,241,0,0,0,0,255,246,0,0,255,219,255,243,0,0,255,247,0,0,255,247,0,0,255,245,255,241,255,241,255,246,0,0,0,0,0,0,0,0,0,0,0,0,255,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,247,255,242,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,177,255,235,0,0,0,0,0,0,0,0,255,177,0,0,0,0,255,228,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,203,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,243,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,245,255,243,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,247,0,0,0,0,0,0,0,0,0,0,255,247,0,0,255,245,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,236,255,237,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,123,0,0,0,0,0,0,0,0,255,236,255,189,255,190,255,235,255,217,255,209,255,241,0,0,255,124,255,205,255,194,255,182,255,193,0,0,0,0,255,228,0,0,0,0,255,213,255,227,0,0,0,0,0,0,0,0,0,0,255,211,255,217,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,243,255,248,255,225,255,245,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,226,255,227,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,245,0,0,0,0,0,0,0,0,0,0,0,0,255,110,0,0,0,0,0,0,0,0,255,234,255,174,255,184,255,237,255,210,255,203,255,234,255,181,255,110,255,200,255,179,255,167,255,178,255,192,255,110,255,223,0,0,0,6,255,200,255,215,0,0,255,234,0,0,0,0,0,0,255,198,255,204,255,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,243,255,244,255,213,255,241,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,214,255,215,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,220,0,0,255,248,255,248,0,0,0,0,255,234,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,146,255,215,0,0,255,222,0,0,255,242,0,0,0,0,255,243,0,0,0,0,0,0,0,0,255,121,255,214,255,213,255,226,0,0,0,0,255,241,255,239,0,0,255,242,255,222,0,0,255,221,0,0,0,0,0,0,0,0,0,0,255,227,255,236,0,0,0,0,0,0,255,248,255,223,255,232,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,232,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,240,0,0,255,248,255,223,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,217,255,216,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,246,0,0,255,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,239,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,228,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,240,255,239,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,197,0,0,0,0,0,0,0,0,0,0,255,233,0,0,255,247,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,227,255,225,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,247,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,199,0,0,0,0,0,0,0,0,0,0,255,199,255,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,237,255,243,0,0,0,0,0,0,255,233,0,0,255,243,0,0,0,0,0,0,0,0,0,0,255,235,255,217,0,0,255,244,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,243,0,0,0,0,0,0,0,0,0,0,255,227,0,0,255,230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,208,0,0,0,0,0,0,0,0,0,0,255,221,0,0,255,244,255,203,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,203,255,201,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,251,255,243,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,252,255,241,255,239,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,247,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,248,255,232,255,251,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,228,255,227,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,243,255,234,255,235,255,244,255,244,255,223,255,222,0,0,0,0,0,0,255,223,0,0,255,240,0,0,255,247,255,250,0,0,0,0,255,224,255,214,255,248,255,223,0,0,0,0,0,0,0,0,0,0,0,0,255,242,0,0,255,231,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,188,0,0,0,0,0,0,0,0,0,0,255,188,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,246,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,225,255,222,0,0,0,0,0,0,0,0,255,226,255,222,255,243,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,223,0,0,0,0,0,0,0,0,255,240,255,223,255,247,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,232,0,0,0,0,0,0,0,0,255,247,255,231,255,250,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,243,0,0,0,0,0,0,0,0,0,0,255,227,0,0,255,232,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,238,255,221,0,0,0,0,0,0,0,0,255,223,255,221,255,235,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,236,0,0,0,0,0,0,0,0,0,0,255,226,0,0,255,244,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,28,0,3,0,3,0,0,0,7,0,9,0,1,0,11,0,13,0,4,0,15,0,26,0,7,0,30,0,30,0,19,0,33,0,40,0,20,0,43,0,46,0,28,0,49,0,49,0,32,0,51,0,61,0,33,0,66,0,72,0,44,0,76,0,77,0,51,0,83,0,85,0,53,0,87,0,92,0,56,0,97,0,97,0,62,0,110,0,111,0,63,0,126,0,126,0,65,0,157,0,158,0,66,0,161,0,163,0,68,0,171,0,175,0,71,0,209,0,210,0,76,0,212,0,213,0,78,0,221,0,221,0,80,0,240,0,246,0,81,0,249,0,252,0,88,1,0,1,0,0,92,1,2,1,10,0,93,1,12,1,12,0,102,255,255,255,255,0,103,0,2,0,22,0,3,0,3,0,0,0,7,0,7,0,1,0,9,0,9,0,2,0,13,0,16,0,3,0,21,0,21,0,7,0,24,0,24,0,8,0,33,0,61,0,9,0,66,0,92,0,38,0,97,0,97,0,65,0,107,0,107,0,66,0,110,0,110,0,67,0,122,0,122,0,68,0,126,0,149,0,69,0,151,0,181,0,93,0,183,0,190,0,124,0,193,0,200,0,132,0,207,0,214,0,140,0,220,0,221,0,148,0,240,0,245,0,150,0,247,0,248,0,156,0,250,1,2,0,158,1,4,1,12,0,167,0,1,0,7,1,6,0,1,0,0,0,2,0,0,0,0,0,0,0,3,0,4,0,5,0,6,0,0,0,0,0,0,0,0,0,7,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,10,0,11,0,12,0,13,0,14,0,15,0,16,0,17,0,17,0,18,0,19,0,20,0,21,0,17,0,22,0,23,0,22,0,24,0,25,0,26,0,27,0,28,0,29,0,30,0,31,0,32,0,33,0,34,0,0,0,0,0,0,0,0,0,35,0,36,0,37,0,38,0,39,0,40,0,41,0,42,0,43,0,43,0,44,0,45,0,42,0,42,0,46,0,46,0,47,0,48,0,49,0,50,0,47,0,51,0,52,0,53,0,54,0,55,0,56,0,0,0,0,0,0,0,0,0,57,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,58,0,0,0,0,0,59,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,0,0,0,0,0,0,0,61,0,10,0,10,0,10,0,10,0,10,0,10,0,14,0,12,0,14,0,14,0,14,0,14,0,17,0,17,0,17,0,17,0,13,0,17,0,22,0,22,0,22,0,22,0,22,0,0,0,22,0,27,0,27,0,27,0,27,0,31,0,62,0,63,0,35,0,35,0,35,0,35,0,35,0,35,0,39,0,37,0,39,0,39,0,39,0,39,0,43,0,43,0,43,0,43,0,64,0,42,0,46,0,46,0,46,0,46,0,46,0,0,0,46,0,47,0,47,0,47,0,47,0,54,0,36,0,54,0,0,0,0,0,43,0,14,0,39,0,25,0,49,0,31,0,32,0,55,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,4,0,65,0,66,0,67,0,65,0,66,0,67,0,0,0,0,0,0,0,0,0,0,0,58,0,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,0,71,0,72,0,73,0,70,0,74,0,0,0,75,0,75,0,0,0,76,0,69,0,78,0,75,0,79,0,70,0,80,0,79,0,81,0,0,0,82,0,83,0,84,0,85,0,86,0,87,0,88,0,70,0,77,0,1,0,2,1,11,0,73,0,23,0,0,0,0,0,0,0,1,0,23,0,0,0,64,0,50,0,0,0,2,0,14,0,15,0,3,0,0,0,74,0,76,0,0,0,4,0,0,0,5,0,67,0,0,0,0,0,70,0,71,0,0,0,0,0,0,0,51,0,6,0,16,0,27,0,28,0,27,0,29,0,27,0,28,0,27,0,27,0,75,0,27,0,27,0,7,0,27,0,28,0,27,0,28,0,27,0,30,0,37,0,31,0,38,0,39,0,40,0,24,0,41,0,0,0,52,0,65,0,0,0,0,0,0,0,17,0,62,0,18,0,18,0,18,0,42,0,8,0,62,0,63,0,63,0,62,0,53,0,32,0,32,0,18,0,32,0,18,0,32,0,19,0,43,0,25,0,54,0,55,0,44,0,26,0,33,0,0,0,0,0,56,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,0,0,0,0,0,57,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,0,0,0,0,0,0,0,0,0,16,0,16,0,16,0,16,0,16,0,16,0,9,0,28,0,29,0,29,0,29,0,29,0,27,0,27,0,27,0,27,0,27,0,27,0,28,0,28,0,28,0,28,0,28,0,0,0,28,0,31,0,31,0,31,0,31,0,24,0,27,0,45,0,17,0,17,0,17,0,17,0,17,0,17,0,17,0,18,0,18,0,18,0,18,0,18,0,63,0,63,0,63,0,63,0,10,0,32,0,18,0,18,0,18,0,18,0,18,0,0,0,18,0,25,0,25,0,25,0,25,0,26,0,32,0,26,0,0,0,0,0,63,0,28,0,18,0,30,0,19,0,24,0,41,0,33,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,14,0,35,0,36,0,21,0,35,0,36,0,21,0,0,0,0,0,0,0,15,0,0,0,20,0,66,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,58,0,34,0,22,0,34,0,68,0,34,0,22,0,34,0,34,0,69,0,34,0,11,0,13,0,34,0,22,0,12,0,34,0,22,0,34,0,72,0,46,0,59,0,60,0,61,0,47,0,48,0,49,0,22,0,34,0,1,0,0,0,10,0,32,0,58,0,1,108,97,116,110,0,8,0,4,0,0,0,0,255,255,0,2,0,0,0,1,0,2,97,97,108,116,0,14,115,109,99,112,0,20,0,0,0,1,0,0,0,0,0,1,0,1,0,2,0,6,0,14,0,1,0,0,0,1,0,78,0,1,0,0,0,1,0,8,0,2,0,124,0,28,0,251,0,241,0,242,0,243,0,244,0,245,0,246,0,247,0,248,0,249,0,250,1,12,0,252,0,253,0,254,1,0,1,1,1,2,1,3,1,4,1,5,1,6,1,7,1,8,1,9,1,10,0,255,1,11,0,2,0,62,0,28,0,251,0,241,0,242,0,243,0,244,0,245,0,246,0,247,0,248,0,249,0,250,1,12,0,252,0,253,0,254,1,0,1,1,1,2,1,3,1,4,1,5,1,6,1,7,1,8,1,9,1,10,0,255,1,11,0,2,0,3,0,66,0,91,0,0,0,165,0,165,0,26,0,195,0,195,0,27,0,0,0,3,1,245,1,144,0,5,0,0,2,188,2,138,0,0,0,140,2,188,2,138,0,0,1,221,0,50,0,250,8,2,2,11,8,3,5,2,2,2,0,4,128,0,0,47,0,0,0,11,0,0,0,0,0,0,0,0,80,89,82,83,0,64,0,32,33,34,3,197,255,6,0,0,3,197,0,250,0,0,0,1,0,0,0,0,1,234,2,188,0,0,0,32,0,2,0,0,0,3,0,0,0,3,0,0,2,222,0,1,0,0,0,0,0,28,0,3,0,1,0,0,1,230,0,6,1,202,0,0,0,32,0,224,0,1,0,2,0,3,0,4,0,5,0,6,0,7,0,8,0,9,0,10,0,11,0,12,0,13,0,14,0,15,0,16,0,17,0,18,0,19,0,20,0,21,0,22,0,23,0,24,0,25,0,26,0,27,0,28,0,29,0,30,0,31,0,32,0,33,0,34,0,35,0,36,0,37,0,38,0,39,0,40,0,41,0,42,0,43,0,44,0,45,0,46,0,47,0,48,0,49,0,50,0,51,0,52,0,53,0,54,0,55,0,56,0,57,0,58,0,59,0,60,0,61,0,62,0,63,0,64,0,65,0,66,0,67,0,68,0,69,0,70,0,71,0,72,0,73,0,74,0,75,0,76,0,77,0,78,0,79,0,80,0,81,0,82,0,83,0,84,0,85,0,86,0,87,0,88,0,89,0,90,0,91,0,92,0,93,0,94,0,95,0,0,0,239,0,0,0,211,0,201,0,214,0,218,0,215,0,216,0,203,0,219,0,196,0,220,0,194,0,0,0,199,0,0,0,0,0,209,0,210,0,212,0,213,0,217,0,207,0,208,0,206,0,240,0,197,0,221,0,195,0,0,0,200,0,198,0,96,0,97,0,98,0,99,0,100,0,101,0,102,0,103,0,104,0,105,0,106,0,107,0,108,0,109,0,110,0,0,0,111,0,112,0,113,0,114,0,115,0,116,0,117,0,118,0,119,0,120,0,121,0,122,0,123,0,124,0,125,0,126,0,127,0,128,0,129,0,130,0,131,0,132,0,133,0,134,0,135,0,136,0,137,0,138,0,139,0,140,0,141,0,142,0,143,0,144,0,145,0,146,0,147,0,148,0,149,0,150,0,151,0,152,0,153,0,154,0,155,0,156,0,157,0,158,0,159,0,160,0,161,0,162,0,163,0,164,0,165,0,166,0,167,0,168,0,169,0,170,0,171,0,172,0,173,0,174,0,175,0,176,0,177,0,178,0,179,0,180,0,181,0,182,0,183,0,184,0,185,0,186,0,187,0,188,0,189,0,190,0,4,0,248,0,0,0,58,0,32,0,4,0,26,0,126,0,142,0,158,0,174,0,255,1,13,1,49,1,83,1,97,1,120,1,126,1,146,2,55,2,199,2,218,2,220,32,20,32,26,32,30,32,34,32,38,32,48,32,58,32,112,32,121,32,137,32,172,33,34,255,255,0,0,0,32,0,142,0,158,0,160,0,176,1,12,1,49,1,82,1,96,1,120,1,125,1,146,2,55,2,198,2,218,2,220,32,19,32,24,32,28,32,32,32,38,32,48,32,57,32,112,32,116,32,128,32,172,33,34,255,255,255,225,0,57,0,42,255,192,255,191,255,179,255,144,255,112,255,100,255,78,255,74,255,55,254,147,254,5,253,243,253,242,224,188,224,185,224,184,224,183,224,180,224,171,224,163,224,110,224,107,224,101,224,67,223,206,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,248,0,0,0,58,0,32,0,4,0,26,0,126,0,142,0,158,0,174,0,255,1,13,1,49,1,83,1,97,1,120,1,126,1,146,2,55,2,199,2,218,2,220,32,20,32,26,32,30,32,34,32,38,32,48,32,58,32,112,32,121,32,137,32,172,33,34,255,255,0,0,0,32,0,142,0,158,0,160,0,176,1,12,1,49,1,82,1,96,1,120,1,125,1,146,2,55,2,198,2,218,2,220,32,19,32,24,32,28,32,32,32,38,32,48,32,57,32,112,32,116,32,128,32,172,33,34,255,255,255,225,0,57,0,42,255,192,255,191,255,179,255,144,255,112,255,100,255,78,255,74,255,55,254,147,254,5,253,243,253,242,224,188,224,185,224,184,224,183,224,180,224,171,224,163,224,110,224,107,224,101,224,67,223,206,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20,0,70,0,84,0,58,0,96,0,72,0,0,0,14,255,14,0,8,1,64,0,8,1,234,0,10,2,188,0,14,2,48,0,11,2,238,0,5,184,0,0,44,75,184,0,9,80,88,177,1,1,142,89,184,1,255,133,184,0,68,29,185,0,9,0,3,95,94,45,184,0,1,44,32,32,69,105,68,176,1,96,45,184,0,2,44,184,0,1,42,33,45,184,0,3,44,32,70,176,3,37,70,82,88,35,89,32,138,32,138,73,100,138,32,70,32,104,97,100,176,4,37,70,32,104,97,100,82,88,35,101,138,89,47,32,176,0,83,88,105,32,176,0,84,88,33,176,64,89,27,105,32,176,0,84,88,33,176,64,101,89,89,58,45,184,0,4,44,32,70,176,4,37,70,82,88,35,138,89,32,70,32,106,97,100,176,4,37,70,32,106,97,100,82,88,35,138,89,47,253,45,184,0,5,44,75,32,176,3,38,80,88,81,88,176,128,68,27,176,64,68,89,27,33,33,32,69,176,192,80,88,176,192,68,27,33,89,89,45,184,0,6,44,32,32,69,105,68,176,1,96,32,32,69,125,105,24,68,176,1,96,45,184,0,7,44,184,0,6,42,45,184,0,8,44,75,32,176,3,38,83,88,176,64,27,176,0,89,138,138,32,176,3,38,83,88,35,33,176,128,138,138,27,138,35,89,32,176,3,38,83,88,35,33,184,0,192,138,138,27,138,35,89,32,176,3,38,83,88,35,33,184,1,0,138,138,27,138,35,89,32,176,3,38,83,88,35,33,184,1,64,138,138,27,138,35,89,32,184,0,3,38,83,88,176,3,37,69,184,1,128,80,88,35,33,184,1,128,35,33,27,176,3,37,69,35,33,35,33,89,27,33,89,68,45,184,0,9,44,75,83,88,69,68,27,33,33,89,45,0,0,0,0,2,0,8,0,2,255,255,0,3,0,1,0,72,0,250,0,162,1,104,0,3,0,28,184,0,2,47,65,3,0,0,0,2,0,1,93,184,0,3,220,0,184,0,1,47,184,0,2,220,48,49,55,35,53,51,162,90,90,250,110,0,0,2,0,59,0,0,0,183,2,238,0,3,0,7,0,164,187,0,7,0,4,0,6,0,4,43,65,5,0,0,0,7,0,16,0,7,0,2,93,184,0,7,16,184,0,0,208,65,13,0,6,0,0,0,22,0,0,0,38,0,0,0,54,0,0,0,70,0,0,0,86,0,0,0,6,113,65,5,0,0,0,6,0,16,0,6,0,2,93,184,0,6,16,184,0,3,208,65,13,0,9,0,3,0,25,0,3,0,41,0,3,0,57,0,3,0,73,0,3,0,89,0,3,0,6,113,0,184,0,0,69,88,184,0,3,47,27,185,0,3,0,18,62,89,184,0,0,69,88,184,0,4,47,27,185,0,4,0,6,62,89,184,0,7,220,65,3,0,63,0,7,0,1,113,184,0,1,220,48,49,19,3,35,3,19,35,53,51,183,30,64,30,104,84,84,2,238,253,218,2,38,253,18,86,0,2,0,40,1,194,1,106,2,238,0,3,0,7,0,60,184,0,7,47,184,0,3,220,185,0,0,0,4,244,184,0,7,16,185,0,4,0,4,244,0,184,0,0,69,88,184,0,7,47,27,185,0,7,0,18,62,89,184,0,6,220,184,0,2,208,184,0,7,16,184,0,3,208,48,49,1,3,35,3,35,3,35,3,1,106,20,52,20,136,20,54,20,2,238,254,212,1,44,254,212,1,44,0,0,2,0,33,255,245,2,160,2,188,0,27,0,31,1,239,184,0,12,47,65,3,0,137,0,12,0,1,93,65,5,0,0,0,12,0,16,0,12,0,2,93,184,0,8,220,184,0,7,220,184,0,26,208,65,3,0,71,0,26,0,1,93,186,0,27,0,26,0,7,17,18,57,184,0,27,16,184,0,0,208,184,0,0,47,186,0,2,0,26,0,7,17,18,57,186,0,3,0,26,0,7,17,18,57,184,0,3,16,184,0,4,208,184,0,4,47,186,0,6,0,7,0,26,17,18,57,184,0,8,16,184,0,25,208,65,3,0,71,0,25,0,1,93,186,0,9,0,8,0,25,17,18,57,184,0,12,16,184,0,11,220,184,0,22,208,65,3,0,71,0,22,0,1,93,186,0,10,0,11,0,22,17,18,57,184,0,12,16,184,0,21,208,65,3,0,71,0,21,0,1,93,186,0,13,0,12,0,21,17,18,57,184,0,13,16,184,0,14,208,184,0,14,47,186,0,16,0,12,0,21,17,18,57,186,0,17,0,21,0,12,17,18,57,184,0,17,16,184,0,18,208,184,0,18,47,186,0,20,0,21,0,12,17,18,57,186,0,23,0,22,0,11,17,18,57,186,0,24,0,25,0,8,17,18,57,186,0,28,0,25,0,8,17,18,57,186,0,29,0,22,0,11,17,18,57,186,0,30,0,11,0,22,17,18,57,186,0,31,0,8,0,25,17,18,57,0,184,0,0,69,88,184,0,22,47,27,185,0,22,0,14,62,89,184,0,0,69,88,184,0,11,47,27,185,0,11,0,6,62,89,186,0,23,0,22,0,11,17,18,57,184,0,23,47,65,3,0,15,0,23,0,1,93,185,0,29,0,2,244,65,3,0,159,0,29,0,1,93,184,0,2,208,186,0,30,0,11,0,22,17,18,57,184,0,30,47,65,3,0,144,0,30,0,1,93,184,0,3,208,184,0,30,16,185,0,10,0,2,244,65,3,0,159,0,10,0,1,93,184,0,6,208,184,0,11,16,184,0,8,208,184,0,10,16,184,0,13,208,184,0,30,16,184,0,16,208,184,0,29,16,184,0,17,208,184,0,23,16,184,0,20,208,184,0,22,16,184,0,25,208,184,0,23,16,184,0,27,208,48,49,1,7,35,7,51,7,35,7,35,55,35,7,35,55,35,55,51,55,35,55,51,55,51,7,51,55,51,15,1,35,7,51,2,160,29,116,48,128,38,122,87,80,87,133,87,80,86,120,37,115,48,126,29,129,74,80,74,133,75,80,74,113,132,48,132,1,251,84,123,84,227,227,227,227,84,123,84,193,193,193,193,84,123,0,0,0,1,0,42,255,224,1,222,2,236,0,43,2,240,186,0,39,0,17,0,3,43,65,3,0,16,0,39,0,1,93,65,3,0,208,0,39,0,1,93,65,3,0,144,0,39,0,1,93,65,3,0,176,0,39,0,1,93,65,3,0,111,0,17,0,1,93,65,3,0,79,0,17,0,1,93,65,3,0,16,0,17,0,1,93,186,0,2,0,39,0,17,17,18,57,184,0,2,47,185,0,1,0,4,244,186,0,0,0,1,0,2,17,18,57,186,0,3,0,2,0,1,17,18,57,186,0,5,0,17,0,39,17,18,57,184,0,5,47,184,0,39,16,184,0,10,220,65,11,0,79,0,10,0,95,0,10,0,111,0,10,0,127,0,10,0,143,0,10,0,5,93,65,3,0,223,0,10,0,1,93,184,0,3,16,184,0,22,208,184,0,2,16,184,0,23,208,184,0,1,16,184,0,24,208,184,0,0,16,184,0,25,208,186,0,27,0,39,0,17,17,18,57,184,0,27,47,184,0,17,16,184,0,32,220,65,3,0,239,0,32,0,1,93,65,9,0,80,0,32,0,96,0,32,0,112,0,32,0,128,0,32,0,4,93,0,184,0,2,47,184,0,0,69,88,184,0,23,47,27,185,0,23,0,18,62,89,65,5,0,80,0,2,0,96,0,2,0,2,93,186,0,3,0,2,0,23,17,18,57,184,0,3,47,184,0,0,208,184,0,3,16,184,0,6,220,65,3,0,128,0,6,0,1,93,65,3,0,32,0,6,0,1,93,184,0,3,16,185,0,8,0,2,244,186,0,22,0,23,0,2,17,18,57,184,0,22,47,186,0,13,0,3,0,22,17,18,57,65,9,0,90,0,13,0,106,0,13,0,122,0,13,0,138,0,13,0,4,93,184,0,25,208,184,0,22,16,184,0,28,220,184,0,22,16,185,0,30,0,2,244,186,0,35,0,22,0,3,17,18,57,48,49,1,65,3,0,135,0,5,0,1,93,65,3,0,25,0,15,0,1,93,65,3,0,27,0,16,0,1,93,65,3,0,139,0,16,0,1,93,65,3,0,8,0,20,0,1,93,65,11,0,53,0,34,0,69,0,34,0,85,0,34,0,101,0,34,0,117,0,34,0,5,93,65,3,0,21,0,37,0,1,93,65,3,0,117,0,37,0,1,93,65,3,0,38,0,37,0,1,93,65,7,0,71,0,37,0,87,0,37,0,103,0,37,0,3,93,65,3,0,118,0,38,0,1,93,65,3,0,22,0,42,0,1,93,65,3,0,7,0,42,0,1,93,0,65,3,0,139,0,4,0,1,93,65,11,0,60,0,4,0,76,0,4,0,92,0,4,0,108,0,4,0,124,0,4,0,5,93,65,3,0,139,0,5,0,1,93,65,3,0,137,0,12,0,1,93,65,3,0,24,0,15,0,1,93,65,3,0,41,0,15,0,1,93,65,3,0,6,0,20,0,1,93,65,3,0,131,0,26,0,1,93,65,11,0,52,0,26,0,68,0,26,0,84,0,26,0,100,0,26,0,116,0,26,0,5,93,65,11,0,55,0,34,0,71,0,34,0,87,0,34,0,103,0,34,0,119,0,34,0,5,93,65,3,0,69,0,37,0,1,93,65,5,0,22,0,37,0,38,0,37,0,2,93,65,7,0,86,0,37,0,102,0,37,0,118,0,37,0,3,93,65,5,0,9,0,42,0,25,0,42,0,2,93,37,23,35,55,38,39,55,22,51,50,53,52,46,4,53,52,62,2,55,39,51,7,22,23,7,38,35,34,21,20,30,4,21,20,14,2,1,29,15,89,17,117,59,12,70,116,110,47,71,82,71,47,21,45,71,49,17,90,16,108,53,9,102,65,121,49,73,85,73,49,14,42,76,82,114,113,6,32,109,58,63,29,36,26,24,34,52,42,28,53,41,28,5,117,117,6,31,96,48,58,27,32,23,24,38,61,49,22,49,43,33,0,0,0,0,5,0,35,255,242,3,37,2,193,0,3,0,21,0,37,0,55,0,71,2,46,184,0,7,47,184,0,41,47,65,7,0,0,0,41,0,16,0,41,0,32,0,41,0,3,93,184,0,51,220,186,0,1,0,7,0,51,17,18,57,184,0,1,47,184,0,0,220,184,0,1,16,184,0,3,220,184,0,2,220,184,0,7,16,184,0,17,220,184,0,7,16,184,0,27,220,65,3,0,31,0,27,0,1,113,184,0,17,16,184,0,33,220,65,3,0,16,0,33,0,1,113,184,0,41,16,184,0,61,220,65,3,0,31,0,61,0,1,113,184,0,51,16,184,0,67,220,65,3,0,16,0,67,0,1,113,0,184,0,0,69,88,184,0,12,47,27,185,0,12,0,14,62,89,184,0,0,69,88,184,0,2,47,27,185,0,2,0,14,62,89,184,0,0,69,88,184,0,38,47,27,185,0,38,0,6,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,184,0,12,16,184,0,4,220,184,0,12,16,184,0,22,220,184,0,4,16,184,0,30,220,184,0,38,16,184,0,46,220,184,0,56,220,184,0,38,16,184,0,64,220,48,49,1,65,3,0,87,0,0,0,1,93,65,7,0,10,0,6,0,26,0,6,0,42,0,6,0,3,93,65,7,0,10,0,9,0,26,0,9,0,42,0,9,0,3,93,65,3,0,200,0,10,0,1,93,65,3,0,199,0,14,0,1,93,65,7,0,5,0,15,0,21,0,15,0,37,0,15,0,3,93,65,7,0,5,0,19,0,21,0,19,0,37,0,19,0,3,93,65,3,0,199,0,20,0,1,93,65,5,0,118,0,24,0,134,0,24,0,2,93,65,3,0,201,0,39,0,1,93,65,7,0,10,0,40,0,26,0,40,0,42,0,40,0,3,93,65,7,0,10,0,43,0,26,0,43,0,42,0,43,0,3,93,65,3,0,200,0,44,0,1,93,65,3,0,199,0,48,0,1,93,65,7,0,5,0,49,0,21,0,49,0,37,0,49,0,3,93,65,7,0,5,0,53,0,21,0,53,0,37,0,53,0,3,93,65,3,0,199,0,54,0,1,93,65,5,0,118,0,58,0,134,0,58,0,2,93,0,65,3,0,203,0,5,0,1,93,65,3,0,197,0,10,0,1,93,65,3,0,195,0,14,0,1,93,65,3,0,202,0,20,0,1,93,65,3,0,201,0,39,0,1,93,65,3,0,199,0,44,0,1,93,65,3,0,198,0,48,0,1,93,65,3,0,202,0,54,0,1,93,23,35,1,51,1,34,38,53,52,62,2,51,50,30,2,21,20,14,2,3,34,14,2,21,20,22,51,50,54,53,52,46,2,1,34,38,53,52,62,2,51,50,30,2,21,20,14,2,3,34,14,2,21,20,22,51,50,54,53,52,46,2,237,75,1,165,74,254,36,64,82,24,42,55,30,31,53,39,23,23,40,55,29,19,34,26,15,54,37,40,54,14,26,33,1,195,64,82,24,42,55,30,31,53,39,23,23,40,55,29,19,34,26,15,54,37,40,54,14,26,33,12,2,200,254,145,94,88,46,71,48,25,24,46,67,44,46,71,49,25,1,64,19,36,52,31,60,70,75,64,29,48,34,18,253,101,94,88,46,71,48,25,24,46,67,44,46,71,49,25,1,64,19,36,52,31,60,70,75,64,29,48,34,18,0,3,0,36,255,233,2,81,2,191,0,30,0,43,0,51,3,97,186,0,28,0,10,0,3,43,65,3,0,127,0,10,0,1,93,65,3,0,16,0,10,0,1,93,184,0,10,16,185,0,47,0,4,244,65,3,0,16,0,28,0,1,93,184,0,28,16,185,0,27,0,5,244,186,0,44,0,47,0,27,17,18,57,65,3,0,105,0,44,0,1,93,186,0,30,0,28,0,10,17,18,57,65,3,0,103,0,30,0,1,93,186,0,2,0,44,0,30,17,18,57,186,0,14,0,10,0,28,17,18,57,184,0,14,47,184,0,22,220,65,3,0,128,0,22,0,1,93,186,0,12,0,14,0,22,17,18,57,65,3,0,25,0,12,0,1,93,65,3,0,8,0,12,0,1,93,186,0,24,0,22,0,14,17,18,57,65,3,0,135,0,24,0,1,93,65,3,0,10,0,24,0,1,93,65,3,0,153,0,24,0,1,93,65,3,0,102,0,24,0,1,93,65,3,0,117,0,24,0,1,93,186,0,25,0,44,0,30,17,18,57,65,3,0,136,0,25,0,1,93,184,0,14,16,184,0,34,220,65,3,0,159,0,34,0,1,93,65,7,0,63,0,34,0,79,0,34,0,95,0,34,0,3,113,186,0,36,0,12,0,24,17,18,57,184,0,22,16,184,0,41,220,65,3,0,161,0,41,0,1,93,65,3,0,144,0,41,0,1,93,186,0,45,0,12,0,24,17,18,57,0,184,0,0,69,88,184,0,19,47,27,185,0,19,0,14,62,89,184,0,0,69,88,184,0,5,47,27,185,0,5,0,6,62,89,184,0,0,69,88,184,0,1,47,27,185,0,1,0,6,62,89,186,0,27,0,19,0,5,17,18,57,184,0,27,47,186,0,2,0,5,0,27,17,18,57,186,0,36,0,19,0,5,17,18,57,65,3,0,101,0,36,0,1,93,65,3,0,133,0,36,0,1,93,186,0,45,0,19,0,5,17,18,57,65,3,0,105,0,45,0,1,93,186,0,12,0,36,0,45,17,18,57,186,0,24,0,36,0,45,17,18,57,186,0,25,0,27,0,5,17,18,57,65,7,0,101,0,25,0,117,0,25,0,133,0,25,0,3,93,186,0,30,0,25,0,2,17,18,57,184,0,19,16,185,0,31,0,1,244,186,0,44,0,25,0,2,17,18,57,65,3,0,103,0,44,0,1,93,184,0,5,16,185,0,50,0,1,244,48,49,1,65,3,0,22,0,3,0,1,93,65,7,0,88,0,7,0,104,0,7,0,120,0,7,0,3,93,65,3,0,105,0,8,0,1,93,65,3,0,137,0,8,0,1,93,65,3,0,10,0,8,0,1,93,65,3,0,90,0,8,0,1,93,65,3,0,122,0,8,0,1,93,65,3,0,89,0,9,0,1,93,65,3,0,9,0,16,0,1,93,65,3,0,27,0,16,0,1,93,65,5,0,6,0,20,0,22,0,20,0,2,93,65,3,0,4,0,21,0,1,93,65,5,0,38,0,21,0,54,0,21,0,2,93,65,3,0,88,0,25,0,1,93,0,65,3,0,25,0,3,0,1,93,65,3,0,89,0,3,0,1,93,65,3,0,122,0,3,0,1,93,65,7,0,89,0,7,0,105,0,7,0,121,0,7,0,3,93,65,3,0,88,0,8,0,1,93,65,3,0,120,0,8,0,1,93,65,3,0,9,0,8,0,1,93,65,3,0,105,0,8,0,1,93,65,3,0,88,0,9,0,1,93,65,3,0,21,0,16,0,1,93,65,3,0,6,0,16,0,1,93,65,3,0,20,0,20,0,1,93,65,3,0,68,0,20,0,1,93,65,3,0,5,0,20,0,1,93,65,3,0,37,0,20,0,1,93,65,3,0,54,0,20,0,1,93,65,3,0,86,0,20,0,1,93,65,3,0,85,0,25,0,1,93,65,3,0,71,0,25,0,1,93,65,3,0,137,0,45,0,1,93,33,35,39,14,1,35,34,46,2,53,52,55,38,53,52,62,2,51,50,22,21,20,7,23,54,55,51,6,7,3,34,6,21,20,23,63,1,62,1,53,52,38,19,39,6,21,20,22,51,50,2,81,92,44,44,86,58,60,87,58,28,126,75,31,53,71,40,72,71,164,190,32,7,81,4,61,236,43,59,55,53,20,29,24,43,106,208,81,75,73,88,46,38,31,27,49,68,41,115,89,91,79,39,61,44,23,69,57,119,102,195,41,149,156,95,2,22,52,48,61,67,41,17,25,44,26,36,39,253,239,208,57,87,55,69,0,0,0,1,0,41,1,194,0,141,2,238,0,3,0,34,184,0,3,47,185,0,0,0,4,244,0,184,0,0,69,88,184,0,3,47,27,185,0,3,0,18,62,89,184,0,2,220,48,49,19,3,35,3,141,18,64,18,2,238,254,212,1,44,0,0,0,1,0,42,255,120,0,237,2,238,0,15,0,150,184,0,6,47,184,0,12,220,184,0,0,208,184,0,12,16,184,0,11,220,184,0,1,208,184,0,6,16,185,0,14,0,5,244,65,3,0,15,0,17,0,1,93,0,184,0,0,47,184,0,0,69,88,184,0,12,47,27,185,0,12,0,18,62,89,48,49,1,65,3,0,134,0,13,0,1,93,65,3,0,55,0,13,0,1,93,65,3,0,151,0,13,0,1,93,65,3,0,134,0,15,0,1,93,65,3,0,151,0,15,0,1,93,0,65,3,0,152,0,13,0,1,93,65,3,0,137,0,13,0,1,93,65,3,0,150,0,15,0,1,93,65,3,0,135,0,15,0,1,93,23,35,46,3,53,52,62,2,55,51,6,21,20,237,79,30,44,28,14,14,29,44,29,79,123,136,45,93,106,124,75,76,124,106,92,45,200,243,244,0,0,1,0,24,255,120,0,219,2,238,0,15,0,149,184,0,11,47,65,3,0,48,0,11,0,1,93,65,3,0,112,0,11,0,1,93,184,0,5,220,184,0,6,220,184,0,0,208,184,0,5,16,184,0,1,208,184,0,11,16,185,0,3,0,5,244,65,3,0,15,0,17,0,1,93,0,184,0,0,47,184,0,0,69,88,184,0,6,47,27,185,0,6,0,18,62,89,48,49,1,65,3,0,152,0,2,0,1,93,65,3,0,137,0,2,0,1,93,65,3,0,56,0,4,0,1,93,65,5,0,137,0,4,0,153,0,4,0,2,93,0,65,3,0,151,0,2,0,1,93,65,5,0,136,0,4,0,152,0,4,0,2,93,23,35,54,53,52,39,51,30,3,21,20,14,2,103,79,123,123,79,29,44,29,14,14,29,43,136,199,244,243,200,45,92,106,124,76,75,124,106,93,0,0,0,1,0,33,1,168,1,137,2,237,0,14,0,193,186,0,9,0,8,0,3,43,0,184,0,0,69,88,184,0,8,47,27,185,0,8,0,18,62,89,184,0,2,220,65,3,0,64,0,2,0,1,93,65,3,0,64,0,2,0,1,113,184,0,0,208,184,0,0,47,48,49,1,65,5,0,40,0,3,0,56,0,3,0,2,113,65,3,0,56,0,4,0,1,113,65,3,0,228,0,5,0,1,93,65,3,0,121,0,5,0,1,93,65,5,0,137,0,11,0,153,0,11,0,2,93,65,3,0,55,0,14,0,1,113,65,3,0,73,0,14,0,1,93,0,65,3,0,7,0,0,0,1,113,65,3,0,53,0,1,0,1,93,65,3,0,167,0,1,0,1,93,65,3,0,230,0,5,0,1,93,65,3,0,231,0,6,0,1,93,65,7,0,184,0,11,0,200,0,11,0,216,0,11,0,3,93,1,39,7,39,55,39,55,23,39,51,7,55,23,7,23,1,59,102,100,32,108,156,23,148,13,46,16,149,23,158,113,1,171,133,136,32,117,65,41,86,156,156,86,42,63,115,0,0,0,0,1,0,46,0,102,1,160,1,196,0,11,0,177,184,0,4,47,65,3,0,143,0,4,0,1,93,65,3,0,160,0,4,0,1,93,65,3,0,0,0,4,0,1,93,184,0,1,220,65,3,0,159,0,1,0,1,93,184,0,0,220,65,3,0,144,0,0,0,1,93,184,0,4,16,184,0,5,220,65,3,0,159,0,5,0,1,93,184,0,4,16,184,0,7,208,184,0,1,16,184,0,10,208,0,184,0,4,47,184,0,1,208,184,0,4,16,184,0,3,220,184,0,4,16,184,0,7,220,65,7,0,64,0,7,0,80,0,7,0,96,0,7,0,3,113,184,0,8,220,65,3,0,47,0,8,0,1,93,65,5,0,31,0,8,0,47,0,8,0,2,113,65,3,0,175,0,8,0,1,93,184,0,7,16,184,0,10,208,48,49,37,35,21,35,53,35,53,51,53,51,21,51,1,160,145,80,145,145,80,145,238,136,136,86,128,128,0,0,0,0,1,0,57,255,147,0,158,0,86,0,6,0,95,187,0,6,0,4,0,5,0,4,43,65,3,0,16,0,5,0,1,93,184,0,5,16,184,0,2,208,65,3,0,16,0,6,0,1,93,186,0,3,0,5,0,6,17,18,57,0,184,0,0,69,88,184,0,4,47,27,185,0,4,0,6,62,89,184,0,0,208,184,0,4,16,184,0,1,220,184,0,4,16,184,0,5,220,65,3,0,63,0,5,0,1,113,48,49,51,7,39,55,39,53,51,158,78,23,35,34,100,109,13,87,9,86,0,0,1,0,57,0,238,1,111,1,68,0,3,0,37,184,0,1,47,65,3,0,0,0,1,0,1,93,184,0,0,220,65,3,0,96,0,0,0,1,93,0,184,0,1,47,184,0,2,220,48,49,37,33,53,33,1,111,254,202,1,54,238,86,0,0,1,0,57,0,0,0,147,0,86,0,3,0,61,187,0,0,0,4,0,1,0,4,43,65,3,0,16,0,0,0,1,93,65,3,0,16,0,1,0,1,93,0,184,0,0,69,88,184,0,1,47,27,185,0,1,0,6,62,89,184,0,2,220,65,3,0,63,0,2,0,1,113,48,49,51,35,53,51,147,90,90,86,0,0,1,0,19,255,171,1,241,2,188,0,3,0,61,184,0,2,47,184,0,0,220,65,3,0,128,0,0,0,1,93,184,0,2,16,185,0,1,0,4,244,184,0,0,16,185,0,3,0,4,244,0,184,0,1,47,184,0,0,69,88,184,0,3,47,27,185,0,3,0,14,62,89,48,49,9,1,35,1,1,241,254,134,100,1,122,2,188,252,239,3,17,0,2,0,63,255,242,2,139,2,202,0,19,0,35,2,48,186,0,15,0,5,0,3,43,65,3,0,15,0,5,0,1,113,65,3,0,143,0,5,0,1,93,65,3,0,239,0,5,0,1,93,65,5,0,0,0,5,0,16,0,5,0,2,93,65,3,0,32,0,15,0,1,113,65,3,0,80,0,15,0,1,113,65,3,0,64,0,15,0,1,93,65,5,0,0,0,15,0,16,0,15,0,2,93,184,0,5,16,185,0,25,0,4,244,184,0,15,16,185,0,31,0,4,244,0,184,0,0,69,88,184,0,10,47,27,185,0,10,0,14,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,184,0,10,16,185,0,20,0,2,244,184,0,0,16,185,0,28,0,2,244,48,49,1,65,3,0,25,0,2,0,1,93,65,7,0,105,0,2,0,121,0,2,0,137,0,2,0,3,93,65,3,0,42,0,2,0,1,93,65,3,0,24,0,3,0,1,93,65,7,0,89,0,3,0,105,0,3,0,121,0,3,0,3,93,65,3,0,104,0,8,0,1,93,65,3,0,25,0,8,0,1,93,65,3,0,121,0,8,0,1,93,65,5,0,22,0,12,0,38,0,12,0,2,93,65,3,0,102,0,12,0,1,93,65,3,0,22,0,13,0,1,93,65,7,0,102,0,13,0,118,0,13,0,134,0,13,0,3,93,65,3,0,87,0,13,0,1,93,65,3,0,86,0,17,0,1,93,65,3,0,38,0,18,0,1,93,65,3,0,23,0,18,0,1,93,65,7,0,103,0,18,0,119,0,18,0,135,0,18,0,3,93,65,3,0,89,0,26,0,1,93,0,65,3,0,137,0,1,0,1,93,65,3,0,40,0,2,0,1,93,65,3,0,25,0,2,0,1,93,65,7,0,105,0,2,0,121,0,2,0,137,0,2,0,3,93,65,3,0,24,0,3,0,1,93,65,3,0,104,0,3,0,1,93,65,3,0,121,0,3,0,1,93,65,3,0,22,0,8,0,1,93,65,3,0,118,0,8,0,1,93,65,3,0,103,0,8,0,1,93,65,7,0,103,0,12,0,119,0,12,0,135,0,12,0,3,93,65,3,0,117,0,13,0,1,93,65,3,0,23,0,13,0,1,93,65,3,0,103,0,13,0,1,93,65,3,0,88,0,17,0,1,93,65,5,0,25,0,18,0,41,0,18,0,2,93,65,5,0,105,0,18,0,121,0,18,0,2,93,65,3,0,138,0,18,0,1,93,65,3,0,87,0,26,0,1,93,5,34,46,2,53,52,62,2,51,50,30,2,21,20,14,2,3,34,14,2,21,20,22,51,50,54,53,52,46,2,1,95,65,106,75,42,46,81,110,63,62,106,77,43,43,79,111,57,41,72,53,31,102,87,91,108,29,51,70,14,50,92,130,80,83,139,99,55,53,94,132,78,84,137,97,53,2,130,39,74,108,69,132,134,143,142,64,101,69,37,0,0,0,1,0,34,0,0,0,254,2,188,0,11,0,150,187,0,0,0,4,0,1,0,4,43,65,3,0,16,0,0,0,1,93,65,3,0,16,0,1,0,1,93,184,0,1,16,184,0,5,220,186,0,10,0,1,0,0,17,18,57,0,184,0,0,69,88,184,0,10,47,27,185,0,10,0,14,62,89,184,0,0,69,88,184,0,1,47,27,185,0,1,0,6,62,89,184,0,10,16,184,0,4,220,186,0,2,0,10,0,4,17,18,57,65,5,0,235,0,2,0,251,0,2,0,2,93,65,7,0,11,0,2,0,27,0,2,0,43,0,2,0,3,113,65,5,0,202,0,2,0,218,0,2,0,2,93,185,0,5,0,2,244,48,49,51,35,17,6,7,39,62,3,55,51,254,100,54,50,16,21,43,39,33,11,73,2,51,45,16,89,7,23,29,33,17,0,0,1,0,50,0,0,1,214,2,202,0,28,1,188,186,0,22,0,12,0,3,43,65,3,0,95,0,12,0,1,93,184,0,12,16,184,0,1,208,65,3,0,42,0,1,0,1,113,65,3,0,67,0,1,0,1,113,184,0,22,16,185,0,6,0,4,244,184,0,1,16,184,0,27,208,65,3,0,114,0,27,0,1,93,65,3,0,19,0,27,0,1,113,65,3,0,69,0,27,0,1,93,65,3,0,245,0,27,0,1,93,65,3,0,5,0,27,0,1,113,65,5,0,83,0,27,0,99,0,27,0,2,93,65,5,0,67,0,27,0,83,0,27,0,2,113,65,3,0,33,0,27,0,1,113,65,3,0,128,0,27,0,1,93,184,0,22,16,184,0,28,208,184,0,28,47,0,184,0,0,69,88,184,0,17,47,27,185,0,17,0,14,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,186,0,4,0,17,0,0,17,18,57,184,0,17,16,185,0,9,0,2,244,184,0,17,16,184,0,11,220,185,0,12,0,2,244,65,3,0,86,0,12,0,1,93,186,0,25,0,0,0,17,17,18,57,184,0,0,16,185,0,28,0,2,244,48,49,1,65,5,0,105,0,3,0,121,0,3,0,2,93,65,3,0,89,0,4,0,1,93,65,3,0,149,0,19,0,1,93,65,7,0,103,0,19,0,119,0,19,0,135,0,19,0,3,93,65,7,0,101,0,20,0,117,0,20,0,133,0,20,0,3,93,65,3,0,6,0,20,0,1,93,65,3,0,150,0,20,0,1,93,0,65,3,0,118,0,3,0,1,93,65,3,0,133,0,4,0,1,93,65,3,0,22,0,4,0,1,93,65,3,0,87,0,4,0,1,93,65,3,0,133,0,14,0,1,93,65,7,0,6,0,14,0,22,0,14,0,38,0,14,0,3,93,65,7,0,101,0,19,0,117,0,19,0,133,0,19,0,3,93,65,3,0,6,0,20,0,1,93,65,3,0,151,0,20,0,1,93,41,1,62,1,55,54,53,52,38,35,34,7,39,62,3,51,50,30,2,21,20,14,2,7,51,1,214,254,98,91,116,28,56,65,57,93,70,12,7,35,51,67,39,55,75,45,19,23,51,82,59,242,129,179,52,104,48,54,59,93,85,13,34,30,20,35,55,69,33,36,83,103,130,84,0,1,0,40,255,242,1,228,2,202,0,49,2,46,186,0,45,0,5,0,3,43,65,3,0,79,0,5,0,1,93,65,3,0,143,0,5,0,1,93,65,3,0,16,0,5,0,1,93,65,3,0,16,0,45,0,1,113,65,3,0,16,0,45,0,1,93,184,0,45,16,185,0,16,0,4,244,186,0,22,0,45,0,5,17,18,57,184,0,22,47,186,0,40,0,45,0,5,17,18,57,184,0,40,47,185,0,27,0,4,244,186,0,32,0,5,0,45,17,18,57,184,0,32,47,186,0,43,0,22,0,40,17,18,57,65,3,0,117,0,43,0,1,93,65,3,0,86,0,43,0,1,93,65,3,0,100,0,43,0,1,93,65,3,0,132,0,43,0,1,93,0,184,0,0,69,88,184,0,35,47,27,185,0,35,0,14,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,184,0,6,220,65,3,0,32,0,6,0,1,93,184,0,5,208,65,7,0,10,0,5,0,26,0,5,0,42,0,5,0,3,113,184,0,0,16,185,0,11,0,2,244,186,0,24,0,35,0,0,17,18,57,184,0,24,47,185,0,21,0,2,244,184,0,35,16,185,0,29,0,2,244,184,0,35,16,184,0,31,220,65,5,0,144,0,31,0,160,0,31,0,2,93,186,0,43,0,24,0,21,17,18,57,48,49,1,65,3,0,137,0,3,0,1,93,65,13,0,56,0,33,0,72,0,33,0,88,0,33,0,104,0,33,0,120,0,33,0,136,0,33,0,6,93,65,3,0,7,0,37,0,1,93,65,7,0,87,0,42,0,103,0,42,0,119,0,42,0,3,93,65,5,0,85,0,44,0,101,0,44,0,2,93,65,3,0,133,0,44,0,1,93,65,3,0,118,0,44,0,1,93,65,3,0,87,0,47,0,1,93,0,65,11,0,57,0,3,0,73,0,3,0,89,0,3,0,105,0,3,0,121,0,3,0,5,93,65,3,0,138,0,3,0,1,93,65,13,0,54,0,33,0,70,0,33,0,86,0,33,0,102,0,33,0,118,0,33,0,134,0,33,0,6,93,65,3,0,6,0,37,0,1,93,65,3,0,88,0,42,0,1,93,65,3,0,105,0,42,0,1,93,65,3,0,122,0,42,0,1,93,65,3,0,86,0,44,0,1,93,65,3,0,118,0,44,0,1,93,65,3,0,103,0,44,0,1,93,65,3,0,135,0,44,0,1,93,65,3,0,90,0,47,0,1,93,65,3,0,89,0,48,0,1,93,23,34,46,2,39,55,30,3,51,50,62,2,53,52,46,2,43,1,55,51,50,54,53,52,35,34,7,39,62,1,51,50,30,2,21,20,6,7,22,21,20,14,2,230,30,61,53,39,7,23,28,42,37,38,23,30,55,40,24,17,39,63,47,73,10,37,91,76,119,85,50,17,16,83,63,66,83,47,17,40,51,116,40,69,93,14,11,17,18,7,88,15,20,14,6,15,34,54,38,30,48,34,18,76,58,57,94,41,81,16,30,35,53,63,29,42,69,35,39,135,54,85,59,30,0,2,0,14,0,0,1,244,2,188,0,9,0,12,1,7,186,0,1,0,5,0,3,43,184,0,1,16,184,0,0,220,184,0,1,16,185,0,4,0,4,244,65,3,0,143,0,5,0,1,93,184,0,10,208,184,0,1,16,184,0,8,208,186,0,6,0,10,0,8,17,18,57,65,3,0,137,0,6,0,1,93,184,0,5,16,184,0,12,208,65,3,0,116,0,12,0,1,93,65,3,0,22,0,12,0,1,113,65,3,0,37,0,12,0,1,113,65,3,0,99,0,12,0,1,93,65,3,0,130,0,12,0,1,93,0,184,0,0,69,88,184,0,6,47,27,185,0,6,0,14,62,89,184,0,0,69,88,184,0,3,47,27,185,0,3,0,6,62,89,186,0,1,0,6,0,3,17,18,57,184,0,1,47,65,3,0,144,0,1,0,1,93,184,0,4,208,184,0,1,16,185,0,8,0,2,244,184,0,10,208,184,0,6,16,184,0,11,208,65,3,0,252,0,11,0,1,93,65,3,0,46,0,11,0,1,113,65,5,0,125,0,11,0,141,0,11,0,2,93,65,3,0,11,0,11,0,1,113,65,3,0,106,0,11,0,1,93,48,49,65,3,0,92,0,11,0,1,93,37,35,21,35,53,33,1,51,17,51,35,53,7,1,244,85,100,254,211,1,66,79,85,185,153,190,190,190,1,254,254,88,254,254,0,0,0,0,1,0,51,255,242,1,233,2,188,0,31,1,213,186,0,27,0,5,0,3,43,65,3,0,79,0,5,0,1,113,65,3,0,47,0,5,0,1,93,65,3,0,47,0,5,0,1,113,65,3,0,16,0,5,0,1,93,65,3,0,16,0,27,0,1,93,65,3,0,64,0,27,0,1,93,65,3,0,96,0,27,0,1,93,184,0,27,16,185,0,13,0,4,244,186,0,17,0,5,0,27,17,18,57,184,0,17,47,184,0,16,220,65,3,0,86,0,16,0,1,113,184,0,17,16,184,0,18,208,186,0,19,0,17,0,27,17,18,57,184,0,19,47,184,0,16,16,184,0,21,208,186,0,22,0,21,0,16,17,18,57,65,3,0,39,0,22,0,1,113,0,184,0,0,69,88,184,0,19,47,27,185,0,19,0,14,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,184,0,6,220,65,3,0,48,0,6,0,1,93,185,0,5,0,2,244,184,0,0,16,185,0,8,0,2,244,186,0,22,0,19,0,0,17,18,57,184,0,22,47,185,0,16,0,2,244,184,0,19,16,185,0,20,0,2,244,48,49,1,65,3,0,72,0,3,0,1,93,65,3,0,137,0,11,0,1,93,65,3,0,70,0,24,0,1,93,65,3,0,102,0,24,0,1,93,65,3,0,55,0,24,0,1,93,65,3,0,100,0,25,0,1,93,65,3,0,69,0,25,0,1,93,65,3,0,54,0,25,0,1,93,65,3,0,86,0,25,0,1,93,65,3,0,119,0,25,0,1,93,65,3,0,55,0,29,0,1,93,65,3,0,71,0,30,0,1,93,0,65,3,0,73,0,3,0,1,93,65,3,0,135,0,11,0,1,93,65,3,0,67,0,24,0,1,93,65,3,0,53,0,24,0,1,93,65,5,0,85,0,24,0,101,0,24,0,2,93,65,9,0,53,0,25,0,69,0,25,0,85,0,25,0,101,0,25,0,4,93,65,3,0,119,0,25,0,1,93,65,3,0,56,0,29,0,1,93,65,3,0,57,0,30,0,1,93,65,3,0,76,0,30,0,1,93,23,34,46,2,39,55,22,51,50,62,2,53,52,38,43,1,19,33,7,35,7,50,30,2,21,20,14,2,220,22,54,50,37,6,23,72,73,35,60,45,26,99,112,85,42,1,62,9,233,20,81,115,72,34,44,73,98,14,7,12,14,6,89,42,25,43,58,34,63,60,1,89,86,174,25,50,77,52,56,92,66,36,0,0,0,0,2,0,62,255,242,2,12,2,188,0,27,0,47,2,74,186,0,23,0,5,0,3,43,65,3,0,239,0,5,0,1,93,65,3,0,31,0,5,0,1,93,65,3,0,143,0,5,0,1,93,65,3,0,0,0,5,0,1,93,65,3,0,0,0,23,0,1,93,65,3,0,192,0,23,0,1,93,65,5,0,48,0,23,0,64,0,23,0,2,93,186,0,11,0,23,0,5,17,18,57,184,0,11,47,184,0,5,16,185,0,33,0,4,244,184,0,16,208,184,0,23,16,185,0,43,0,4,244,0,184,0,0,69,88,184,0,10,47,27,185,0,10,0,14,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,184,0,10,16,184,0,12,208,65,3,0,249,0,12,0,1,93,184,0,0,16,184,0,18,220,65,3,0,64,0,18,0,1,93,186,0,16,0,18,0,0,17,18,57,65,3,0,243,0,16,0,1,93,185,0,28,0,2,244,184,0,0,16,185,0,38,0,2,244,48,49,1,65,7,0,89,0,2,0,105,0,2,0,121,0,2,0,3,93,65,3,0,138,0,2,0,1,93,65,3,0,91,0,3,0,1,93,65,3,0,136,0,8,0,1,93,65,3,0,247,0,11,0,1,93,65,3,0,69,0,13,0,1,93,65,3,0,117,0,13,0,1,93,65,3,0,54,0,13,0,1,93,65,3,0,103,0,13,0,1,93,65,5,0,102,0,14,0,118,0,14,0,2,93,65,5,0,102,0,20,0,118,0,20,0,2,93,65,5,0,7,0,20,0,23,0,20,0,2,93,65,3,0,135,0,20,0,1,93,65,3,0,102,0,21,0,1,93,65,3,0,134,0,21,0,1,93,65,3,0,119,0,21,0,1,93,65,3,0,87,0,25,0,1,93,65,3,0,86,0,26,0,1,93,0,65,3,0,136,0,2,0,1,93,65,7,0,89,0,2,0,105,0,2,0,121,0,2,0,3,93,65,3,0,135,0,8,0,1,93,65,3,0,6,0,9,0,1,93,65,3,0,250,0,11,0,1,93,65,3,0,72,0,13,0,1,93,65,3,0,120,0,13,0,1,93,65,3,0,107,0,13,0,1,93,65,3,0,122,0,14,0,1,93,65,3,0,87,0,17,0,1,93,65,3,0,117,0,20,0,1,93,65,5,0,6,0,20,0,22,0,20,0,2,93,65,3,0,102,0,20,0,1,93,65,3,0,134,0,20,0,1,93,65,3,0,102,0,21,0,1,93,65,3,0,134,0,21,0,1,93,65,3,0,119,0,21,0,1,93,65,3,0,88,0,25,0,1,93,65,3,0,90,0,26,0,1,93,5,34,46,2,53,52,62,2,55,23,14,3,7,54,51,50,30,2,21,20,14,2,3,34,14,2,21,20,30,2,51,50,62,2,53,52,46,2,1,25,50,80,58,31,61,91,105,43,65,40,76,66,55,19,46,95,45,78,57,32,35,64,89,33,29,51,38,23,20,36,48,27,33,50,34,17,13,30,47,14,30,62,96,66,98,168,123,70,1,38,18,46,69,100,72,63,27,51,76,48,49,84,63,36,1,97,20,36,51,31,33,49,33,17,24,40,52,29,24,45,35,21,0,1,0,39,0,0,1,236,2,188,0,5,0,190,186,0,0,0,5,0,3,43,65,3,0,55,0,0,0,1,93,65,3,0,87,0,0,0,1,93,184,0,0,16,184,0,1,208,184,0,0,16,184,0,3,208,65,7,0,41,0,3,0,57,0,3,0,73,0,3,0,3,93,65,3,0,90,0,3,0,1,93,65,5,0,108,0,3,0,124,0,3,0,2,93,65,3,0,141,0,3,0,1,93,65,5,0,26,0,3,0,42,0,3,0,2,113,65,3,0,249,0,3,0,1,93,65,3,0,9,0,3,0,1,113,65,3,0,232,0,3,0,1,93,65,3,0,151,0,3,0,1,93,184,0,2,208,0,184,0,0,69,88,184,0,5,47,27,185,0,5,0,14,62,89,184,0,0,69,88,184,0,2,47,27,185,0,2,0,6,62,89,184,0,5,16,185,0,4,0,2,244,48,49,9,1,35,1,33,53,1,236,254,209,100,1,9,254,197,2,188,253,68,2,102,86,0,0,0,3,0,59,255,242,2,37,2,201,0,31,0,43,0,57,2,65,186,0,27,0,5,0,3,43,65,3,0,31,0,5,0,1,113,65,3,0,0,0,5,0,1,93,65,5,0,0,0,27,0,16,0,27,0,2,93,65,3,0,80,0,27,0,1,113,65,3,0,32,0,27,0,1,113,186,0,9,0,5,0,27,17,18,57,184,0,9,47,186,0,19,0,27,0,5,17,18,57,184,0,19,47,186,0,7,0,9,0,19,17,18,57,186,0,24,0,19,0,9,17,18,57,184,0,9,16,185,0,32,0,4,244,184,0,19,16,185,0,38,0,4,244,184,0,5,16,185,0,47,0,4,244,184,0,27,16,185,0,55,0,4,244,0,184,0,0,69,88,184,0,14,47,27,185,0,14,0,14,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,186,0,35,0,14,0,0,17,18,57,65,3,0,134,0,35,0,1,93,65,3,0,170,0,35,0,1,93,65,3,0,185,0,35,0,1,93,65,3,0,86,0,35,0,1,93,65,5,0,101,0,35,0,117,0,35,0,2,93,186,0,44,0,0,0,14,17,18,57,65,3,0,138,0,44,0,1,93,65,3,0,185,0,44,0,1,93,65,3,0,41,0,44,0,1,93,186,0,7,0,35,0,44,17,18,57,186,0,24,0,35,0,44,17,18,57,184,0,14,16,185,0,41,0,2,244,184,0,0,16,185,0,50,0,2,244,48,49,1,65,3,0,104,0,2,0,1,93,65,3,0,90,0,2,0,1,93,65,3,0,89,0,3,0,1,93,65,3,0,10,0,3,0,1,93,65,3,0,122,0,3,0,1,93,65,3,0,107,0,3,0,1,93,65,5,0,57,0,8,0,73,0,8,0,2,93,65,3,0,24,0,11,0,1,93,65,3,0,9,0,11,0,1,93,65,5,0,6,0,17,0,22,0,17,0,2,93,65,3,0,100,0,26,0,1,93,65,3,0,117,0,26,0,1,93,65,5,0,86,0,29,0,102,0,29,0,2,93,65,3,0,133,0,42,0,1,93,65,5,0,56,0,53,0,72,0,53,0,2,93,0,65,5,0,89,0,2,0,105,0,2,0,2,93,65,7,0,89,0,3,0,105,0,3,0,121,0,3,0,3,93,65,3,0,6,0,11,0,1,93,65,3,0,23,0,11,0,1,93,65,3,0,7,0,17,0,1,93,65,3,0,119,0,26,0,1,93,65,5,0,88,0,29,0,104,0,29,0,2,93,65,3,0,89,0,30,0,1,93,65,3,0,69,0,53,0,1,93,65,3,0,55,0,53,0,1,93,5,34,46,2,53,52,55,38,53,52,62,2,51,50,30,2,21,20,14,2,7,30,1,21,20,14,2,3,20,22,23,62,1,53,52,38,35,34,6,23,14,1,21,20,22,51,50,62,2,53,52,38,1,40,60,89,59,29,134,93,24,50,78,56,54,76,49,23,11,27,45,34,81,75,33,64,95,170,60,51,58,59,58,54,54,62,119,66,77,71,66,32,54,40,22,79,14,33,56,73,41,116,71,72,92,36,64,46,27,25,43,58,32,27,41,38,38,24,28,89,72,40,76,60,36,2,36,34,60,19,17,67,40,39,44,49,241,13,73,63,58,59,19,34,47,27,51,73,0,0,2,0,45,0,0,1,251,2,202,0,26,0,46,2,23,186,0,5,0,22,0,3,43,65,3,0,224,0,5,0,1,93,65,3,0,64,0,5,0,1,93,65,3,0,192,0,5,0,1,93,65,3,0,128,0,5,0,1,93,65,3,0,63,0,22,0,1,93,65,3,0,31,0,22,0,1,93,186,0,11,0,22,0,5,17,18,57,184,0,11,47,184,0,5,16,185,0,32,0,4,244,184,0,16,208,184,0,22,16,185,0,42,0,4,244,0,184,0,0,69,88,184,0,0,47,27,185,0,0,0,14,62,89,184,0,0,69,88,184,0,10,47,27,185,0,10,0,6,62,89,184,0,12,208,65,3,0,246,0,12,0,1,93,184,0,0,16,184,0,19,220,65,3,0,79,0,19,0,1,93,186,0,16,0,0,0,19,17,18,57,185,0,27,0,2,244,184,0,0,16,185,0,37,0,2,244,48,49,1,65,3,0,117,0,2,0,1,93,65,3,0,86,0,2,0,1,93,65,3,0,134,0,2,0,1,93,65,3,0,86,0,3,0,1,93,65,3,0,134,0,6,0,1,93,65,3,0,6,0,8,0,1,93,65,3,0,134,0,8,0,1,93,65,3,0,23,0,8,0,1,93,65,5,0,57,0,13,0,73,0,13,0,2,93,65,5,0,106,0,13,0,122,0,13,0,2,93,65,3,0,88,0,16,0,1,93,65,3,0,87,0,17,0,1,93,65,3,0,136,0,20,0,1,93,65,3,0,121,0,20,0,1,93,65,5,0,9,0,21,0,25,0,21,0,2,93,65,3,0,105,0,21,0,1,93,65,3,0,138,0,21,0,1,93,65,3,0,89,0,24,0,1,93,65,3,0,89,0,25,0,1,93,0,65,3,0,102,0,2,0,1,93,65,3,0,134,0,2,0,1,93,65,3,0,87,0,2,0,1,93,65,3,0,119,0,2,0,1,93,65,3,0,86,0,3,0,1,93,65,3,0,24,0,8,0,1,93,65,3,0,137,0,8,0,1,93,65,3,0,9,0,9,0,1,93,65,3,0,101,0,13,0,1,93,65,3,0,118,0,13,0,1,93,65,3,0,71,0,13,0,1,93,65,3,0,88,0,16,0,1,93,65,3,0,89,0,17,0,1,93,65,3,0,104,0,20,0,1,93,65,5,0,122,0,20,0,138,0,20,0,2,93,65,3,0,86,0,24,0,1,93,65,3,0,85,0,25,0,1,93,1,50,30,2,21,20,14,2,35,39,62,3,55,14,1,35,34,38,53,52,62,2,19,50,62,2,53,52,46,2,35,34,14,2,21,20,30,2,1,32,42,79,61,37,61,89,101,40,73,41,83,70,50,9,20,76,43,100,112,36,64,89,32,30,51,38,22,21,35,48,27,33,50,34,17,13,29,47,2,202,24,58,97,73,110,172,118,62,38,19,51,71,94,63,27,30,102,100,51,85,62,35,254,159,20,37,51,32,31,49,33,17,24,40,53,28,24,46,34,21,0,0,2,0,57,0,0,0,147,1,184,0,3,0,7,0,102,187,0,7,0,4,0,6,0,4,43,65,3,0,16,0,7,0,1,93,184,0,7,16,184,0,0,208,65,3,0,16,0,6,0,1,93,184,0,6,16,184,0,1,208,0,184,0,2,47,184,0,0,69,88,184,0,5,47,27,185,0,5,0,6,62,89,184,0,2,16,184,0,1,220,65,3,0,48,0,1,0,1,113,184,0,5,16,184,0,6,220,65,3,0,63,0,6,0,1,113,48,49,19,35,53,51,17,35,53,51,147,90,90,90,90,1,98,86,254,72,86,0,0,0,0,2,0,57,255,147,0,158,1,184,0,3,0,10,0,136,187,0,10,0,4,0,9,0,4,43,65,3,0,16,0,10,0,1,93,184,0,10,16,184,0,0,208,65,3,0,16,0,9,0,1,93,184,0,9,16,184,0,1,208,184,0,9,16,184,0,6,208,186,0,7,0,9,0,10,17,18,57,0,184,0,2,47,184,0,0,69,88,184,0,8,47,27,185,0,8,0,6,62,89,184,0,2,16,184,0,1,220,65,3,0,48,0,1,0,1,113,184,0,8,16,184,0,4,208,184,0,8,16,184,0,5,220,184,0,8,16,184,0,9,220,65,3,0,63,0,9,0,1,113,48,49,19,35,53,51,17,7,39,55,39,53,51,158,100,100,78,23,35,34,100,1,98,86,254,71,108,13,87,9,86,0,0,0,0,1,0,33,0,78,1,88,1,234,0,5,0,73,184,0,2,47,184,0,4,220,184,0,0,208,184,0,4,16,185,0,3,0,4,244,184,0,1,208,184,0,2,16,185,0,5,0,4,244,0,25,184,0,2,47,24,184,0,1,208,184,0,1,47,184,0,2,16,184,0,3,208,184,0,3,47,184,0,2,16,184,0,5,208,48,49,37,35,39,55,51,7,1,88,95,216,216,95,216,78,206,206,206,0,2,0,66,0,160,1,180,1,138,0,3,0,7,0,61,184,0,5,47,65,3,0,16,0,5,0,1,93,184,0,4,220,184,0,0,208,184,0,5,16,184,0,1,208,0,184,0,5,47,184,0,1,220,65,3,0,15,0,1,0,1,93,184,0,2,220,184,0,5,16,184,0,6,220,48,49,1,33,53,33,21,33,53,33,1,180,254,142,1,114,254,142,1,114,1,62,76,234,76,0,1,0,60,0,78,1,115,1,234,0,5,0,82,184,0,0,47,65,3,0,16,0,0,0,1,93,184,0,4,220,185,0,5,0,4,244,184,0,1,208,184,0,4,16,184,0,2,208,184,0,0,16,185,0,3,0,4,244,0,25,184,0,0,47,24,184,0,1,208,184,0,1,47,184,0,0,16,184,0,3,208,184,0,0,16,184,0,5,208,184,0,5,47,48,49,1,7,35,55,39,51,1,115,216,95,216,216,95,1,28,206,206,206,0,0,0,2,0,30,0,0,1,141,2,238,0,36,0,40,1,93,186,0,29,0,21,0,3,43,65,3,0,16,0,21,0,1,93,65,3,0,16,0,29,0,1,93,186,0,1,0,21,0,29,17,18,57,184,0,1,47,65,5,0,16,0,1,0,32,0,1,0,2,113,65,7,0,16,0,1,0,32,0,1,0,48,0,1,0,3,93,184,0,0,220,184,0,29,16,184,0,10,220,65,7,0,48,0,10,0,64,0,10,0,80,0,10,0,3,113,186,0,39,0,21,0,29,17,18,57,184,0,39,47,185,0,40,0,4,244,0,184,0,0,69,88,184,0,24,47,27,185,0,24,0,18,62,89,184,0,0,69,88,184,0,38,47,27,185,0,38,0,6,62,89,184,0,39,220,65,3,0,63,0,39,0,1,113,184,0,1,220,184,0,24,16,185,0,15,0,1,244,184,0,24,16,184,0,20,220,48,49,1,65,3,0,121,0,8,0,1,93,65,3,0,6,0,26,0,1,93,65,3,0,102,0,26,0,1,93,65,3,0,101,0,27,0,1,93,65,3,0,119,0,27,0,1,93,65,3,0,39,0,33,0,1,93,65,3,0,134,0,34,0,1,93,65,3,0,23,0,34,0,1,93,0,65,7,0,54,0,22,0,70,0,22,0,86,0,22,0,3,93,65,3,0,7,0,26,0,1,93,65,3,0,103,0,26,0,1,93,65,5,0,103,0,27,0,119,0,27,0,2,93,65,3,0,40,0,33,0,1,93,65,3,0,137,0,33,0,1,93,65,3,0,25,0,34,0,1,93,65,3,0,138,0,34,0,1,93,55,35,38,53,52,62,4,53,52,46,2,35,34,14,2,7,39,62,1,51,50,30,2,21,20,6,15,1,14,1,31,1,35,53,51,226,59,3,22,34,38,34,22,21,35,46,26,22,43,35,26,5,25,19,86,54,48,77,54,29,35,25,51,26,35,1,18,91,91,200,40,5,31,53,49,47,49,55,32,30,46,31,16,13,20,24,11,67,29,38,33,54,67,33,35,76,32,65,33,66,29,227,86,0,2,0,49,255,169,2,163,2,41,0,61,0,76,1,131,184,0,38,47,65,3,0,48,0,38,0,1,93,184,0,48,220,186,0,7,0,38,0,48,17,18,57,184,0,7,47,184,0,0,208,65,3,0,102,0,0,0,1,93,65,3,0,70,0,0,0,1,93,184,0,64,208,65,3,0,68,0,64,0,1,93,65,3,0,197,0,64,0,1,93,65,3,0,54,0,64,0,1,93,65,3,0,53,0,64,0,1,113,65,3,0,5,0,64,0,1,93,65,3,0,212,0,64,0,1,93,65,3,0,19,0,64,0,1,93,184,0,15,208,65,3,0,55,0,15,0,1,93,186,0,28,0,38,0,48,17,18,57,186,0,52,0,48,0,38,17,18,57,184,0,0,16,184,0,57,208,184,0,7,16,184,0,72,220,65,3,0,176,0,72,0,1,93,0,184,0,0,69,88,184,0,43,47,27,185,0,43,0,16,62,89,184,0,33,220,186,0,2,0,33,0,43,17,18,57,184,0,2,47,186,0,10,0,43,0,33,17,18,57,184,0,10,47,186,0,15,0,2,0,10,17,18,57,65,3,0,129,0,15,0,1,93,65,3,0,100,0,15,0,1,93,65,3,0,195,0,15,0,1,93,65,3,0,49,0,15,0,1,93,65,7,0,0,0,15,0,16,0,15,0,32,0,15,0,3,93,184,0,23,208,184,0,23,47,186,0,28,0,33,0,43,17,18,57,65,5,0,19,0,28,0,35,0,28,0,2,93,65,3,0,1,0,28,0,1,93,186,0,52,0,43,0,33,17,18,57,184,0,55,220,184,0,2,16,184,0,62,220,184,0,10,16,184,0,69,220,48,49,1,65,5,0,57,0,5,0,73,0,5,0,2,93,0,65,3,0,54,0,5,0,1,93,1,38,35,34,14,2,21,20,22,51,50,62,2,55,20,14,2,21,20,22,51,50,62,2,55,14,3,35,34,46,2,53,52,62,2,51,50,30,2,21,20,14,2,7,6,35,34,53,52,62,2,39,50,23,14,3,35,34,38,53,52,62,2,2,33,51,71,46,91,72,45,44,51,21,50,48,43,14,1,1,1,26,29,15,36,36,34,12,24,70,86,97,51,57,92,65,34,60,104,136,77,58,93,64,34,5,16,33,28,39,27,37,10,16,19,111,47,7,6,41,54,59,25,22,22,34,53,61,1,123,53,50,79,101,51,48,63,17,31,42,26,1,9,10,10,1,32,51,11,18,23,12,43,71,51,28,35,66,96,60,80,140,103,60,36,66,94,58,26,56,51,42,13,17,53,13,48,61,72,30,22,39,85,72,47,36,28,39,73,55,34,0,0,0,2,0,7,0,0,2,97,2,188,0,7,0,10,1,97,187,0,7,0,4,0,6,0,4,43,65,3,0,16,0,7,0,1,93,184,0,7,16,184,0,0,208,65,3,0,246,0,0,0,1,93,65,3,0,86,0,0,0,1,93,65,3,0,22,0,0,0,1,93,185,0,1,0,4,244,65,3,0,16,0,6,0,1,93,186,0,9,0,6,0,7,17,18,57,186,0,2,0,1,0,9,17,18,57,184,0,6,16,184,0,5,208,65,3,0,249,0,5,0,1,93,65,3,0,25,0,5,0,1,93,65,3,0,89,0,5,0,1,93,185,0,4,0,4,244,186,0,3,0,4,0,9,17,18,57,186,0,8,0,9,0,1,17,18,57,186,0,10,0,9,0,4,17,18,57,0,184,0,0,69,88,184,0,7,47,27,185,0,7,0,14,62,89,184,0,0,69,88,184,0,4,47,27,185,0,4,0,6,62,89,184,0,1,208,186,0,8,0,7,0,4,17,18,57,184,0,8,47,185,0,2,0,2,244,184,0,7,16,184,0,9,208,48,49,1,65,3,0,56,0,0,0,1,93,65,5,0,72,0,6,0,88,0,6,0,2,93,65,3,0,57,0,6,0,1,93,65,7,0,105,0,6,0,121,0,6,0,137,0,6,0,3,93,65,7,0,102,0,7,0,118,0,7,0,134,0,7,0,3,93,65,7,0,55,0,7,0,71,0,7,0,87,0,7,0,3,93,0,65,3,0,22,0,9,0,1,93,65,3,0,250,0,9,0,1,93,65,5,0,10,0,9,0,26,0,9,0,2,113,65,3,0,43,0,9,0,1,113,33,35,39,33,7,35,19,51,19,11,1,2,97,100,67,254,244,67,100,251,100,54,104,104,189,189,2,188,254,87,1,36,254,220,0,0,3,0,80,0,0,2,50,2,188,0,20,0,33,0,46,2,71,186,0,16,0,1,0,3,43,65,3,0,191,0,1,0,1,93,65,5,0,0,0,1,0,16,0,1,0,2,93,65,3,0,80,0,1,0,1,113,65,3,0,240,0,16,0,1,93,65,5,0,0,0,16,0,16,0,16,0,2,93,65,3,0,208,0,16,0,1,93,65,3,0,80,0,16,0,1,113,65,3,0,16,0,16,0,1,113,186,0,8,0,16,0,1,17,18,57,184,0,8,47,184,0,1,16,185,0,36,0,4,244,184,0,23,208,186,0,13,0,8,0,23,17,18,57,65,3,0,5,0,13,0,1,93,184,0,8,16,185,0,29,0,4,244,184,0,16,16,185,0,42,0,4,244,0,184,0,0,69,88,184,0,3,47,27,185,0,3,0,14,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,186,0,23,0,3,0,0,17,18,57,184,0,23,47,185,0,35,0,2,244,186,0,13,0,23,0,35,17,18,57,184,0,3,16,185,0,21,0,2,244,184,0,0,16,185,0,37,0,2,244,48,49,1,65,3,0,119,0,5,0,1,93,65,3,0,117,0,6,0,1,93,65,3,0,6,0,6,0,1,93,65,3,0,38,0,6,0,1,93,65,3,0,134,0,6,0,1,93,65,3,0,23,0,6,0,1,93,65,5,0,118,0,11,0,134,0,11,0,2,93,65,3,0,118,0,12,0,1,93,65,3,0,135,0,12,0,1,93,65,3,0,85,0,14,0,1,93,65,3,0,102,0,14,0,1,93,65,3,0,134,0,14,0,1,93,65,3,0,117,0,15,0,1,93,65,3,0,116,0,18,0,1,93,65,3,0,6,0,18,0,1,93,65,5,0,86,0,18,0,102,0,18,0,2,93,65,5,0,87,0,19,0,103,0,19,0,2,93,0,65,3,0,133,0,5,0,1,93,65,3,0,118,0,5,0,1,93,65,3,0,133,0,6,0,1,93,65,3,0,118,0,6,0,1,93,65,7,0,7,0,6,0,23,0,6,0,39,0,6,0,3,93,65,3,0,136,0,11,0,1,93,65,3,0,121,0,11,0,1,93,65,3,0,136,0,12,0,1,93,65,3,0,122,0,12,0,1,93,65,3,0,101,0,14,0,1,93,65,3,0,86,0,14,0,1,93,65,3,0,134,0,14,0,1,93,65,3,0,119,0,15,0,1,93,65,3,0,9,0,18,0,1,93,65,5,0,90,0,18,0,106,0,18,0,2,93,65,3,0,123,0,18,0,1,93,65,3,0,106,0,19,0,1,93,65,3,0,91,0,19,0,1,93,33,35,17,51,50,30,2,21,20,14,2,7,30,1,21,20,14,2,3,35,21,51,50,62,2,53,52,46,2,19,35,21,51,50,62,2,53,52,46,2,1,64,240,158,65,99,66,34,3,12,23,19,65,52,43,69,87,98,90,118,24,40,30,17,23,38,50,30,148,98,45,70,49,26,20,36,52,2,188,14,39,67,53,27,40,34,33,20,25,80,60,67,82,44,15,2,103,206,7,22,44,38,33,38,19,5,254,220,237,7,24,44,38,35,47,29,13,0,0,0,1,0,39,255,242,2,71,2,202,0,38,1,174,186,0,12,0,5,0,3,43,65,3,0,95,0,5,0,1,93,65,3,0,127,0,5,0,1,93,65,3,0,63,0,5,0,1,93,65,3,0,16,0,5,0,1,93,65,3,0,0,0,12,0,1,113,65,5,0,0,0,12,0,16,0,12,0,2,93,65,3,0,224,0,12,0,1,93,65,3,0,176,0,12,0,1,93,184,0,5,16,185,0,21,0,4,244,184,0,12,16,184,0,37,208,65,3,0,0,0,40,0,1,93,0,184,0,0,69,88,184,0,10,47,27,185,0,10,0,14,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,65,3,0,25,0,5,0,1,93,184,0,10,16,184,0,13,220,65,5,0,144,0,13,0,160,0,13,0,2,93,185,0,12,0,2,244,184,0,10,16,185,0,16,0,2,244,184,0,0,16,185,0,26,0,2,244,184,0,0,16,184,0,36,220,65,5,0,159,0,36,0,175,0,36,0,2,93,185,0,37,0,2,244,48,49,1,65,3,0,104,0,2,0,1,93,65,3,0,25,0,2,0,1,93,65,3,0,121,0,2,0,1,93,65,3,0,90,0,2,0,1,93,65,3,0,90,0,3,0,1,93,65,3,0,24,0,7,0,1,93,65,3,0,88,0,7,0,1,93,65,3,0,24,0,8,0,1,93,65,3,0,88,0,8,0,1,93,65,3,0,121,0,8,0,1,93,65,3,0,106,0,8,0,1,93,65,3,0,71,0,19,0,1,93,0,65,3,0,24,0,2,0,1,93,65,5,0,88,0,2,0,104,0,2,0,2,93,65,3,0,121,0,2,0,1,93,65,3,0,88,0,3,0,1,93,65,3,0,23,0,7,0,1,93,65,3,0,87,0,7,0,1,93,65,5,0,85,0,8,0,101,0,8,0,2,93,65,3,0,118,0,8,0,1,93,65,3,0,23,0,8,0,1,93,5,34,46,2,53,52,62,2,51,50,23,7,39,38,35,34,14,2,21,20,30,2,51,50,54,63,1,54,63,1,54,63,1,23,6,1,134,77,129,93,52,52,93,128,77,107,87,10,57,57,70,59,91,63,33,32,63,93,60,15,28,15,25,8,19,23,5,21,23,10,87,14,52,96,134,82,81,134,96,53,41,88,20,23,42,74,102,60,59,102,75,42,2,3,5,1,7,7,1,8,8,88,40,0,0,2,0,80,0,0,2,175,2,188,0,12,0,25,1,67,186,0,8,0,1,0,3,43,65,3,0,47,0,1,0,1,113,65,3,0,127,0,1,0,1,93,65,3,0,175,0,1,0,1,93,65,3,0,16,0,1,0,1,93,65,3,0,128,0,8,0,1,93,65,3,0,224,0,8,0,1,93,65,3,0,16,0,8,0,1,113,65,3,0,192,0,8,0,1,93,65,5,0,64,0,8,0,80,0,8,0,2,93,65,5,0,16,0,8,0,32,0,8,0,2,93,184,0,1,16,185,0,15,0,4,244,184,0,8,16,185,0,21,0,4,244,0,184,0,0,69,88,184,0,3,47,27,185,0,3,0,14,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,184,0,3,16,185,0,13,0,2,244,184,0,0,16,185,0,16,0,2,244,48,49,1,65,7,0,86,0,5,0,102,0,5,0,118,0,5,0,3,93,65,3,0,86,0,6,0,1,93,65,3,0,86,0,10,0,1,93,65,3,0,86,0,11,0,1,93,65,3,0,118,0,11,0,1,93,65,3,0,103,0,11,0,1,93,65,3,0,8,0,18,0,1,93,0,65,3,0,86,0,5,0,1,93,65,5,0,103,0,5,0,119,0,5,0,2,93,65,3,0,87,0,6,0,1,93,65,3,0,89,0,10,0,1,93,65,3,0,105,0,11,0,1,93,65,3,0,90,0,11,0,1,93,65,3,0,123,0,11,0,1,93,41,1,17,33,50,30,2,21,20,14,2,3,35,17,51,50,62,2,53,52,46,2,1,83,254,253,1,3,76,128,93,51,51,91,128,78,164,164,58,91,63,32,32,63,91,2,188,48,91,130,81,81,130,90,49,2,102,253,240,37,69,98,60,60,98,69,37,0,0,0,1,0,80,0,0,2,4,2,188,0,11,0,168,186,0,11,0,1,0,3,43,65,3,0,191,0,1,0,1,93,65,3,0,0,0,1,0,1,93,65,3,0,0,0,11,0,1,93,65,3,0,208,0,11,0,1,93,65,3,0,64,0,11,0,1,93,184,0,11,16,184,0,4,208,184,0,4,47,184,0,1,16,185,0,10,0,4,244,184,0,6,208,184,0,11,16,184,0,8,208,184,0,8,47,0,184,0,0,69,88,184,0,2,47,27,185,0,2,0,14,62,89,184,0,0,69,88,184,0,1,47,27,185,0,1,0,6,62,89,184,0,2,16,185,0,5,0,2,244,186,0,6,0,2,0,1,17,18,57,184,0,6,47,185,0,9,0,2,244,184,0,1,16,185,0,10,0,2,244,48,49,41,1,17,33,21,33,21,33,21,33,21,33,2,4,254,76,1,171,254,180,1,8,254,248,1,85,2,188,86,205,86,237,0,0,0,1,0,80,0,0,1,251,2,188,0,9,0,163,186,0,0,0,7,0,3,43,65,3,0,143,0,0,0,1,93,65,5,0,0,0,0,0,16,0,0,0,2,93,65,3,0,64,0,0,0,1,93,65,3,0,143,0,7,0,1,93,65,3,0,191,0,7,0,1,93,65,5,0,0,0,7,0,16,0,7,0,2,93,184,0,7,16,185,0,6,0,4,244,184,0,2,208,184,0,0,16,184,0,3,208,184,0,3,47,0,184,0,0,69,88,184,0,8,47,27,185,0,8,0,14,62,89,184,0,0,69,88,184,0,6,47,27,185,0,6,0,6,62,89,184,0,8,16,185,0,1,0,2,244,186,0,2,0,8,0,6,17,18,57,184,0,2,47,185,0,5,0,2,244,48,49,1,33,21,33,21,33,17,35,17,33,1,251,254,180,1,0,255,0,95,1,171,2,102,205,86,254,189,2,188,0,0,0,1,0,39,255,242,2,109,2,202,0,36,1,79,186,0,31,0,5,0,3,43,65,5,0,63,0,5,0,79,0,5,0,2,93,65,3,0,32,0,5,0,1,93,65,3,0,128,0,31,0,1,93,65,3,0,32,0,31,0,1,113,65,3,0,63,0,31,0,1,93,65,3,0,0,0,31,0,1,113,65,3,0,80,0,31,0,1,93,65,3,0,32,0,31,0,1,93,186,0,12,0,31,0,5,17,18,57,184,0,12,47,184,0,5,16,185,0,20,0,4,244,184,0,31,16,185,0,28,0,4,244,184,0,31,16,184,0,30,220,0,184,0,0,69,88,184,0,10,47,27,185,0,10,0,14,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,184,0,10,16,184,0,13,220,184,0,10,16,185,0,15,0,2,244,184,0,0,16,185,0,25,0,2,244,186,0,30,0,10,0,0,17,18,57,184,0,30,47,185,0,29,0,2,244,48,49,1,65,3,0,90,0,2,0,1,93,65,3,0,91,0,3,0,1,93,65,3,0,89,0,8,0,1,93,65,3,0,6,0,17,0,1,93,65,3,0,7,0,23,0,1,93,0,65,3,0,90,0,2,0,1,93,65,3,0,83,0,8,0,1,93,65,11,0,70,0,11,0,86,0,11,0,102,0,11,0,118,0,11,0,134,0,11,0,5,93,65,11,0,70,0,12,0,86,0,12,0,102,0,12,0,118,0,12,0,134,0,12,0,5,93,65,3,0,7,0,23,0,1,93,5,34,46,2,53,52,62,2,51,50,23,7,38,35,34,14,2,21,20,30,2,51,50,55,53,35,53,51,17,14,3,1,126,74,126,92,51,52,93,129,77,118,90,9,105,91,61,94,63,32,34,67,99,66,72,45,110,205,20,59,65,67,14,53,96,134,82,82,134,95,52,40,83,37,41,73,103,61,63,103,72,40,19,174,86,254,200,11,19,15,8,0,1,0,80,0,0,2,154,2,188,0,11,0,209,186,0,0,0,5,0,3,43,65,3,0,208,0,0,0,1,93,65,3,0,80,0,0,0,1,113,65,3,0,32,0,0,0,1,113,65,3,0,64,0,0,0,1,93,65,3,0,16,0,0,0,1,93,184,0,0,16,185,0,1,0,4,244,65,3,0,191,0,5,0,1,93,65,3,0,15,0,5,0,1,113,65,3,0,143,0,5,0,1,93,65,3,0,16,0,5,0,1,93,184,0,5,16,185,0,4,0,4,244,184,0,8,208,184,0,1,16,184,0,9,208,65,3,0,64,0,13,0,1,93,0,184,0,0,69,88,184,0,7,47,27,185,0,7,0,14,62,89,184,0,0,69,88,184,0,4,47,27,185,0,4,0,6,62,89,184,0,1,208,186,0,8,0,7,0,4,17,18,57,184,0,8,47,185,0,3,0,2,244,184,0,7,16,184,0,10,208,48,49,1,65,3,0,15,0,12,0,1,93,33,35,17,33,17,35,17,51,17,33,17,51,2,154,95,254,116,95,95,1,140,95,1,65,254,191,2,188,254,223,1,33,0,0,1,0,80,0,0,0,175,2,188,0,3,0,118,187,0,0,0,4,0,1,0,4,43,65,5,0,159,0,0,0,175,0,0,0,2,93,65,3,0,0,0,0,0,1,93,65,3,0,112,0,0,0,1,93,65,5,0,159,0,1,0,175,0,1,0,2,93,65,3,0,112,0,1,0,1,93,65,3,0,0,0,1,0,1,93,65,3,0,80,0,5,0,1,93,0,184,0,0,69,88,184,0,2,47,27,185,0,2,0,14,62,89,184,0,0,69,88,184,0,1,47,27,185,0,1,0,6,62,89,48,49,51,35,17,51,175,95,95,2,188,0,0,0,0,1,255,239,255,84,0,175,2,188,0,12,0,104,187,0,10,0,4,0,9,0,4,43,65,3,0,95,0,9,0,1,93,65,5,0,159,0,9,0,175,0,9,0,2,93,65,3,0,0,0,9,0,1,93,65,5,0,159,0,10,0,175,0,10,0,2,93,65,3,0,95,0,10,0,1,93,65,3,0,0,0,10,0,1,93,0,184,0,1,47,184,0,0,69,88,184,0,9,47,27,185,0,9,0,14,62,89,184,0,1,16,184,0,3,220,48,49,23,35,39,51,50,62,2,53,17,51,17,20,9,16,10,4,27,36,21,9,95,172,56,12,27,43,31,2,191,253,36,140,0,0,0,2,0,80,0,0,2,61,2,188,0,5,0,9,1,44,186,0,1,0,7,0,3,43,65,3,0,80,0,1,0,1,93,65,5,0,0,0,1,0,16,0,1,0,2,93,65,3,0,176,0,1,0,1,93,184,0,1,16,184,0,0,208,65,5,0,85,0,0,0,101,0,0,0,2,93,65,3,0,70,0,0,0,1,93,65,7,0,153,0,0,0,169,0,0,0,185,0,0,0,3,93,65,3,0,57,0,0,0,1,113,65,3,0,39,0,0,0,1,93,65,5,0,22,0,0,0,38,0,0,0,2,113,65,3,0,116,0,0,0,1,93,65,3,0,131,0,0,0,1,93,184,0,1,16,184,0,2,208,65,3,0,70,0,2,0,1,93,184,0,1,16,184,0,3,208,65,3,0,8,0,3,0,1,93,184,0,0,16,184,0,4,208,65,3,0,8,0,4,0,1,93,184,0,0,16,184,0,5,208,65,3,0,70,0,5,0,1,93,65,3,0,143,0,7,0,1,93,65,3,0,16,0,7,0,1,93,184,0,7,16,185,0,6,0,4,244,0,184,0,0,69,88,184,0,9,47,27,185,0,9,0,14,62,89,184,0,0,69,88,184,0,6,47,27,185,0,6,0,6,62,89,184,0,1,208,184,0,9,16,184,0,3,208,186,0,5,0,3,0,1,17,18,57,25,184,0,5,47,24,184,0,2,208,48,49,33,35,9,1,51,1,3,35,17,51,2,61,100,254,253,1,3,100,254,253,139,95,95,1,115,1,73,254,183,254,141,2,188,0,0,0,0,1,0,80,0,0,1,240,2,188,0,5,0,114,186,0,5,0,1,0,3,43,65,3,0,175,0,1,0,1,93,65,5,0,0,0,1,0,16,0,1,0,2,93,65,3,0,144,0,1,0,1,93,184,0,1,16,185,0,4,0,4,244,65,3,0,175,0,5,0,1,93,65,5,0,0,0,5,0,16,0,5,0,2,93,0,184,0,0,69,88,184,0,3,47,27,185,0,3,0,14,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,185,0,5,0,2,244,48,49,41,1,17,51,17,33,1,240,254,96,95,1,65,2,188,253,154,0,0,0,0,1,0,48,0,0,2,252,2,188,0,11,2,149,186,0,0,0,6,0,3,43,65,3,0,80,0,0,0,1,113,65,3,0,63,0,0,0,1,93,65,5,0,160,0,0,0,176,0,0,0,2,113,65,5,0,80,0,0,0,96,0,0,0,2,93,65,5,0,0,0,0,0,16,0,0,0,2,93,184,0,0,16,185,0,1,0,4,244,184,0,2,208,65,3,0,7,0,2,0,1,113,65,5,0,22,0,2,0,38,0,2,0,2,113,65,3,0,47,0,6,0,1,113,65,3,0,143,0,6,0,1,93,65,5,0,47,0,6,0,63,0,6,0,2,93,65,3,0,15,0,6,0,1,113,65,3,0,80,0,6,0,1,113,65,5,0,0,0,6,0,16,0,6,0,2,93,186,0,3,0,6,0,0,17,18,57,184,0,6,16,185,0,5,0,4,244,184,0,4,208,65,5,0,25,0,4,0,41,0,4,0,2,113,65,3,0,8,0,4,0,1,113,184,0,6,16,184,0,7,208,65,7,0,57,0,7,0,73,0,7,0,89,0,7,0,3,113,65,3,0,152,0,7,0,1,93,186,0,8,0,4,0,7,17,18,57,65,3,0,7,0,8,0,1,113,184,0,3,16,184,0,9,208,184,0,0,16,184,0,11,208,65,3,0,136,0,11,0,1,93,65,3,0,151,0,11,0,1,93,65,7,0,54,0,11,0,70,0,11,0,86,0,11,0,3,113,186,0,10,0,2,0,11,17,18,57,65,3,0,8,0,10,0,1,113,0,184,0,0,69,88,184,0,8,47,27,185,0,8,0,14,62,89,184,0,0,69,88,184,0,5,47,27,185,0,5,0,6,62,89,184,0,1,208,184,0,8,16,184,0,4,208,65,5,0,91,0,4,0,107,0,4,0,2,113,65,5,0,60,0,4,0,76,0,4,0,2,113,65,3,0,45,0,4,0,1,113,65,3,0,31,0,4,0,1,113,65,3,0,142,0,4,0,1,93,65,3,0,13,0,4,0,1,113,65,3,0,252,0,4,0,1,93,65,5,0,107,0,4,0,123,0,4,0,2,93,65,3,0,89,0,4,0,1,93,184,0,2,208,186,0,3,0,8,0,5,17,18,57,65,5,0,89,0,3,0,105,0,3,0,2,93,184,0,3,16,184,0,9,208,65,7,0,84,0,9,0,100,0,9,0,116,0,9,0,3,93,65,3,0,244,0,9,0,1,93,65,3,0,154,0,9,0,1,93,65,3,0,69,0,9,0,1,93,65,5,0,84,0,9,0,100,0,9,0,2,113,65,3,0,67,0,9,0,1,113,65,3,0,130,0,9,0,1,93,184,0,8,16,184,0,10,208,48,49,1,65,3,0,117,0,8,0,1,93,65,3,0,122,0,10,0,1,93,0,65,3,0,124,0,2,0,1,93,65,3,0,41,0,3,0,1,113,65,3,0,10,0,3,0,1,93,65,3,0,123,0,4,0,1,93,65,5,0,20,0,9,0,36,0,9,0,2,113,33,35,11,3,35,19,51,27,1,51,2,252,100,66,190,194,66,100,94,81,184,182,82,2,17,254,149,1,107,253,239,2,188,254,165,1,91,0,1,0,80,0,0,2,112,2,188,0,9,1,47,186,0,9,0,4,0,3,43,65,3,0,0,0,9,0,1,93,65,3,0,112,0,9,0,1,93,65,3,0,48,0,9,0,1,93,65,3,0,32,0,9,0,1,113,65,3,0,0,0,9,0,1,113,184,0,9,16,185,0,8,0,4,244,184,0,1,208,65,5,0,0,0,4,0,16,0,4,0,2,93,184,0,4,16,185,0,3,0,4,244,184,0,6,208,65,3,0,134,0,6,0,1,93,65,5,0,20,0,6,0,36,0,6,0,2,113,0,184,0,0,69,88,184,0,5,47,27,185,0,5,0,14,62,89,184,0,0,69,88,184,0,3,47,27,185,0,3,0,6,62,89,184,0,1,208,184,0,5,16,184,0,2,208,65,3,0,57,0,2,0,1,93,184,0,1,16,184,0,7,208,184,0,5,16,184,0,8,208,48,49,1,65,3,0,89,0,1,0,1,93,65,3,0,85,0,6,0,1,93,0,65,5,0,74,0,2,0,90,0,2,0,2,93,65,3,0,43,0,2,0,1,113,65,5,0,108,0,2,0,124,0,2,0,2,93,65,3,0,143,0,2,0,1,93,65,3,0,128,0,7,0,1,93,65,3,0,67,0,7,0,1,93,65,5,0,99,0,7,0,115,0,7,0,2,93,65,3,0,35,0,7,0,1,113,65,3,0,84,0,7,0,1,93,33,35,1,17,35,17,51,1,17,51,2,112,81,254,144,95,103,1,89,96,2,41,253,215,2,188,253,244,2,12,0,0,2,0,39,255,242,2,217,2,202,0,18,0,37,1,177,186,0,17,0,7,0,3,43,65,3,0,15,0,7,0,1,93,65,5,0,79,0,7,0,95,0,7,0,2,93,65,5,0,176,0,17,0,192,0,17,0,2,93,65,3,0,32,0,17,0,1,113,65,3,0,113,0,17,0,1,93,65,5,0,224,0,17,0,240,0,17,0,2,93,65,3,0,128,0,17,0,1,93,65,3,0,32,0,17,0,1,93,184,0,7,16,185,0,26,0,4,244,184,0,17,16,185,0,36,0,4,244,0,184,0,0,69,88,184,0,12,47,27,185,0,12,0,14,62,89,184,0,0,69,88,184,0,2,47,27,185,0,2,0,6,62,89,184,0,12,16,185,0,21,0,2,244,184,0,2,16,185,0,31,0,2,244,48,49,1,65,3,0,86,0,0,0,1,93,65,5,0,103,0,0,0,119,0,0,0,2,93,65,3,0,88,0,4,0,1,93,65,5,0,105,0,4,0,121,0,4,0,2,93,65,3,0,88,0,5,0,1,93,65,3,0,88,0,9,0,1,93,65,3,0,120,0,9,0,1,93,65,3,0,105,0,10,0,1,93,65,3,0,90,0,10,0,1,93,65,7,0,87,0,14,0,103,0,14,0,119,0,14,0,3,93,65,3,0,86,0,15,0,1,93,65,3,0,118,0,15,0,1,93,65,3,0,15,0,38,0,1,93,0,65,3,0,104,0,0,0,1,93,65,3,0,90,0,0,0,1,93,65,3,0,122,0,0,0,1,93,65,5,0,89,0,4,0,105,0,4,0,2,93,65,3,0,123,0,4,0,1,93,65,3,0,89,0,5,0,1,93,65,3,0,86,0,9,0,1,93,65,3,0,119,0,9,0,1,93,65,5,0,86,0,10,0,102,0,10,0,2,93,65,3,0,86,0,14,0,1,93,65,5,0,103,0,14,0,119,0,14,0,2,93,65,3,0,86,0,15,0,1,93,65,3,0,119,0,15,0,1,93,37,6,35,34,46,2,53,52,62,2,51,50,30,2,21,20,3,38,35,34,14,2,21,20,30,2,51,50,62,2,53,52,2,120,96,152,76,127,91,51,52,91,127,75,75,127,92,51,167,62,116,58,90,61,32,32,61,90,58,58,90,62,31,85,99,52,95,134,83,83,134,95,52,52,96,134,82,165,1,109,78,42,74,102,60,60,102,74,42,42,75,101,60,122,0,0,2,0,80,0,0,2,36,2,188,0,14,0,25,1,63,186,0,9,0,2,0,3,43,65,5,0,0,0,2,0,16,0,2,0,2,93,65,3,0,143,0,2,0,1,93,65,3,0,175,0,2,0,1,93,65,3,0,144,0,2,0,1,93,65,3,0,112,0,2,0,1,93,184,0,2,16,185,0,1,0,4,244,65,3,0,80,0,9,0,1,93,65,3,0,144,0,9,0,1,93,65,3,0,0,0,9,0,1,113,65,3,0,175,0,9,0,1,93,65,3,0,224,0,9,0,1,93,65,3,0,112,0,9,0,1,93,65,5,0,0,0,9,0,16,0,9,0,2,93,65,3,0,32,0,9,0,1,113,184,0,16,208,184,0,9,16,185,0,20,0,4,244,0,184,0,0,69,88,184,0,4,47,27,185,0,4,0,14,62,89,184,0,0,69,88,184,0,1,47,27,185,0,1,0,6,62,89,186,0,0,0,4,0,1,17,18,57,184,0,0,47,185,0,16,0,2,244,184,0,4,16,185,0,25,0,2,244,48,49,1,65,3,0,135,0,6,0,1,93,65,5,0,101,0,7,0,117,0,7,0,2,93,65,3,0,6,0,7,0,1,93,65,3,0,134,0,7,0,1,93,0,65,3,0,134,0,6,0,1,93,65,5,0,103,0,6,0,119,0,6,0,2,93,65,5,0,101,0,7,0,117,0,7,0,2,93,65,3,0,6,0,7,0,1,93,65,3,0,135,0,7,0,1,93,55,21,35,17,51,50,30,2,21,20,14,2,35,3,17,51,50,54,53,52,46,2,35,180,100,224,49,88,67,40,41,64,76,35,152,134,73,62,16,38,63,46,245,245,2,188,15,47,86,70,68,91,55,23,1,114,254,227,77,71,37,53,32,15,0,0,2,0,39,255,242,2,217,2,202,0,21,0,43,2,27,186,0,19,0,9,0,3,43,65,5,0,224,0,19,0,240,0,19,0,2,93,65,3,0,32,0,19,0,1,93,65,3,0,32,0,19,0,1,113,65,5,0,176,0,19,0,192,0,19,0,2,93,65,3,0,112,0,19,0,1,93,65,5,0,79,0,9,0,95,0,9,0,2,93,65,3,0,15,0,9,0,1,93,186,0,21,0,19,0,9,17,18,57,184,0,21,16,184,0,0,208,186,0,2,0,9,0,19,17,18,57,184,0,2,16,184,0,1,208,65,3,0,88,0,1,0,1,113,184,0,9,16,185,0,27,0,4,244,184,0,19,16,185,0,39,0,4,244,186,0,34,0,27,0,39,17,18,57,65,3,0,121,0,34,0,1,93,184,0,34,16,184,0,35,208,65,3,0,56,0,35,0,1,113,65,3,0,72,0,35,0,1,93,186,0,37,0,39,0,27,17,18,57,184,0,37,16,184,0,36,208,65,3,0,15,0,44,0,1,93,0,184,0,0,69,88,184,0,14,47,27,185,0,14,0,14,62,89,184,0,0,69,88,184,0,4,47,27,185,0,4,0,6,62,89,186,0,2,0,4,0,14,17,18,57,184,0,2,16,184,0,1,208,184,0,1,47,186,0,21,0,14,0,4,17,18,57,184,0,14,16,185,0,22,0,2,244,184,0,4,16,185,0,32,0,2,244,186,0,34,0,32,0,22,17,18,57,186,0,37,0,22,0,32,17,18,57,184,0,37,16,184,0,36,208,184,0,36,47,48,49,1,65,3,0,104,0,1,0,1,93,65,3,0,89,0,6,0,1,93,65,3,0,121,0,6,0,1,93,65,3,0,89,0,7,0,1,93,65,3,0,89,0,11,0,1,93,65,3,0,123,0,11,0,1,93,65,5,0,89,0,12,0,105,0,12,0,2,93,65,7,0,86,0,16,0,102,0,16,0,118,0,16,0,3,93,65,3,0,86,0,17,0,1,93,65,3,0,105,0,35,0,1,93,0,65,3,0,89,0,2,0,1,93,65,3,0,89,0,6,0,1,93,65,3,0,121,0,6,0,1,93,65,3,0,106,0,6,0,1,93,65,3,0,89,0,7,0,1,93,65,3,0,87,0,11,0,1,93,65,3,0,119,0,11,0,1,93,65,5,0,86,0,12,0,102,0,12,0,2,93,65,3,0,86,0,16,0,1,93,65,3,0,118,0,16,0,1,93,37,7,39,6,35,34,46,2,53,52,62,2,51,50,30,2,21,20,7,1,34,14,2,21,20,30,2,51,50,55,39,55,23,54,53,52,46,2,2,203,50,65,100,116,76,127,91,51,52,91,127,75,75,127,92,51,74,254,241,59,89,62,31,31,60,90,60,96,55,103,50,105,48,34,65,93,62,59,54,71,52,95,134,83,83,134,95,52,52,96,134,82,129,110,2,5,41,74,102,61,60,102,74,42,40,84,61,93,75,111,60,101,75,42,0,0,0,0,2,0,80,0,0,2,72,2,188,0,15,0,26,1,159,186,0,12,0,5,0,3,43,65,3,0,15,0,5,0,1,113,65,5,0,0,0,5,0,16,0,5,0,2,93,65,3,0,144,0,5,0,1,93,65,3,0,224,0,12,0,1,93,65,5,0,0,0,12,0,16,0,12,0,2,93,65,3,0,112,0,12,0,1,93,65,3,0,80,0,12,0,1,93,186,0,15,0,5,0,12,17,18,57,65,3,0,38,0,15,0,1,93,65,3,0,23,0,15,0,1,93,65,3,0,135,0,15,0,1,93,65,3,0,102,0,15,0,1,93,65,3,0,85,0,15,0,1,93,65,3,0,117,0,15,0,1,93,184,0,15,16,184,0,0,208,184,0,15,16,185,0,2,0,4,244,65,3,0,136,0,2,0,1,93,184,0,1,208,184,0,5,16,185,0,4,0,4,244,184,0,18,208,184,0,12,16,185,0,24,0,4,244,0,184,0,0,69,88,184,0,7,47,27,185,0,7,0,14,62,89,184,0,0,69,88,184,0,4,47,27,185,0,4,0,6,62,89,184,0,1,208,186,0,3,0,7,0,4,17,18,57,184,0,3,47,186,0,15,0,3,0,7,17,18,57,184,0,7,16,185,0,16,0,2,244,184,0,3,16,185,0,18,0,2,244,48,49,1,65,3,0,102,0,9,0,1,93,65,3,0,100,0,10,0,1,93,65,3,0,134,0,10,0,1,93,65,3,0,22,0,10,0,1,113,65,3,0,7,0,10,0,1,93,65,3,0,119,0,10,0,1,93,65,3,0,89,0,22,0,1,93,65,3,0,89,0,26,0,1,93,0,65,5,0,101,0,9,0,117,0,9,0,2,93,65,3,0,117,0,10,0,1,93,65,3,0,102,0,10,0,1,93,65,3,0,7,0,10,0,1,93,65,3,0,23,0,10,0,1,113,65,3,0,85,0,22,0,1,93,33,35,3,35,17,35,17,51,50,30,2,21,20,6,7,3,35,17,51,50,62,2,53,52,38,2,72,102,155,147,100,227,58,91,61,32,67,61,115,126,151,24,43,33,19,72,1,17,254,239,2,188,22,49,78,56,66,103,28,1,69,254,254,16,32,49,33,61,67,0,1,0,40,255,242,2,41,2,202,0,57,3,109,186,0,53,0,19,0,3,43,65,3,0,79,0,19,0,1,93,65,3,0,111,0,19,0,1,93,65,3,0,80,0,53,0,1,93,65,3,0,160,0,53,0,1,93,65,3,0,224,0,53,0,1,93,65,3,0,192,0,53,0,1,93,65,5,0,112,0,53,0,128,0,53,0,2,93,65,3,0,32,0,53,0,1,93,65,3,0,0,0,53,0,1,93,186,0,2,0,19,0,53,17,18,57,184,0,2,47,184,0,53,16,185,0,10,0,4,244,186,0,29,0,53,0,19,17,18,57,184,0,29,47,184,0,19,16,185,0,37,0,4,244,0,184,0,0,69,88,184,0,24,47,27,185,0,24,0,14,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,184,0,3,220,65,5,0,112,0,3,0,128,0,3,0,2,93,65,3,0,16,0,3,0,1,93,65,3,0,240,0,3,0,1,93,184,0,0,16,185,0,5,0,2,244,186,0,15,0,0,0,24,17,18,57,65,3,0,137,0,15,0,1,93,184,0,24,16,184,0,30,220,65,3,0,143,0,30,0,1,93,65,3,0,255,0,30,0,1,93,184,0,24,16,185,0,32,0,2,244,186,0,40,0,24,0,0,17,18,57,48,49,1,65,11,0,40,0,2,0,56,0,2,0,72,0,2,0,88,0,2,0,104,0,2,0,5,93,65,3,0,136,0,2,0,1,93,65,5,0,56,0,12,0,72,0,12,0,2,93,65,3,0,138,0,12,0,1,93,65,3,0,105,0,16,0,1,93,65,3,0,72,0,17,0,1,93,65,3,0,72,0,18,0,1,93,65,3,0,58,0,18,0,1,93,65,3,0,138,0,18,0,1,93,65,3,0,105,0,21,0,1,93,65,3,0,137,0,21,0,1,93,65,3,0,121,0,22,0,1,93,65,3,0,106,0,22,0,1,93,65,3,0,120,0,39,0,1,93,65,3,0,6,0,49,0,1,93,65,3,0,101,0,50,0,1,93,65,3,0,6,0,50,0,1,93,65,3,0,38,0,50,0,1,93,65,3,0,118,0,50,0,1,93,65,3,0,100,0,55,0,1,93,65,3,0,132,0,55,0,1,93,65,3,0,117,0,55,0,1,93,65,3,0,6,0,56,0,1,93,65,3,0,102,0,56,0,1,93,65,3,0,119,0,56,0,1,93,0,65,11,0,41,0,1,0,57,0,1,0,73,0,1,0,89,0,1,0,105,0,1,0,5,93,65,11,0,40,0,2,0,56,0,2,0,72,0,2,0,88,0,2,0,104,0,2,0,5,93,65,3,0,138,0,2,0,1,93,65,3,0,123,0,2,0,1,93,65,3,0,136,0,12,0,1,93,65,5,0,57,0,12,0,73,0,12,0,2,93,65,3,0,90,0,14,0,1,93,65,3,0,105,0,16,0,1,93,65,3,0,10,0,17,0,1,93,65,3,0,74,0,17,0,1,93,65,3,0,135,0,18,0,1,93,65,3,0,72,0,18,0,1,93,65,3,0,133,0,21,0,1,93,65,3,0,103,0,21,0,1,93,65,3,0,116,0,22,0,1,93,65,3,0,101,0,22,0,1,93,65,11,0,38,0,27,0,54,0,27,0,70,0,27,0,86,0,27,0,102,0,27,0,5,93,65,3,0,132,0,28,0,1,93,65,13,0,38,0,28,0,54,0,28,0,70,0,28,0,86,0,28,0,102,0,28,0,118,0,28,0,6,93,65,3,0,116,0,39,0,1,93,65,3,0,7,0,49,0,1,93,65,3,0,102,0,50,0,1,93,65,3,0,7,0,50,0,1,93,65,3,0,39,0,50,0,1,93,65,3,0,105,0,55,0,1,93,65,3,0,137,0,55,0,1,93,65,3,0,122,0,55,0,1,93,65,3,0,9,0,56,0,1,93,65,3,0,106,0,56,0,1,93,65,3,0,123,0,56,0,1,93,5,34,39,55,22,51,50,62,2,53,52,46,2,47,1,46,1,53,52,62,2,51,50,30,2,23,7,38,35,34,14,2,21,20,22,23,30,3,31,1,30,1,31,1,30,1,23,20,14,2,1,24,145,84,13,94,124,36,61,45,25,26,47,67,41,70,85,73,24,57,97,74,30,64,59,50,17,10,126,75,29,57,44,27,75,76,21,19,18,31,34,34,13,17,5,25,23,15,3,18,58,107,14,45,111,70,13,27,41,27,28,41,32,26,14,23,28,83,57,30,71,61,40,8,13,18,9,101,63,12,26,38,27,44,49,24,7,4,5,11,15,18,7,10,5,26,24,56,39,30,67,58,39,0,1,0,15,0,0,2,6,2,188,0,7,0,86,187,0,1,0,4,0,4,0,4,43,184,0,1,16,184,0,0,220,184,0,4,16,184,0,5,220,65,3,0,31,0,9,0,1,93,0,184,0,0,69,88,184,0,6,47,27,185,0,6,0,14,62,89,184,0,0,69,88,184,0,3,47,27,185,0,3,0,6,62,89,184,0,6,16,185,0,5,0,2,244,184,0,1,208,48,49,1,35,17,35,17,35,53,33,2,6,204,95,204,1,247,2,102,253,154,2,102,86,0,0,0,1,0,72,255,242,2,140,2,188,0,21,1,207,186,0,15,0,1,0,3,43,65,3,0,223,0,1,0,1,93,65,3,0,143,0,1,0,1,93,65,5,0,175,0,1,0,191,0,1,0,2,93,65,3,0,16,0,1,0,1,93,184,0,1,16,185,0,2,0,4,244,65,3,0,64,0,15,0,1,93,65,3,0,175,0,15,0,1,93,65,3,0,240,0,15,0,1,93,65,3,0,0,0,15,0,1,113,65,3,0,16,0,15,0,1,93,65,3,0,32,0,15,0,1,113,184,0,15,16,185,0,14,0,4,244,65,3,0,15,0,22,0,1,93,0,184,0,0,69,88,184,0,2,47,27,185,0,2,0,14,62,89,184,0,0,69,88,184,0,19,47,27,185,0,19,0,6,62,89,185,0,8,0,2,244,184,0,2,16,184,0,14,208,48,49,1,65,3,0,103,0,5,0,1,93,65,3,0,135,0,5,0,1,93,65,3,0,136,0,10,0,1,93,65,3,0,104,0,11,0,1,93,65,3,0,136,0,11,0,1,93,65,3,0,36,0,17,0,1,93,65,3,0,22,0,17,0,1,93,65,3,0,118,0,17,0,1,93,65,3,0,23,0,18,0,1,93,65,3,0,71,0,18,0,1,93,65,3,0,24,0,20,0,1,93,65,3,0,72,0,20,0,1,93,65,3,0,58,0,20,0,1,93,65,3,0,25,0,21,0,1,93,65,3,0,122,0,21,0,1,93,65,3,0,43,0,21,0,1,93,0,65,3,0,133,0,5,0,1,93,65,3,0,102,0,5,0,1,93,65,3,0,133,0,6,0,1,93,65,3,0,134,0,10,0,1,93,65,3,0,101,0,11,0,1,93,65,3,0,135,0,11,0,1,93,65,3,0,120,0,17,0,1,93,65,3,0,56,0,18,0,1,93,65,3,0,41,0,18,0,1,93,65,3,0,73,0,18,0,1,93,65,3,0,27,0,18,0,1,93,65,3,0,25,0,20,0,1,93,65,3,0,57,0,20,0,1,93,65,3,0,42,0,20,0,1,93,65,3,0,74,0,20,0,1,93,19,17,51,17,20,30,2,51,50,62,2,53,17,51,17,20,6,35,34,38,72,95,14,41,77,63,63,77,42,13,95,145,145,145,145,1,41,1,147,254,155,51,97,77,46,48,76,97,50,1,101,254,109,148,163,163,0,0,0,0,1,0,4,0,0,2,128,2,188,0,6,1,95,187,0,1,0,4,0,2,0,4,43,65,3,0,16,0,1,0,1,93,65,3,0,112,0,1,0,1,93,65,5,0,32,0,1,0,48,0,1,0,2,113,184,0,1,16,184,0,0,208,65,3,0,24,0,0,0,1,93,65,3,0,71,0,0,0,1,93,65,3,0,134,0,0,0,1,93,65,3,0,112,0,2,0,1,93,65,3,0,16,0,2,0,1,93,65,5,0,32,0,2,0,48,0,2,0,2,113,184,0,2,16,184,0,3,208,65,3,0,137,0,3,0,1,93,65,3,0,72,0,3,0,1,93,185,0,4,0,4,244,186,0,5,0,2,0,1,17,18,57,184,0,0,16,185,0,6,0,4,244,65,3,0,79,0,8,0,1,93,0,184,0,0,69,88,184,0,4,47,27,185,0,4,0,14,62,89,184,0,0,69,88,184,0,2,47,27,185,0,2,0,6,62,89,184,0,5,208,184,0,4,16,184,0,6,208,48,49,1,65,3,0,134,0,1,0,1,93,65,13,0,167,0,1,0,183,0,1,0,199,0,1,0,215,0,1,0,231,0,1,0,247,0,1,0,6,93,65,7,0,7,0,1,0,23,0,1,0,39,0,1,0,3,113,65,13,0,168,0,2,0,184,0,2,0,200,0,2,0,216,0,2,0,232,0,2,0,248,0,2,0,6,93,65,7,0,8,0,2,0,24,0,2,0,40,0,2,0,3,113,65,3,0,137,0,2,0,1,93,0,65,5,0,100,0,5,0,116,0,5,0,2,93,65,3,0,85,0,5,0,1,93,9,1,35,1,51,27,1,2,128,254,244,100,254,244,100,219,217,2,188,253,68,2,188,253,177,2,79,0,1,0,14,0,0,3,193,2,188,0,12,1,221,186,0,10,0,9,0,3,43,65,3,0,63,0,10,0,1,93,184,0,10,16,184,0,1,220,65,3,0,47,0,1,0,1,93,184,0,0,208,184,0,1,16,185,0,2,0,4,244,65,3,0,63,0,9,0,1,93,186,0,3,0,9,0,10,17,18,57,184,0,9,16,184,0,5,220,185,0,4,0,4,244,184,0,5,16,184,0,6,208,65,3,0,71,0,6,0,1,93,185,0,7,0,4,244,186,0,8,0,5,0,4,17,18,57,186,0,11,0,2,0,1,17,18,57,184,0,0,16,185,0,12,0,4,244,65,3,0,191,0,14,0,1,93,65,3,0,159,0,14,0,1,93,0,184,0,0,69,88,184,0,7,47,27,185,0,7,0,14,62,89,184,0,0,69,88,184,0,5,47,27,185,0,5,0,6,62,89,184,0,2,208,184,0,7,16,184,0,9,208,184,0,9,47,184,0,3,208,184,0,5,16,184,0,8,208,184,0,11,208,184,0,7,16,184,0,12,208,48,49,1,65,3,0,40,0,1,0,1,93,65,3,0,8,0,2,0,1,93,65,5,0,56,0,2,0,72,0,2,0,2,93,65,3,0,137,0,2,0,1,93,65,3,0,122,0,2,0,1,93,65,7,0,102,0,4,0,118,0,4,0,134,0,4,0,3,93,65,3,0,71,0,4,0,1,93,65,3,0,247,0,4,0,1,93,65,3,0,135,0,7,0,1,93,65,3,0,104,0,9,0,1,93,65,3,0,136,0,9,0,1,93,65,3,0,248,0,9,0,1,93,65,3,0,7,0,10,0,1,93,65,3,0,71,0,10,0,1,93,65,3,0,135,0,10,0,1,93,65,3,0,56,0,10,0,1,93,65,3,0,41,0,10,0,1,93,0,65,3,0,4,0,3,0,1,93,65,3,0,21,0,3,0,1,93,65,3,0,70,0,3,0,1,93,65,3,0,123,0,3,0,1,93,65,3,0,26,0,8,0,1,93,65,3,0,11,0,8,0,1,93,65,3,0,57,0,11,0,1,93,65,3,0,26,0,11,0,1,93,65,3,0,12,0,11,0,1,93,1,3,35,11,1,35,3,51,27,1,51,27,1,3,193,205,105,165,171,105,196,100,155,175,86,177,154,2,188,253,68,2,62,253,194,2,188,253,176,2,66,253,191,2,79,0,1,0,9,0,0,2,82,2,188,0,11,1,205,187,0,11,0,4,0,5,0,4,43,184,0,11,16,184,0,0,208,65,3,0,182,0,0,0,1,93,65,3,0,22,0,0,0,1,113,65,3,0,215,0,0,0,1,93,65,3,0,87,0,0,0,1,93,65,3,0,136,0,0,0,1,93,65,3,0,151,0,0,0,1,93,65,3,0,23,0,0,0,1,93,65,3,0,54,0,0,0,1,113,65,3,0,246,0,0,0,1,93,65,3,0,101,0,0,0,1,93,65,3,0,36,0,0,0,1,93,185,0,1,0,4,244,65,3,0,39,0,1,0,1,93,186,0,2,0,5,0,11,17,18,57,184,0,5,16,184,0,4,208,65,3,0,54,0,4,0,1,93,65,3,0,215,0,4,0,1,93,65,3,0,41,0,4,0,1,93,65,3,0,105,0,4,0,1,93,65,3,0,230,0,4,0,1,93,65,5,0,118,0,4,0,134,0,4,0,2,93,65,3,0,166,0,4,0,1,93,185,0,3,0,4,244,184,0,4,16,184,0,6,208,184,0,3,16,184,0,7,208,65,3,0,118,0,7,0,1,93,186,0,8,0,5,0,11,17,18,57,184,0,1,16,184,0,9,208,184,0,0,16,184,0,10,208,65,3,0,15,0,13,0,1,93,0,184,0,0,69,88,184,0,7,47,27,185,0,7,0,14,62,89,184,0,0,69,88,184,0,3,47,27,185,0,3,0,6,62,89,184,0,1,208,186,0,2,0,3,0,7,17,18,57,65,3,0,150,0,2,0,1,93,186,0,8,0,7,0,3,17,18,57,186,0,5,0,8,0,2,17,18,57,184,0,7,16,184,0,9,208,186,0,11,0,2,0,8,17,18,57,48,49,65,3,0,74,0,2,0,1,93,65,3,0,106,0,2,0,1,93,65,3,0,138,0,2,0,1,93,65,3,0,123,0,2,0,1,93,65,3,0,116,0,8,0,1,93,65,3,0,101,0,8,0,1,93,65,3,0,133,0,8,0,1,93,65,7,0,54,0,8,0,70,0,8,0,86,0,8,0,3,93,33,35,11,1,35,19,3,51,27,1,51,3,2,82,100,202,183,100,235,235,110,180,194,100,250,1,30,254,226,1,93,1,95,254,239,1,17,254,173,0,0,0,1,255,253,0,0,2,57,2,188,0,8,0,233,187,0,1,0,4,0,4,0,4,43,65,3,0,175,0,1,0,1,93,65,3,0,32,0,1,0,1,93,184,0,1,16,184,0,0,208,65,3,0,121,0,0,0,1,93,65,3,0,102,0,0,0,1,93,65,3,0,38,0,0,0,1,93,65,3,0,175,0,4,0,1,93,65,3,0,32,0,4,0,1,93,184,0,4,16,184,0,5,208,65,3,0,105,0,5,0,1,93,65,3,0,41,0,5,0,1,93,65,3,0,118,0,5,0,1,93,185,0,6,0,4,244,186,0,7,0,4,0,1,17,18,57,184,0,0,16,185,0,8,0,4,244,0,184,0,0,69,88,184,0,6,47,27,185,0,6,0,14,62,89,184,0,0,69,88,184,0,2,47,27,185,0,2,0,6,62,89,186,0,7,0,6,0,2,17,18,57,184,0,6,16,184,0,8,208,48,49,65,3,0,88,0,1,0,1,93,65,3,0,89,0,4,0,1,93,65,3,0,131,0,7,0,1,93,65,3,0,116,0,7,0,1,93,1,3,17,35,17,3,51,27,1,2,57,236,99,237,100,186,186,2,188,254,135,254,189,1,67,1,121,254,221,1,35,0,0,0,1,0,9,0,0,2,30,2,188,0,7,1,200,186,0,2,0,6,0,3,43,65,3,0,64,0,2,0,1,93,65,3,0,175,0,2,0,1,93,65,3,0,96,0,2,0,1,93,65,5,0,16,0,2,0,32,0,2,0,2,93,65,3,0,128,0,2,0,1,93,184,0,2,16,184,0,0,208,65,3,0,16,0,6,0,1,93,184,0,6,16,184,0,4,208,184,0,1,208,65,3,0,99,0,1,0,1,93,65,3,0,69,0,1,0,1,93,65,5,0,85,0,1,0,101,0,1,0,2,113,65,3,0,38,0,1,0,1,93,65,3,0,184,0,1,0,1,93,65,5,0,153,0,1,0,169,0,1,0,2,93,65,5,0,54,0,1,0,70,0,1,0,2,113,65,3,0,246,0,1,0,1,93,65,3,0,6,0,1,0,1,113,65,3,0,21,0,1,0,1,113,65,3,0,36,0,1,0,1,113,65,3,0,114,0,1,0,1,93,65,3,0,128,0,1,0,1,93,184,0,0,16,184,0,5,208,65,3,0,24,0,5,0,1,93,65,3,0,41,0,5,0,1,93,65,3,0,58,0,5,0,1,113,65,3,0,74,0,5,0,1,93,65,3,0,43,0,5,0,1,113,65,3,0,125,0,5,0,1,93,65,3,0,143,0,5,0,1,93,65,3,0,108,0,5,0,1,93,65,3,0,26,0,5,0,1,113,65,5,0,90,0,5,0,106,0,5,0,2,113,65,3,0,249,0,5,0,1,93,65,3,0,9,0,5,0,1,113,65,3,0,73,0,5,0,1,113,65,3,0,183,0,5,0,1,93,65,5,0,150,0,5,0,166,0,5,0,2,93,0,184,0,0,69,88,184,0,7,47,27,185,0,7,0,14,62,89,184,0,0,69,88,184,0,3,47,27,185,0,3,0,6,62,89,185,0,2,0,2,244,184,0,7,16,185,0,6,0,2,244,48,49,1,65,3,0,84,0,1,0,1,93,65,3,0,54,0,1,0,1,93,65,3,0,57,0,5,0,1,93,65,3,0,91,0,5,0,1,93,9,1,33,21,33,1,33,53,2,30,254,135,1,76,254,24,1,120,254,181,2,188,253,154,86,2,102,86,0,0,0,1,0,70,255,121,1,71,2,238,0,7,0,78,184,0,1,47,65,3,0,143,0,1,0,1,93,65,5,0,0,0,1,0,16,0,1,0,2,93,184,0,0,220,184,0,4,208,184,0,1,16,184,0,6,220,0,184,0,0,47,184,0,0,69,88,184,0,3,47,27,185,0,3,0,18,62,89,184,0,4,220,184,0,0,16,184,0,7,220,48,49,5,33,17,33,21,35,17,51,1,71,254,255,1,1,174,174,135,3,117,68,253,19,0,0,0,1,0,35,255,171,1,250,2,188,0,3,0,61,184,0,2,47,184,0,0,220,65,5,0,112,0,0,0,128,0,0,0,2,93,185,0,1,0,4,244,184,0,2,16,185,0,3,0,4,244,0,184,0,1,47,184,0,0,69,88,184,0,3,47,27,185,0,3,0,14,62,89,48,49,5,35,1,51,1,250,93,254,134,93,85,3,17,0,1,0,0,255,121,1,1,2,238,0,7,0,82,184,0,2,47,65,3,0,208,0,2,0,1,93,65,3,0,16,0,2,0,1,93,184,0,4,220,184,0,2,16,184,0,5,220,184,0,4,16,184,0,7,208,0,184,0,3,47,184,0,0,69,88,184,0,0,47,27,185,0,0,0,18,62,89,184,0,3,16,184,0,4,220,184,0,0,16,184,0,7,220,48,49,17,33,17,33,53,51,17,35,1,1,254,255,174,174,2,238,252,139,68,2,237,0,0,0,0,1,0,49,1,181,1,205,2,247,0,5,0,95,25,184,0,4,47,24,184,0,1,208,184,0,4,16,184,0,3,208,184,0,3,47,184,0,4,16,184,0,5,208,184,0,5,47,0,184,0,4,47,184,0,2,220,184,0,0,208,184,0,4,16,184,0,1,208,65,7,0,107,0,1,0,123,0,1,0,139,0,1,0,3,93,184,0,2,16,184,0,3,208,65,3,0,181,0,3,0,1,93,184,0,5,208,48,49,1,39,7,53,55,23,1,205,206,206,206,206,1,181,216,216,106,216,216,0,1,0,3,255,134,2,51,255,220,0,3,0,64,184,0,4,47,184,0,5,47,184,0,4,16,184,0,2,208,184,0,2,47,184,0,5,16,184,0,3,208,184,0,3,47,0,184,0,4,47,184,0,2,220,184,0,1,220,65,7,0,79,0,1,0,95,0,1,0,111,0,1,0,3,113,48,49,5,33,53,33,2,51,253,208,2,48,122,86,0,0,0,1,0,58,2,84,0,245,2,220,0,3,0,126,184,0,1,47,65,7,0,0,0,1,0,16,0,1,0,32,0,1,0,3,93,65,5,0,16,0,1,0,32,0,1,0,2,113,184,0,3,220,0,184,0,0,47,65,3,0,16,0,0,0,1,113,65,3,0,64,0,0,0,1,93,65,3,0,32,0,0,0,1,93,184,0,2,220,65,5,0,15,0,2,0,31,0,2,0,2,93,184,0,1,220,184,0,0,16,184,0,3,220,65,11,0,86,0,3,0,102,0,3,0,118,0,3,0,134,0,3,0,150,0,3,0,5,93,48,49,19,39,53,23,245,187,187,2,84,64,72,95,0,2,0,24,255,246,1,216,1,244,0,34,0,43,2,22,186,0,30,0,12,0,3,43,65,3,0,160,0,30,0,1,93,65,3,0,159,0,30,0,1,93,65,3,0,127,0,30,0,1,93,65,3,0,48,0,30,0,1,113,65,3,0,192,0,30,0,1,93,65,3,0,16,0,30,0,1,113,184,0,30,16,184,0,0,208,184,0,0,47,65,3,0,0,0,0,0,1,93,184,0,30,16,185,0,36,0,4,244,186,0,7,0,36,0,30,17,18,57,65,9,0,111,0,12,0,127,0,12,0,143,0,12,0,159,0,12,0,4,93,65,3,0,15,0,12,0,1,113,65,3,0,63,0,12,0,1,93,65,3,0,31,0,12,0,1,93,65,3,0,191,0,12,0,1,93,65,3,0,192,0,12,0,1,93,65,3,0,160,0,12,0,1,93,184,0,17,208,186,0,23,0,12,0,30,17,18,57,184,0,23,47,184,0,12,16,185,0,39,0,4,244,0,184,0,0,69,88,184,0,25,47,27,185,0,25,0,12,62,89,184,0,0,69,88,184,0,1,47,27,185,0,1,0,6,62,89,184,0,0,69,88,184,0,9,47,27,185,0,9,0,6,62,89,186,0,17,0,25,0,9,17,18,57,184,0,17,47,186,0,7,0,17,0,9,17,18,57,184,0,25,16,185,0,20,0,2,244,184,0,25,16,184,0,22,220,65,3,0,79,0,22,0,1,93,184,0,1,16,185,0,34,0,1,244,184,0,17,16,185,0,36,0,1,244,184,0,9,16,185,0,41,0,1,244,48,49,1,65,3,0,56,0,10,0,1,93,65,3,0,25,0,10,0,1,93,65,3,0,41,0,11,0,1,93,65,3,0,26,0,11,0,1,93,65,3,0,24,0,14,0,1,93,65,3,0,136,0,14,0,1,93,65,5,0,120,0,24,0,136,0,24,0,2,93,65,7,0,7,0,27,0,23,0,27,0,39,0,27,0,3,93,65,3,0,6,0,28,0,1,93,0,65,3,0,56,0,10,0,1,93,65,3,0,25,0,10,0,1,93,65,3,0,42,0,10,0,1,93,65,3,0,118,0,14,0,1,93,65,3,0,135,0,14,0,1,93,65,3,0,117,0,24,0,1,93,65,5,0,86,0,24,0,102,0,24,0,2,93,65,3,0,135,0,24,0,1,93,65,5,0,6,0,27,0,22,0,27,0,2,93,65,3,0,39,0,27,0,1,93,37,7,35,34,46,2,39,6,35,34,38,53,52,62,2,55,52,38,35,34,7,39,54,51,50,30,2,29,1,20,22,51,39,53,14,1,21,20,51,50,54,1,216,14,7,30,40,28,19,9,62,88,69,82,55,85,104,49,51,56,64,65,13,66,100,47,66,41,19,20,36,146,108,93,76,36,67,62,72,7,17,28,20,72,79,63,51,66,40,17,1,66,47,44,73,51,25,55,90,65,100,58,45,66,117,4,49,55,75,36,0,2,0,60,255,246,2,11,2,238,0,21,0,41,1,57,186,0,17,0,7,0,3,43,65,3,0,15,0,7,0,1,113,65,3,0,31,0,7,0,1,93,65,3,0,47,0,7,0,1,113,65,3,0,0,0,7,0,1,93,65,3,0,32,0,7,0,1,93,184,0,7,16,185,0,10,0,4,244,184,0,5,208,65,3,0,0,0,17,0,1,93,65,7,0,32,0,17,0,48,0,17,0,64,0,17,0,3,93,65,3,0,96,0,17,0,1,93,65,3,0,16,0,17,0,1,113,184,0,10,16,184,0,27,208,184,0,17,16,185,0,37,0,4,244,0,184,0,0,69,88,184,0,12,47,27,185,0,12,0,12,62,89,184,0,0,69,88,184,0,9,47,27,185,0,9,0,18,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,184,0,0,69,88,184,0,6,47,27,185,0,6,0,6,62,89,186,0,5,0,0,0,12,17,18,57,186,0,10,0,12,0,0,17,18,57,184,0,12,16,185,0,22,0,2,244,184,0,0,16,185,0,32,0,2,244,48,49,1,65,3,0,87,0,11,0,1,93,65,3,0,102,0,20,0,1,93,65,3,0,87,0,20,0,1,93,0,65,5,0,85,0,11,0,101,0,11,0,2,93,65,3,0,86,0,14,0,1,93,65,3,0,103,0,14,0,1,93,65,5,0,89,0,20,0,105,0,20,0,2,93,5,34,46,2,39,7,35,17,51,17,54,51,50,30,2,21,20,14,2,3,34,14,2,21,20,30,2,51,50,62,2,53,52,46,2,1,45,18,42,42,37,12,10,80,90,52,100,49,82,58,32,34,60,81,57,29,53,40,24,23,40,53,30,32,52,36,20,20,37,52,10,10,18,27,17,62,2,238,254,199,63,41,70,93,51,53,93,69,40,1,174,23,45,65,42,43,66,44,22,28,48,64,35,37,64,47,27,0,1,0,33,255,246,1,171,1,244,0,25,1,133,186,0,12,0,5,0,3,43,65,3,0,143,0,5,0,1,93,65,3,0,31,0,5,0,1,93,65,9,0,63,0,5,0,79,0,5,0,95,0,5,0,111,0,5,0,4,93,65,3,0,32,0,5,0,1,93,65,3,0,176,0,12,0,1,93,65,3,0,0,0,12,0,1,113,65,3,0,32,0,12,0,1,113,65,3,0,208,0,12,0,1,93,65,3,0,32,0,12,0,1,93,65,3,0,0,0,12,0,1,93,184,0,5,16,185,0,18,0,4,244,184,0,12,16,184,0,24,208,0,184,0,0,69,88,184,0,10,47,27,185,0,10,0,12,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,184,0,10,16,184,0,13,220,184,0,10,16,185,0,15,0,2,244,184,0,0,16,185,0,21,0,2,244,184,0,0,16,184,0,23,220,48,49,1,65,5,0,90,0,2,0,106,0,2,0,2,93,65,5,0,89,0,8,0,105,0,8,0,2,93,65,3,0,104,0,11,0,1,93,65,3,0,104,0,24,0,1,93,65,3,0,104,0,25,0,1,93,0,65,3,0,89,0,2,0,1,93,65,3,0,106,0,2,0,1,93,65,3,0,84,0,8,0,1,93,65,3,0,101,0,8,0,1,93,65,3,0,132,0,11,0,1,93,65,5,0,85,0,11,0,101,0,11,0,2,93,65,3,0,84,0,12,0,1,93,65,3,0,116,0,12,0,1,93,65,3,0,101,0,12,0,1,93,65,3,0,133,0,12,0,1,93,65,7,0,90,0,24,0,106,0,24,0,122,0,24,0,3,93,65,3,0,140,0,24,0,1,93,65,5,0,89,0,25,0,105,0,25,0,2,93,5,34,46,2,53,52,62,2,51,50,23,7,38,35,34,6,21,20,22,51,50,55,23,6,1,21,59,90,63,32,32,61,91,59,98,53,14,62,65,81,80,80,81,66,62,12,55,10,39,69,93,55,56,93,68,37,29,81,30,90,84,84,93,30,72,37,0,0,0,0,2,0,32,255,246,1,239,2,238,0,21,0,41,1,39,186,0,21,0,12,0,3,43,65,3,0,143,0,21,0,1,93,65,7,0,0,0,21,0,16,0,21,0,32,0,21,0,3,113,184,0,21,16,185,0,20,0,4,244,184,0,2,208,65,3,0,31,0,12,0,1,93,65,5,0,63,0,12,0,79,0,12,0,2,93,65,3,0,111,0,12,0,1,93,65,3,0,143,0,12,0,1,93,184,0,12,16,185,0,27,0,4,244,184,0,20,16,184,0,37,208,0,184,0,0,69,88,184,0,21,47,27,185,0,21,0,18,62,89,184,0,0,69,88,184,0,17,47,27,185,0,17,0,12,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,184,0,0,69,88,184,0,7,47,27,185,0,7,0,6,62,89,186,0,2,0,7,0,17,17,18,57,186,0,19,0,17,0,7,17,18,57,184,0,17,16,185,0,22,0,2,244,184,0,7,16,185,0,32,0,2,244,48,49,1,65,3,0,88,0,9,0,1,93,65,3,0,105,0,9,0,1,93,65,3,0,104,0,15,0,1,93,0,65,5,0,88,0,9,0,104,0,9,0,2,93,65,3,0,103,0,15,0,1,93,65,3,0,85,0,16,0,1,93,65,3,0,101,0,18,0,1,93,65,3,0,86,0,18,0,1,93,33,35,39,14,3,35,34,46,2,53,52,62,2,51,50,23,17,51,3,34,14,2,21,20,30,2,51,50,62,2,53,52,46,2,1,239,80,10,12,37,41,42,18,47,82,60,34,32,59,82,50,99,51,90,233,32,51,36,19,19,35,51,33,30,55,43,25,26,43,55,62,17,26,19,10,40,69,93,53,51,93,70,41,62,1,56,254,182,26,46,64,39,36,64,47,28,21,43,65,43,42,66,46,24,0,0,2,0,31,255,246,1,226,1,244,0,24,0,30,2,2,186,0,23,0,13,0,3,43,65,3,0,175,0,13,0,1,93,65,3,0,79,0,13,0,1,93,65,3,0,47,0,13,0,1,113,65,3,0,143,0,13,0,1,93,65,3,0,111,0,13,0,1,93,184,0,13,16,185,0,1,0,4,244,65,3,0,80,0,23,0,1,93,65,3,0,144,0,23,0,1,93,65,3,0,208,0,23,0,1,93,65,3,0,16,0,23,0,1,113,65,3,0,48,0,23,0,1,113,65,3,0,240,0,23,0,1,93,65,3,0,176,0,23,0,1,93,65,3,0,112,0,23,0,1,93,65,3,0,16,0,23,0,1,93,65,3,0,80,0,23,0,1,113,186,0,6,0,23,0,13,17,18,57,184,0,6,47,184,0,23,16,185,0,28,0,4,244,186,0,27,0,1,0,28,17,18,57,0,184,0,0,69,88,184,0,18,47,27,185,0,18,0,12,62,89,184,0,0,69,88,184,0,8,47,27,185,0,8,0,6,62,89,186,0,1,0,18,0,8,17,18,57,184,0,1,47,65,5,0,144,0,1,0,160,0,1,0,2,93,65,5,0,16,0,1,0,32,0,1,0,2,93,65,5,0,80,0,1,0,96,0,1,0,2,113,184,0,8,16,185,0,3,0,2,244,184,0,8,16,184,0,5,220,184,0,18,16,185,0,25,0,2,244,184,0,1,16,184,0,27,220,65,3,0,255,0,27,0,1,113,65,15,0,159,0,27,0,175,0,27,0,191,0,27,0,207,0,27,0,223,0,27,0,239,0,27,0,255,0,27,0,7,93,48,49,1,65,3,0,69,0,2,0,1,93,65,3,0,54,0,2,0,1,93,65,3,0,135,0,6,0,1,93,65,3,0,103,0,7,0,1,93,65,3,0,120,0,7,0,1,93,65,3,0,88,0,10,0,1,93,65,3,0,135,0,20,0,1,93,65,3,0,132,0,21,0,1,93,65,3,0,6,0,21,0,1,93,0,65,3,0,54,0,2,0,1,93,65,3,0,71,0,2,0,1,93,65,3,0,137,0,6,0,1,93,65,5,0,105,0,7,0,121,0,7,0,2,93,65,3,0,90,0,7,0,1,93,65,3,0,89,0,10,0,1,93,65,3,0,134,0,20,0,1,93,65,3,0,135,0,21,0,1,93,37,33,22,51,50,55,23,6,35,34,46,2,53,52,62,2,51,50,30,2,21,20,39,34,7,33,52,38,1,222,254,157,16,168,75,66,12,87,77,62,99,68,36,34,62,89,55,47,78,55,31,213,109,29,1,2,60,245,175,29,71,38,40,69,95,55,53,92,67,39,28,54,77,48,28,155,113,54,59,0,0,0,0,1,0,10,0,0,1,61,2,238,0,23,0,236,186,0,13,0,4,0,3,43,65,3,0,143,0,4,0,1,93,65,3,0,47,0,4,0,1,113,184,0,4,16,185,0,1,0,4,244,184,0,4,16,184,0,5,208,184,0,5,47,184,0,4,16,184,0,7,208,65,3,0,47,0,13,0,1,113,184,0,1,16,184,0,22,208,184,0,13,16,184,0,23,208,184,0,23,47,0,184,0,0,69,88,184,0,11,47,27,185,0,11,0,18,62,89,184,0,0,69,88,184,0,22,47,27,185,0,22,0,12,62,89,184,0,0,69,88,184,0,3,47,27,185,0,3,0,6,62,89,184,0,22,16,185,0,1,0,1,244,184,0,4,208,184,0,22,16,184,0,7,208,184,0,11,16,185,0,16,0,2,244,48,49,1,65,9,0,73,0,9,0,89,0,9,0,105,0,9,0,121,0,9,0,4,93,65,9,0,10,0,9,0,26,0,9,0,42,0,9,0,58,0,9,0,4,93,0,65,9,0,5,0,10,0,21,0,10,0,37,0,10,0,53,0,10,0,4,93,1,35,17,35,17,35,55,51,53,52,54,51,50,23,7,38,35,34,14,2,29,1,51,1,61,132,90,85,12,73,59,55,64,38,14,29,31,17,20,11,4,132,1,164,254,92,1,164,70,124,61,75,13,76,9,7,25,48,40,60,0,0,0,3,0,26,255,6,1,245,1,244,0,53,0,65,0,78,3,224,186,0,30,0,14,0,3,43,65,3,0,95,0,14,0,1,93,65,3,0,32,0,14,0,1,93,65,3,0,160,0,14,0,1,93,184,0,14,16,184,0,5,208,184,0,5,47,184,0,14,16,184,0,9,208,184,0,9,47,65,3,0,0,0,30,0,1,93,65,3,0,96,0,30,0,1,93,65,3,0,160,0,30,0,1,93,65,3,0,128,0,30,0,1,93,65,3,0,32,0,30,0,1,93,65,3,0,192,0,30,0,1,93,65,3,0,16,0,30,0,1,113,186,0,12,0,14,0,30,17,18,57,186,0,21,0,14,0,30,17,18,57,184,0,30,16,184,0,24,208,184,0,24,47,186,0,28,0,30,0,14,17,18,57,186,0,37,0,30,0,14,17,18,57,184,0,9,16,185,0,39,0,4,244,184,0,30,16,184,0,49,208,184,0,49,47,184,0,14,16,185,0,57,0,4,244,184,0,30,16,185,0,63,0,4,244,184,0,5,16,185,0,71,0,4,244,184,0,49,16,185,0,77,0,4,244,65,3,0,79,0,80,0,1,93,0,184,0,0,69,88,184,0,19,47,27,185,0,19,0,12,62,89,184,0,0,69,88,184,0,24,47,27,185,0,24,0,12,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,8,62,89,65,3,0,0,0,0,0,1,93,186,0,44,0,19,0,0,17,18,57,65,5,0,58,0,44,0,74,0,44,0,2,93,65,3,0,101,0,44,0,1,93,184,0,44,16,185,0,66,0,1,244,186,0,7,0,44,0,66,17,18,57,184,0,19,16,184,0,35,220,65,3,0,111,0,35,0,1,93,65,5,0,63,0,35,0,79,0,35,0,2,93,65,3,0,143,0,35,0,1,93,65,3,0,15,0,35,0,1,113,186,0,12,0,35,0,19,17,18,57,186,0,21,0,19,0,35,17,18,57,184,0,24,16,185,0,25,0,1,244,186,0,28,0,19,0,35,17,18,57,186,0,37,0,35,0,19,17,18,57,184,0,19,16,185,0,54,0,1,244,184,0,35,16,185,0,60,0,1,244,186,0,68,0,66,0,44,17,18,57,184,0,0,16,185,0,74,0,1,244,48,49,1,65,3,0,9,0,3,0,1,93,65,5,0,122,0,8,0,138,0,8,0,2,93,65,3,0,121,0,12,0,1,93,65,3,0,120,0,13,0,1,93,65,3,0,138,0,13,0,1,93,65,3,0,9,0,16,0,1,93,65,3,0,123,0,16,0,1,93,65,3,0,140,0,16,0,1,93,65,3,0,136,0,17,0,1,93,65,3,0,121,0,17,0,1,93,65,3,0,117,0,21,0,1,93,65,3,0,134,0,21,0,1,93,65,3,0,117,0,28,0,1,93,65,3,0,134,0,28,0,1,93,65,3,0,117,0,32,0,1,93,65,3,0,134,0,32,0,1,93,65,3,0,134,0,33,0,1,93,65,3,0,7,0,33,0,1,93,65,3,0,119,0,33,0,1,93,65,3,0,134,0,47,0,1,93,65,5,0,23,0,47,0,39,0,47,0,2,93,65,3,0,119,0,47,0,1,93,65,5,0,118,0,51,0,134,0,51,0,2,93,65,3,0,6,0,52,0,1,93,65,3,0,135,0,52,0,1,93,65,3,0,119,0,69,0,1,93,0,65,3,0,8,0,3,0,1,93,65,3,0,120,0,8,0,1,93,65,3,0,120,0,12,0,1,93,65,3,0,120,0,13,0,1,93,65,3,0,6,0,16,0,1,93,65,3,0,119,0,16,0,1,93,65,3,0,133,0,17,0,1,93,65,3,0,119,0,17,0,1,93,65,3,0,134,0,21,0,1,93,65,3,0,119,0,21,0,1,93,65,5,0,118,0,28,0,134,0,28,0,2,93,65,3,0,137,0,32,0,1,93,65,3,0,122,0,32,0,1,93,65,3,0,9,0,33,0,1,93,65,3,0,121,0,33,0,1,93,65,3,0,138,0,33,0,1,93,65,3,0,102,0,42,0,1,93,65,3,0,134,0,47,0,1,93,65,5,0,23,0,47,0,39,0,47,0,2,93,65,3,0,119,0,47,0,1,93,65,5,0,122,0,51,0,138,0,51,0,2,93,65,3,0,9,0,52,0,1,93,65,3,0,121,0,52,0,1,93,65,3,0,138,0,52,0,1,93,65,3,0,121,0,69,0,1,93,65,3,0,138,0,69,0,1,93,23,34,46,2,53,52,55,38,53,52,54,55,38,53,52,62,2,51,50,23,54,59,1,7,35,34,7,22,21,20,14,2,35,34,39,6,21,20,30,2,23,30,3,23,20,14,2,3,34,6,21,20,22,51,50,54,53,52,38,3,34,39,14,1,21,20,22,51,50,54,53,52,255,58,86,57,28,87,50,27,31,85,27,51,75,47,66,59,52,67,8,11,23,31,27,45,28,51,73,46,39,31,24,11,33,59,49,33,70,57,38,2,34,63,92,75,55,60,65,52,54,62,64,12,17,72,34,44,78,69,72,79,250,24,41,54,29,78,32,24,38,17,41,15,61,99,42,72,53,30,36,28,60,7,54,63,39,70,54,32,9,14,16,9,13,10,11,9,6,18,30,47,35,31,56,42,25,2,166,67,55,57,67,72,55,57,62,254,58,12,10,50,26,35,45,47,31,52,0,1,0,60,0,0,1,230,2,238,0,16,1,44,186,0,0,0,9,0,3,43,65,3,0,223,0,0,0,1,93,65,3,0,32,0,0,0,1,93,65,3,0,64,0,0,0,1,93,184,0,0,16,185,0,1,0,4,244,65,3,0,223,0,9,0,1,93,65,3,0,15,0,9,0,1,113,65,3,0,47,0,9,0,1,113,65,3,0,32,0,9,0,1,93,184,0,9,16,185,0,8,0,4,244,184,0,12,208,65,3,0,128,0,17,0,1,93,65,3,0,239,0,18,0,1,93,65,3,0,31,0,18,0,1,93,65,3,0,207,0,18,0,1,93,65,3,0,175,0,18,0,1,93,0,184,0,0,69,88,184,0,11,47,27,185,0,11,0,18,62,89,184,0,0,69,88,184,0,14,47,27,185,0,14,0,12,62,89,184,0,0,69,88,184,0,8,47,27,185,0,8,0,6,62,89,184,0,1,208,184,0,14,16,185,0,5,0,2,244,65,3,0,6,0,9,0,1,113,186,0,12,0,14,0,8,17,18,57,48,49,1,65,7,0,118,0,15,0,134,0,15,0,150,0,15,0,3,93,65,3,0,7,0,15,0,1,93,0,65,3,0,150,0,4,0,1,93,65,3,0,118,0,15,0,1,93,65,3,0,150,0,15,0,1,93,65,3,0,7,0,15,0,1,93,65,3,0,135,0,15,0,1,93,33,35,17,52,38,35,34,7,17,35,17,51,17,54,51,50,21,1,230,90,52,65,88,40,91,91,49,93,193,1,6,87,71,64,254,156,2,238,254,199,63,238,0,2,0,61,0,0,0,151,2,188,0,3,0,7,0,165,187,0,7,0,4,0,6,0,4,43,65,3,0,143,0,7,0,1,93,65,3,0,223,0,7,0,1,93,65,3,0,63,0,7,0,1,113,65,3,0,32,0,7,0,1,93,184,0,7,16,184,0,0,208,65,3,0,223,0,6,0,1,93,65,3,0,63,0,6,0,1,113,65,3,0,143,0,6,0,1,93,65,3,0,32,0,6,0,1,93,184,0,6,16,184,0,1,208,0,184,0,1,47,184,0,0,69,88,184,0,6,47,27,185,0,6,0,12,62,89,184,0,0,69,88,184,0,5,47,27,185,0,5,0,6,62,89,65,3,0,32,0,1,0,1,93,65,3,0,64,0,1,0,1,93,184,0,1,16,184,0,2,220,48,49,19,35,53,51,17,35,17,51,151,90,90,90,90,2,88,100,253,68,1,234,0,0,0,0,2,255,244,255,14,0,151,2,188,0,14,0,18,0,209,187,0,9,0,4,0,8,0,4,43,65,3,0,63,0,8,0,1,113,65,3,0,143,0,8,0,1,93,65,3,0,223,0,8,0,1,93,65,3,0,32,0,8,0,1,93,184,0,8,16,184,0,2,208,184,0,2,47,65,3,0,143,0,9,0,1,93,65,3,0,223,0,9,0,1,93,65,3,0,63,0,9,0,1,113,65,3,0,32,0,9,0,1,93,184,0,9,16,184,0,15,208,184,0,8,16,184,0,16,208,0,184,0,16,47,184,0,0,69,88,184,0,8,47,27,185,0,8,0,12,62,89,184,0,0,69,88,184,0,1,47,27,185,0,1,0,8,62,89,185,0,2,0,1,244,65,3,0,64,0,16,0,1,93,65,3,0,32,0,16,0,1,93,184,0,16,16,184,0,17,220,48,49,1,65,11,0,5,0,12,0,21,0,12,0,37,0,12,0,53,0,12,0,69,0,12,0,5,93,23,7,39,62,3,53,17,51,17,20,14,2,19,35,53,51,28,30,10,22,28,16,7,90,20,33,45,98,90,90,237,5,69,2,10,21,37,30,2,51,253,171,32,45,31,18,3,65,100,0,0,0,1,0,60,0,0,1,189,2,238,0,10,1,129,186,0,8,0,1,0,3,43,65,3,0,15,0,1,0,1,113,65,3,0,143,0,1,0,1,93,65,3,0,0,0,1,0,1,93,65,3,0,32,0,1,0,1,93,184,0,1,16,185,0,0,0,4,244,184,0,4,208,65,3,0,51,0,8,0,1,93,65,3,0,37,0,8,0,1,93,65,3,0,73,0,8,0,1,93,65,3,0,138,0,8,0,1,93,65,3,0,90,0,8,0,1,93,65,3,0,121,0,8,0,1,93,65,3,0,19,0,8,0,1,93,65,3,0,99,0,8,0,1,93,65,3,0,0,0,8,0,1,93,184,0,8,16,184,0,9,208,65,5,0,73,0,9,0,89,0,9,0,2,93,65,3,0,106,0,9,0,1,93,65,5,0,123,0,9,0,139,0,9,0,2,93,65,3,0,41,0,9,0,1,113,65,7,0,166,0,9,0,182,0,9,0,198,0,9,0,3,93,65,3,0,149,0,9,0,1,93,184,0,5,208,65,3,0,134,0,5,0,1,93,184,0,8,16,184,0,6,208,65,3,0,134,0,6,0,1,93,184,0,4,16,184,0,7,208,65,3,0,38,0,7,0,1,113,65,7,0,101,0,7,0,117,0,7,0,133,0,7,0,3,93,65,3,0,63,0,12,0,1,93,65,3,0,31,0,12,0,1,93,0,184,0,0,69,88,184,0,3,47,27,185,0,3,0,18,62,89,184,0,0,69,88,184,0,5,47,27,185,0,5,0,12,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,184,0,9,208,186,0,7,0,5,0,9,17,18,57,25,184,0,7,47,24,184,0,4,208,184,0,7,16,184,0,10,208,48,49,51,35,17,51,17,55,51,7,19,35,39,150,90,90,180,110,202,207,110,185,2,238,254,31,221,226,254,248,249,0,1,0,60,255,246,0,229,2,238,0,12,0,111,186,0,0,0,5,0,3,43,65,3,0,255,0,0,0,1,93,65,3,0,32,0,0,0,1,93,65,3,0,47,0,5,0,1,113,65,3,0,255,0,5,0,1,93,65,3,0,32,0,5,0,1,93,184,0,5,16,185,0,8,0,4,244,65,3,0,16,0,13,0,1,93,65,3,0,175,0,14,0,1,93,0,184,0,7,47,184,0,0,69,88,184,0,2,47,27,185,0,2,0,6,62,89,185,0,0,0,1,244,48,49,55,7,35,34,38,53,17,51,17,20,30,2,229,13,29,66,61,90,5,16,31,62,72,67,51,2,130,253,178,31,39,21,7,0,0,0,1,0,61,0,0,3,53,1,244,0,29,2,14,186,0,9,0,17,0,3,43,65,3,0,0,0,9,0,1,93,65,3,0,255,0,9,0,1,93,65,3,0,32,0,9,0,1,93,65,3,0,64,0,9,0,1,113,184,0,9,16,184,0,1,220,65,3,0,64,0,1,0,1,113,185,0,0,0,4,244,184,0,9,16,185,0,8,0,4,244,65,3,0,255,0,17,0,1,93,65,3,0,32,0,17,0,1,93,65,3,0,0,0,17,0,1,93,184,0,17,16,185,0,16,0,4,244,186,0,20,0,16,0,17,17,18,57,186,0,25,0,8,0,9,17,18,57,65,3,0,95,0,31,0,1,93,0,184,0,0,69,88,184,0,23,47,27,185,0,23,0,12,62,89,184,0,0,69,88,184,0,27,47,27,185,0,27,0,12,62,89,184,0,0,69,88,184,0,19,47,27,185,0,19,0,12,62,89,184,0,0,69,88,184,0,16,47,27,185,0,16,0,6,62,89,184,0,9,208,184,0,1,208,184,0,27,16,185,0,5,0,2,244,184,0,23,16,185,0,13,0,2,244,186,0,20,0,23,0,16,17,18,57,186,0,25,0,27,0,9,17,18,57,48,49,1,65,3,0,168,0,11,0,1,93,65,3,0,154,0,12,0,1,93,65,3,0,123,0,12,0,1,93,65,3,0,87,0,14,0,1,93,65,5,0,88,0,21,0,104,0,21,0,2,93,65,5,0,120,0,25,0,136,0,25,0,2,93,65,3,0,88,0,26,0,1,93,65,3,0,165,0,28,0,1,93,65,3,0,134,0,28,0,1,93,65,5,0,7,0,28,0,23,0,28,0,2,93,65,3,0,151,0,28,0,1,93,0,65,3,0,171,0,11,0,1,93,65,3,0,119,0,12,0,1,93,65,7,0,86,0,14,0,102,0,14,0,118,0,14,0,3,93,65,3,0,85,0,21,0,1,93,65,3,0,102,0,21,0,1,93,65,3,0,119,0,21,0,1,93,65,3,0,164,0,25,0,1,93,65,5,0,133,0,25,0,149,0,25,0,2,93,65,3,0,118,0,25,0,1,93,65,3,0,86,0,26,0,1,93,65,3,0,103,0,26,0,1,93,65,3,0,133,0,28,0,1,93,65,3,0,6,0,28,0,1,93,65,5,0,150,0,28,0,166,0,28,0,2,93,65,3,0,23,0,28,0,1,93,33,35,17,52,38,35,34,21,17,35,17,52,38,35,34,7,17,35,17,51,23,62,1,51,50,23,54,51,50,21,3,53,90,54,61,130,90,59,56,94,36,90,70,10,40,66,41,112,54,51,128,188,1,32,69,63,136,254,228,1,14,84,66,64,254,156,1,234,52,36,26,98,98,211,0,0,0,1,0,61,0,0,1,247,1,244,0,16,1,95,186,0,0,0,9,0,3,43,65,3,0,96,0,0,0,1,93,65,3,0,32,0,0,0,1,113,65,3,0,0,0,0,0,1,93,65,3,0,64,0,0,0,1,113,65,3,0,0,0,0,0,1,113,65,3,0,64,0,0,0,1,93,65,3,0,32,0,0,0,1,93,184,0,0,16,185,0,1,0,4,244,65,3,0,143,0,9,0,1,93,65,3,0,255,0,9,0,1,93,65,3,0,223,0,9,0,1,93,65,3,0,0,0,9,0,1,93,65,3,0,32,0,9,0,1,93,184,0,9,16,185,0,8,0,4,244,184,0,12,208,0,184,0,0,69,88,184,0,14,47,27,185,0,14,0,12,62,89,184,0,0,69,88,184,0,11,47,27,185,0,11,0,12,62,89,184,0,0,69,88,184,0,8,47,27,185,0,8,0,6,62,89,184,0,1,208,184,0,14,16,185,0,5,0,2,244,186,0,7,0,8,0,5,17,18,57,186,0,12,0,14,0,8,17,18,57,48,49,1,65,3,0,117,0,15,0,1,93,65,5,0,6,0,15,0,22,0,15,0,2,93,65,3,0,150,0,15,0,1,93,65,3,0,135,0,15,0,1,93,65,3,0,167,0,15,0,1,93,0,65,3,0,91,0,3,0,1,113,65,3,0,84,0,6,0,1,93,65,3,0,84,0,13,0,1,93,65,3,0,22,0,15,0,1,93,65,3,0,134,0,15,0,1,93,65,3,0,7,0,15,0,1,93,65,3,0,119,0,15,0,1,93,65,3,0,151,0,15,0,1,93,33,35,17,52,38,35,34,7,17,35,17,51,23,54,51,50,21,1,247,90,59,69,98,36,90,70,10,70,92,200,1,14,79,71,64,254,156,1,234,52,62,230,0,0,2,0,32,255,246,2,6,1,244,0,18,0,31,1,107,186,0,17,0,7,0,3,43,65,3,0,31,0,7,0,1,93,65,3,0,95,0,7,0,1,93,65,3,0,159,0,7,0,1,93,65,3,0,47,0,7,0,1,113,65,3,0,127,0,7,0,1,93,65,3,0,63,0,7,0,1,93,65,3,0,32,0,7,0,1,93,65,3,0,160,0,7,0,1,93,65,5,0,160,0,17,0,176,0,17,0,2,93,65,3,0,240,0,17,0,1,93,65,3,0,48,0,17,0,1,113,65,3,0,32,0,17,0,1,93,65,3,0,16,0,17,0,1,113,65,3,0,208,0,17,0,1,93,65,3,0,96,0,17,0,1,93,65,3,0,64,0,17,0,1,93,184,0,7,16,185,0,24,0,4,244,184,0,17,16,185,0,30,0,4,244,0,184,0,0,69,88,184,0,12,47,27,185,0,12,0,12,62,89,184,0,0,69,88,184,0,2,47,27,185,0,2,0,6,62,89,184,0,12,16,185,0,21,0,2,244,184,0,2,16,185,0,27,0,2,244,48,49,1,65,3,0,101,0,0,0,1,93,65,3,0,86,0,0,0,1,93,65,5,0,88,0,4,0,104,0,4,0,2,93,65,3,0,89,0,5,0,1,93,65,5,0,89,0,10,0,105,0,10,0,2,93,65,5,0,86,0,14,0,102,0,14,0,2,93,0,65,5,0,89,0,0,0,105,0,0,0,2,93,65,3,0,88,0,4,0,1,93,65,3,0,105,0,4,0,1,93,65,5,0,87,0,10,0,103,0,10,0,2,93,65,3,0,86,0,14,0,1,93,65,3,0,103,0,14,0,1,93,37,6,35,34,46,2,53,52,62,2,51,50,30,2,21,20,39,38,35,34,6,21,20,22,51,50,54,53,52,1,196,65,112,57,90,63,33,34,63,90,56,56,90,63,34,132,39,72,72,79,79,72,73,78,62,72,39,68,94,54,55,93,68,39,39,69,93,54,110,239,46,91,84,84,91,94,81,83,0,0,0,0,2,0,61,255,14,2,12,1,244,0,22,0,42,1,129,186,0,18,0,7,0,3,43,65,3,0,15,0,7,0,1,113,65,3,0,31,0,7,0,1,93,65,3,0,47,0,7,0,1,113,65,3,0,0,0,7,0,1,93,65,3,0,32,0,7,0,1,93,184,0,7,16,185,0,6,0,4,244,184,0,10,208,65,3,0,0,0,18,0,1,93,65,7,0,32,0,18,0,48,0,18,0,64,0,18,0,3,93,65,3,0,96,0,18,0,1,93,65,3,0,16,0,18,0,1,113,184,0,6,16,184,0,28,208,184,0,18,16,185,0,38,0,4,244,0,184,0,0,69,88,184,0,9,47,27,185,0,9,0,12,62,89,184,0,0,69,88,184,0,13,47,27,185,0,13,0,12,62,89,184,0,0,69,88,184,0,6,47,27,185,0,6,0,8,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,186,0,5,0,0,0,13,17,18,57,65,3,0,34,0,7,0,1,113,186,0,10,0,13,0,0,17,18,57,184,0,13,16,185,0,23,0,2,244,184,0,0,16,185,0,33,0,2,244,48,49,1,65,3,0,104,0,11,0,1,93,65,3,0,91,0,11,0,1,93,65,3,0,86,0,15,0,1,93,65,3,0,103,0,15,0,1,93,65,5,0,86,0,20,0,102,0,20,0,2,93,65,3,0,102,0,21,0,1,93,65,3,0,87,0,21,0,1,93,0,65,3,0,85,0,11,0,1,93,65,3,0,103,0,11,0,1,93,65,5,0,87,0,15,0,103,0,15,0,2,93,65,3,0,104,0,20,0,1,93,65,3,0,89,0,20,0,1,93,65,3,0,89,0,21,0,1,93,65,3,0,106,0,21,0,1,93,5,34,46,2,39,17,35,17,51,23,62,1,51,50,30,2,21,20,14,2,3,34,14,2,21,20,30,2,51,50,62,2,53,52,46,2,1,49,18,43,42,38,13,90,70,10,34,74,57,50,80,57,31,29,55,82,63,29,54,41,25,24,41,54,30,31,51,36,19,19,36,51,10,10,18,27,17,254,208,2,220,70,41,39,41,71,92,51,55,94,68,38,1,174,24,45,65,41,44,65,44,22,27,46,64,38,39,64,46,26,0,0,2,0,33,255,14,1,240,1,244,0,22,0,42,1,65,186,0,16,0,5,0,3,43,65,3,0,31,0,5,0,1,93,65,3,0,111,0,5,0,1,93,65,5,0,63,0,5,0,79,0,5,0,2,93,65,7,0,0,0,16,0,16,0,16,0,32,0,16,0,3,113,184,0,16,16,185,0,17,0,4,244,184,0,13,208,184,0,5,16,185,0,28,0,4,244,184,0,17,16,184,0,38,208,0,184,0,0,69,88,184,0,10,47,27,185,0,10,0,12,62,89,184,0,0,69,88,184,0,15,47,27,185,0,15,0,12,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,184,0,0,69,88,184,0,16,47,27,185,0,16,0,8,62,89,65,3,0,69,0,5,0,1,93,186,0,13,0,10,0,0,17,18,57,65,3,0,47,0,16,0,1,113,186,0,18,0,0,0,10,17,18,57,184,0,10,16,185,0,23,0,2,244,184,0,0,16,185,0,33,0,2,244,48,49,1,65,3,0,90,0,2,0,1,93,65,3,0,107,0,2,0,1,93,65,3,0,90,0,3,0,1,93,65,5,0,88,0,8,0,104,0,8,0,2,93,65,3,0,85,0,12,0,1,93,65,3,0,103,0,12,0,1,93,0,65,5,0,89,0,2,0,105,0,2,0,2,93,65,5,0,86,0,8,0,102,0,8,0,2,93,65,3,0,102,0,12,0,1,93,65,3,0,87,0,12,0,1,93,23,34,46,2,53,52,62,2,51,50,22,23,55,51,17,35,17,14,3,3,34,14,2,21,20,30,2,51,50,62,2,53,52,46,2,252,53,82,56,28,31,57,80,50,57,74,34,10,70,90,12,38,42,43,9,32,50,36,19,19,36,50,32,30,55,40,24,25,41,54,10,38,68,94,55,52,92,70,41,39,41,70,253,36,1,48,16,27,19,10,1,174,26,46,64,39,38,64,46,27,23,44,66,42,41,65,45,24,0,0,0,0,1,0,61,0,0,1,64,1,252,0,15,0,166,186,0,0,0,9,0,3,43,65,3,0,0,0,0,0,1,93,65,3,0,32,0,0,0,1,93,65,3,0,31,0,9,0,1,93,65,3,0,0,0,9,0,1,93,65,3,0,32,0,9,0,1,93,184,0,9,16,185,0,8,0,4,244,184,0,12,208,0,184,0,0,69,88,184,0,10,47,27,185,0,10,0,12,62,89,184,0,0,69,88,184,0,9,47,27,185,0,9,0,6,62,89,184,0,10,16,184,0,0,208,184,0,0,47,184,0,1,220,65,5,0,127,0,1,0,143,0,1,0,2,93,65,5,0,31,0,1,0,47,0,1,0,2,113,186,0,7,0,9,0,1,17,18,57,186,0,12,0,0,0,9,17,18,57,48,49,1,7,35,34,14,2,7,17,35,17,51,23,62,1,51,1,64,20,31,15,34,31,26,6,96,74,11,46,75,45,1,252,99,11,18,22,12,254,166,1,234,81,52,47,0,1,0,32,255,246,1,131,1,244,0,39,2,81,186,0,35,0,15,0,3,43,65,3,0,127,0,15,0,1,93,184,0,15,16,184,0,2,208,184,0,2,47,65,3,0,208,0,35,0,1,93,65,3,0,0,0,35,0,1,113,65,3,0,160,0,35,0,1,93,65,3,0,128,0,35,0,1,93,184,0,35,16,185,0,8,0,4,244,186,0,20,0,35,0,15,17,18,57,184,0,20,47,184,0,15,16,185,0,25,0,4,244,65,3,0,31,0,41,0,1,93,65,3,0,79,0,41,0,1,93,0,184,0,0,69,88,184,0,18,47,27,185,0,18,0,12,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,184,0,3,220,65,5,0,48,0,3,0,64,0,3,0,2,93,184,0,0,16,185,0,6,0,2,244,186,0,10,0,0,0,18,17,18,57,65,3,0,121,0,10,0,1,93,65,3,0,10,0,10,0,1,93,65,3,0,138,0,10,0,1,93,65,5,0,166,0,10,0,182,0,10,0,2,93,65,3,0,149,0,10,0,1,93,184,0,18,16,184,0,21,220,65,5,0,176,0,21,0,192,0,21,0,2,93,184,0,18,16,185,0,23,0,1,244,186,0,29,0,18,0,0,17,18,57,65,3,0,10,0,29,0,1,93,48,49,1,65,9,0,87,0,1,0,103,0,1,0,119,0,1,0,135,0,1,0,4,93,65,3,0,57,0,13,0,1,93,65,3,0,75,0,13,0,1,93,65,3,0,25,0,16,0,1,93,65,3,0,42,0,16,0,1,93,65,3,0,11,0,16,0,1,93,65,5,0,54,0,33,0,70,0,33,0,2,93,65,5,0,118,0,33,0,134,0,33,0,2,93,65,3,0,37,0,38,0,1,93,65,3,0,22,0,38,0,1,93,65,3,0,7,0,38,0,1,93,0,65,9,0,89,0,1,0,105,0,1,0,121,0,1,0,137,0,1,0,4,93,65,9,0,89,0,2,0,105,0,2,0,121,0,2,0,137,0,2,0,4,93,65,3,0,72,0,13,0,1,93,65,3,0,57,0,13,0,1,93,65,3,0,37,0,16,0,1,93,65,3,0,6,0,16,0,1,93,65,3,0,23,0,16,0,1,93,65,9,0,84,0,19,0,100,0,19,0,116,0,19,0,132,0,19,0,4,93,65,9,0,85,0,20,0,101,0,20,0,117,0,20,0,133,0,20,0,4,93,65,5,0,53,0,33,0,69,0,33,0,2,93,65,3,0,134,0,33,0,1,93,65,3,0,119,0,33,0,1,93,65,3,0,9,0,38,0,1,93,65,5,0,26,0,38,0,42,0,38,0,2,93,23,34,39,55,30,1,51,50,53,52,39,46,3,39,52,54,51,50,23,7,38,35,34,21,20,30,2,23,30,3,21,20,14,2,200,107,61,11,20,83,50,98,98,30,53,42,27,2,90,94,67,66,11,52,68,95,10,26,44,34,21,49,42,28,16,42,73,10,43,87,18,32,61,55,26,7,19,31,48,36,63,84,32,82,43,66,16,22,17,16,10,6,21,34,50,35,24,52,42,28,0,0,1,0,18,255,246,1,65,2,108,0,21,0,215,186,0,14,0,6,0,3,43,65,3,0,95,0,14,0,1,93,65,3,0,0,0,14,0,1,93,184,0,14,16,184,0,0,208,184,0,0,47,65,3,0,95,0,6,0,1,93,65,3,0,0,0,6,0,1,93,184,0,6,16,184,0,7,208,184,0,7,47,184,0,6,16,184,0,9,208,184,0,9,47,184,0,6,16,185,0,15,0,4,244,184,0,12,208,184,0,12,47,0,184,0,0,69,88,184,0,12,47,27,185,0,12,0,12,62,89,184,0,0,69,88,184,0,1,47,27,185,0,1,0,6,62,89,185,0,0,0,1,244,184,0,12,16,185,0,15,0,1,244,184,0,6,208,184,0,12,16,184,0,9,208,184,0,12,16,184,0,11,220,48,49,1,65,9,0,57,0,4,0,73,0,4,0,89,0,4,0,105,0,4,0,4,93,0,65,9,0,57,0,3,0,73,0,3,0,89,0,3,0,105,0,3,0,4,93,37,7,35,34,38,53,17,35,55,51,53,55,21,51,21,35,17,20,30,2,51,1,62,7,81,65,63,84,8,76,90,129,129,4,19,42,38,62,72,68,49,1,57,70,121,9,130,70,254,254,35,40,20,5,0,0,1,0,56,255,246,1,207,1,234,0,15,1,48,186,0,15,0,7,0,3,43,65,3,0,32,0,15,0,1,113,65,3,0,255,0,15,0,1,93,65,3,0,223,0,15,0,1,93,65,3,0,80,0,15,0,1,93,65,3,0,112,0,15,0,1,93,184,0,15,16,185,0,14,0,4,244,184,0,2,208,65,3,0,31,0,7,0,1,113,65,3,0,223,0,7,0,1,93,65,3,0,143,0,7,0,1,93,65,3,0,255,0,7,0,1,93,65,3,0,32,0,7,0,1,93,184,0,7,16,185,0,8,0,4,244,65,3,0,31,0,17,0,1,93,65,3,0,63,0,17,0,1,93,0,184,0,0,69,88,184,0,8,47,27,185,0,8,0,12,62,89,184,0,0,69,88,184,0,4,47,27,185,0,4,0,6,62,89,184,0,0,69,88,184,0,1,47,27,185,0,1,0,6,62,89,184,0,8,16,184,0,14,208,186,0,2,0,4,0,14,17,18,57,184,0,4,16,185,0,11,0,2,244,48,49,1,65,5,0,168,0,5,0,184,0,5,0,2,93,65,3,0,102,0,10,0,1,93,65,3,0,134,0,10,0,1,93,65,3,0,119,0,10,0,1,93,0,65,3,0,185,0,5,0,1,93,65,3,0,170,0,5,0,1,93,65,5,0,102,0,10,0,118,0,10,0,2,93,65,3,0,135,0,10,0,1,93,33,35,39,6,35,34,53,17,51,17,20,51,50,55,17,51,1,207,80,10,46,90,181,90,114,78,35,90,54,64,215,1,29,254,252,160,56,1,108,0,0,0,0,1,0,9,0,0,1,227,1,234,0,6,1,25,187,0,1,0,4,0,2,0,4,43,65,3,0,64,0,1,0,1,93,65,3,0,160,0,1,0,1,93,65,3,0,0,0,1,0,1,93,65,3,0,224,0,1,0,1,93,184,0,1,16,184,0,0,208,65,3,0,89,0,0,0,1,93,65,3,0,151,0,0,0,1,93,65,3,0,5,0,0,0,1,93,65,3,0,160,0,2,0,1,93,65,3,0,224,0,2,0,1,93,65,3,0,64,0,2,0,1,93,65,3,0,0,0,2,0,1,93,184,0,2,16,184,0,3,208,65,3,0,10,0,3,0,1,93,65,3,0,152,0,3,0,1,93,65,3,0,86,0,3,0,1,93,185,0,4,0,4,244,65,3,0,184,0,4,0,1,93,186,0,5,0,2,0,1,17,18,57,184,0,0,16,185,0,6,0,4,244,65,3,0,183,0,6,0,1,93,65,3,0,47,0,8,0,1,93,0,184,0,0,69,88,184,0,4,47,27,185,0,4,0,12,62,89,184,0,0,69,88,184,0,2,47,27,185,0,2,0,6,62,89,184,0,5,208,184,0,4,16,184,0,6,208,48,49,65,3,0,132,0,5,0,1,93,65,3,0,117,0,5,0,1,93,65,3,0,12,0,5,0,1,93,1,3,35,3,51,27,1,1,227,186,101,187,100,137,136,1,234,254,22,1,234,254,121,1,135,0,1,0,12,0,0,2,202,1,234,0,12,1,215,187,0,10,0,4,0,9,0,4,43,65,3,0,144,0,10,0,1,93,184,0,10,16,184,0,1,220,184,0,0,208,65,3,0,134,0,0,0,1,93,65,3,0,38,0,0,0,1,93,184,0,1,16,185,0,2,0,4,244,65,3,0,144,0,9,0,1,93,186,0,3,0,9,0,10,17,18,57,184,0,9,16,184,0,5,220,185,0,4,0,4,244,184,0,5,16,184,0,6,208,65,3,0,41,0,6,0,1,93,65,3,0,137,0,6,0,1,93,185,0,7,0,4,244,186,0,8,0,5,0,4,17,18,57,186,0,11,0,2,0,1,17,18,57,184,0,0,16,185,0,12,0,4,244,65,3,0,15,0,13,0,1,93,0,184,0,0,69,88,184,0,7,47,27,185,0,7,0,12,62,89,184,0,0,69,88,184,0,4,47,27,185,0,4,0,6,62,89,184,0,2,208,184,0,2,47,184,0,7,16,184,0,9,208,184,0,9,47,184,0,3,208,184,0,4,16,184,0,8,208,184,0,11,208,184,0,7,16,184,0,12,208,48,49,1,65,3,0,56,0,1,0,1,93,65,3,0,72,0,2,0,1,93,65,5,0,25,0,2,0,41,0,2,0,2,93,65,5,0,121,0,2,0,137,0,2,0,2,93,65,5,0,22,0,4,0,38,0,4,0,2,93,65,5,0,118,0,4,0,134,0,4,0,2,93,65,3,0,71,0,4,0,1,93,65,3,0,72,0,9,0,1,93,65,5,0,121,0,9,0,137,0,9,0,2,93,65,5,0,118,0,10,0,134,0,10,0,2,93,0,65,3,0,3,0,3,0,1,93,65,3,0,54,0,3,0,1,93,65,3,0,71,0,3,0,1,93,65,3,0,41,0,3,0,1,113,65,3,0,89,0,8,0,1,93,65,3,0,74,0,8,0,1,93,65,3,0,27,0,8,0,1,93,65,3,0,12,0,8,0,1,93,65,3,0,44,0,8,0,1,93,65,5,0,73,0,11,0,89,0,11,0,2,93,65,7,0,12,0,11,0,28,0,11,0,44,0,11,0,3,93,1,3,35,11,1,35,3,51,27,1,51,27,1,2,202,148,101,102,103,101,147,106,94,104,93,105,94,1,234,254,22,1,106,254,150,1,234,254,121,1,120,254,136,1,135,0,0,0,1,0,11,0,0,1,207,1,234,0,11,1,236,186,0,11,0,5,0,3,43,65,3,0,160,0,11,0,1,93,65,3,0,0,0,11,0,1,93,65,3,0,208,0,11,0,1,93,65,5,0,96,0,11,0,112,0,11,0,2,93,65,3,0,64,0,11,0,1,93,184,0,11,16,184,0,0,208,65,3,0,22,0,0,0,1,93,65,3,0,200,0,0,0,1,93,65,3,0,137,0,0,0,1,93,65,3,0,122,0,0,0,1,93,65,3,0,41,0,0,0,1,93,65,3,0,103,0,0,0,1,93,65,3,0,245,0,0,0,1,93,65,3,0,5,0,0,0,1,93,185,0,1,0,4,244,65,3,0,64,0,5,0,1,93,65,3,0,143,0,5,0,1,93,65,3,0,95,0,5,0,1,93,65,3,0,111,0,5,0,1,113,65,3,0,160,0,5,0,1,93,65,3,0,0,0,5,0,1,93,186,0,2,0,5,0,11,17,18,57,184,0,5,16,184,0,4,208,65,3,0,25,0,4,0,1,93,65,3,0,10,0,4,0,1,93,65,3,0,250,0,4,0,1,93,65,3,0,104,0,4,0,1,93,65,3,0,118,0,4,0,1,93,185,0,3,0,4,244,65,3,0,184,0,3,0,1,93,184,0,4,16,184,0,6,208,65,3,0,39,0,6,0,1,93,185,0,7,0,4,244,186,0,8,0,5,0,11,17,18,57,184,0,0,16,184,0,10,208,185,0,9,0,4,244,65,3,0,47,0,13,0,1,93,0,184,0,0,69,88,184,0,7,47,27,185,0,7,0,12,62,89,184,0,0,69,88,184,0,3,47,27,185,0,3,0,6,62,89,184,0,1,208,186,0,2,0,3,0,7,17,18,57,65,3,0,214,0,2,0,1,93,65,3,0,165,0,2,0,1,93,186,0,8,0,7,0,3,17,18,57,65,3,0,170,0,8,0,1,93,65,3,0,217,0,8,0,1,93,186,0,5,0,8,0,2,17,18,57,184,0,7,16,184,0,9,208,186,0,11,0,2,0,8,17,18,57,48,49,65,3,0,149,0,2,0,1,93,65,3,0,6,0,2,0,1,93,65,3,0,9,0,8,0,1,93,65,3,0,153,0,8,0,1,93,33,35,39,7,35,55,39,51,23,55,51,7,1,207,101,124,126,101,171,167,101,123,113,105,161,193,193,244,246,194,194,238,0,0,0,1,0,7,255,14,1,242,1,234,0,7,0,254,186,0,0,0,4,0,3,43,65,3,0,80,0,0,0,1,93,65,3,0,127,0,4,0,1,93,65,3,0,140,0,4,0,1,93,186,0,1,0,4,0,0,17,18,57,65,3,0,57,0,1,0,1,93,65,3,0,11,0,1,0,1,93,65,3,0,89,0,1,0,1,93,65,3,0,71,0,1,0,1,93,65,3,0,133,0,1,0,1,93,184,0,1,16,185,0,2,0,4,244,184,0,0,16,185,0,7,0,4,244,186,0,3,0,2,0,7,17,18,57,65,3,0,89,0,3,0,1,93,65,3,0,137,0,3,0,1,93,184,0,4,16,185,0,5,0,4,244,186,0,6,0,7,0,2,17,18,57,65,3,0,119,0,6,0,1,93,65,3,0,134,0,6,0,1,93,0,184,0,0,69,88,184,0,5,47,27,185,0,5,0,12,62,89,184,0,0,69,88,184,0,1,47,27,185,0,1,0,8,62,89,186,0,3,0,5,0,1,17,18,57,186,0,6,0,1,0,5,17,18,57,65,5,0,115,0,6,0,131,0,6,0,2,93,184,0,5,16,184,0,7,208,48,49,9,1,35,19,3,51,27,1,1,242,254,212,100,113,204,100,153,138,1,234,253,36,1,8,1,212,254,148,1,108,0,0,0,1,0,22,0,0,1,190,1,234,0,7,1,238,186,0,2,0,6,0,3,43,65,3,0,32,0,2,0,1,93,65,3,0,128,0,2,0,1,93,65,3,0,0,0,2,0,1,93,65,3,0,16,0,2,0,1,113,65,3,0,64,0,2,0,1,93,184,0,2,16,184,0,0,208,65,3,0,70,0,0,0,1,113,65,3,0,207,0,6,0,1,93,65,3,0,95,0,6,0,1,93,65,3,0,175,0,6,0,1,93,65,3,0,127,0,6,0,1,93,65,3,0,32,0,6,0,1,93,65,3,0,64,0,6,0,1,93,184,0,6,16,184,0,4,208,65,3,0,10,0,4,0,1,113,65,3,0,73,0,4,0,1,113,65,3,0,249,0,4,0,1,93,184,0,1,208,65,5,0,19,0,1,0,35,0,1,0,2,113,65,3,0,4,0,1,0,1,113,65,5,0,229,0,1,0,245,0,1,0,2,93,65,7,0,38,0,1,0,54,0,1,0,70,0,1,0,3,93,65,3,0,214,0,1,0,1,93,65,3,0,153,0,1,0,1,93,65,5,0,54,0,1,0,70,0,1,0,2,113,65,3,0,101,0,1,0,1,113,65,3,0,84,0,1,0,1,113,65,5,0,84,0,1,0,100,0,1,0,2,93,65,3,0,113,0,1,0,1,93,65,3,0,128,0,1,0,1,93,184,0,0,16,184,0,5,208,65,3,0,233,0,5,0,1,93,65,3,0,10,0,5,0,1,113,65,3,0,202,0,5,0,1,93,65,3,0,107,0,5,0,1,93,65,3,0,92,0,5,0,1,93,65,3,0,30,0,5,0,1,113,65,3,0,143,0,5,0,1,93,65,3,0,124,0,5,0,1,93,65,3,0,44,0,5,0,1,113,65,3,0,91,0,5,0,1,113,65,3,0,106,0,5,0,1,113,65,5,0,57,0,5,0,73,0,5,0,2,113,65,7,0,41,0,5,0,57,0,5,0,73,0,5,0,3,93,65,3,0,150,0,5,0,1,93,0,184,0,0,69,88,184,0,7,47,27,185,0,7,0,12,62,89,184,0,0,69,88,184,0,3,47,27,185,0,3,0,6,62,89,185,0,2,0,1,244,184,0,7,16,185,0,6,0,1,244,48,49,9,1,33,21,33,1,35,53,1,190,254,251,1,0,254,93,1,5,251,1,234,254,92,70,1,164,70,0,0,1,0,19,255,121,1,41,2,238,0,53,0,163,184,0,0,47,184,0,8,220,184,0,0,16,184,0,16,208,184,0,0,16,184,0,50,220,184,0,20,208,184,0,0,16,184,0,45,220,65,7,0,159,0,45,0,175,0,45,0,191,0,45,0,3,93,184,0,30,208,184,0,8,16,184,0,35,208,0,184,0,51,47,184,0,0,69,88,184,0,19,47,27,185,0,19,0,18,62,89,186,0,35,0,19,0,51,17,18,57,25,184,0,35,47,24,184,0,8,208,184,0,19,16,184,0,20,220,184,0,51,16,184,0,50,220,48,49,1,65,3,0,134,0,22,0,1,93,65,3,0,133,0,48,0,1,93,0,65,3,0,136,0,22,0,1,93,65,3,0,134,0,48,0,1,93,55,52,62,2,53,52,38,39,62,1,53,52,46,2,53,52,54,55,21,14,3,21,20,30,2,21,20,14,2,7,30,3,21,20,14,2,21,20,30,2,23,21,46,1,83,2,3,3,32,40,38,34,3,3,2,97,117,53,57,26,5,1,1,1,7,18,32,26,26,33,18,6,1,1,1,8,29,56,48,115,99,14,7,40,46,42,10,54,69,25,26,69,54,10,42,45,40,7,71,75,4,69,1,20,40,64,46,5,24,27,24,6,18,31,27,26,15,14,25,25,28,16,5,25,29,28,7,54,64,36,14,3,69,4,73,0,1,0,70,255,47,0,159,2,238,0,3,0,54,184,0,1,47,65,5,0,0,0,1,0,16,0,1,0,2,93,184,0,0,220,65,3,0,128,0,0,0,1,93,0,184,0,1,47,184,0,0,69,88,184,0,2,47,27,185,0,2,0,18,62,89,48,49,23,35,17,51,159,89,89,209,3,191,0,0,0,1,0,2,255,121,1,24,2,238,0,53,0,171,184,0,38,47,184,0,0,208,184,0,38,16,184,0,35,220,184,0,4,208,184,0,38,16,184,0,29,220,65,7,0,144,0,29,0,160,0,29,0,176,0,29,0,3,93,184,0,9,208,184,0,38,16,184,0,46,220,184,0,19,208,0,184,0,3,47,184,0,0,69,88,184,0,35,47,27,185,0,35,0,18,62,89,184,0,3,16,184,0,4,220,186,0,19,0,35,0,3,17,18,57,25,184,0,19,47,24,184,0,35,16,184,0,34,220,184,0,19,16,184,0,46,208,48,49,1,65,5,0,136,0,6,0,152,0,6,0,2,93,0,65,3,0,149,0,6,0,1,93,65,3,0,134,0,6,0,1,93,65,5,0,138,0,31,0,154,0,31,0,2,93,55,20,6,7,53,62,3,53,52,46,2,53,52,62,2,55,46,3,53,52,62,2,53,52,46,2,39,53,30,1,21,20,14,2,21,20,22,23,14,1,21,20,30,2,216,99,115,54,58,25,4,1,1,1,7,18,32,26,26,32,18,7,1,1,1,8,29,56,48,117,97,3,3,2,34,38,40,32,2,3,3,14,72,73,4,69,1,20,42,64,44,7,27,29,25,6,17,28,24,25,14,15,26,27,31,18,6,24,27,24,5,54,64,36,14,3,69,4,75,71,7,40,45,42,10,54,69,26,25,69,54,10,42,46,40,0,1,0,54,0,179,1,144,1,26,0,23,0,156,184,0,8,47,184,0,7,220,184,0,8,16,184,0,21,220,184,0,20,220,0,184,0,0,47,184,0,13,220,65,9,0,47,0,13,0,63,0,13,0,79,0,13,0,95,0,13,0,4,93,184,0,5,220,65,3,0,128,0,5,0,1,114,184,0,0,16,184,0,7,208,184,0,7,47,184,0,0,16,184,0,18,220,65,3,0,112,0,18,0,1,114,65,3,0,64,0,18,0,1,113,184,0,13,16,184,0,20,208,184,0,20,47,48,49,1,65,5,0,41,0,10,0,57,0,10,0,2,93,65,5,0,38,0,22,0,54,0,22,0,2,93,0,65,5,0,38,0,10,0,54,0,10,0,2,93,37,34,46,2,35,34,7,39,62,3,51,50,30,2,51,50,55,23,14,1,1,37,12,34,44,32,10,53,18,36,6,22,28,32,15,13,36,46,32,13,42,27,34,11,58,179,16,19,16,49,9,22,34,23,11,15,19,15,51,9,43,51,0,2,0,50,255,6,0,174,1,244,0,3,0,7,0,168,187,0,5,0,4,0,4,0,4,43,65,5,0,0,0,4,0,16,0,4,0,2,93,184,0,4,16,184,0,0,208,65,13,0,9,0,0,0,25,0,0,0,41,0,0,0,57,0,0,0,73,0,0,0,89,0,0,0,6,113,65,5,0,0,0,5,0,16,0,5,0,2,93,184,0,5,16,184,0,3,208,65,13,0,6,0,3,0,22,0,3,0,38,0,3,0,54,0,3,0,70,0,3,0,86,0,3,0,6,113,0,184,0,0,69,88,184,0,4,47,27,185,0,4,0,12,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,8,62,89,184,0,4,16,184,0,7,220,65,3,0,48,0,7,0,1,113,184,0,1,220,48,49,23,19,51,19,3,51,21,35,50,30,64,30,104,84,84,250,2,38,253,218,2,238,86,0,0,1,0,34,255,225,1,170,2,236,0,36,1,110,186,0,18,0,7,0,3,43,65,5,0,63,0,7,0,79,0,7,0,2,93,65,3,0,143,0,7,0,1,93,65,3,0,32,0,18,0,1,113,65,3,0,208,0,18,0,1,93,65,3,0,0,0,18,0,1,93,186,0,1,0,7,0,18,17,18,57,184,0,1,47,65,3,0,0,0,1,0,1,93,185,0,0,0,4,244,184,0,1,16,184,0,13,208,184,0,0,16,184,0,14,208,184,0,7,16,185,0,27,0,4,244,184,0,18,16,184,0,33,208,0,184,0,0,47,184,0,0,69,88,184,0,13,47,27,185,0,13,0,18,62,89,65,3,0,16,0,13,0,1,93,65,5,0,96,0,13,0,112,0,13,0,2,93,65,5,0,48,0,13,0,64,0,13,0,2,93,186,0,36,0,13,0,0,17,18,57,184,0,36,47,65,3,0,79,0,36,0,1,113,65,7,0,159,0,36,0,175,0,36,0,191,0,36,0,3,93,65,3,0,96,0,36,0,1,93,184,0,2,208,184,0,36,16,184,0,15,220,65,3,0,160,0,15,0,1,93,184,0,12,208,184,0,15,16,184,0,19,220,185,0,18,0,2,244,184,0,15,16,185,0,22,0,2,244,184,0,36,16,185,0,30,0,2,244,184,0,36,16,184,0,32,220,185,0,33,0,2,244,48,49,1,65,3,0,9,0,5,0,1,93,65,3,0,9,0,10,0,1,93,65,3,0,69,0,24,0,1,93,65,3,0,69,0,29,0,1,93,0,65,3,0,8,0,5,0,1,93,65,3,0,6,0,10,0,1,93,65,3,0,72,0,29,0,1,93,5,35,55,46,3,53,52,62,2,55,39,51,7,30,1,23,7,46,1,35,34,14,2,21,20,22,51,50,55,23,14,1,7,1,63,90,17,46,78,56,32,28,54,79,51,17,90,16,43,57,23,8,30,62,32,41,61,41,21,88,78,61,61,8,17,48,57,31,120,6,42,66,89,54,49,89,69,46,7,142,140,3,15,14,78,16,17,29,50,67,38,82,100,32,78,11,18,3,0,0,0,1,0,34,0,0,1,224,2,202,0,37,1,125,186,0,37,0,29,0,3,43,65,3,0,16,0,37,0,1,93,184,0,37,16,184,0,0,208,65,3,0,139,0,0,0,1,93,65,3,0,143,0,29,0,1,93,65,3,0,16,0,29,0,1,93,184,0,29,16,185,0,8,0,4,244,186,0,10,0,37,0,29,17,18,57,184,0,10,47,184,0,8,16,184,0,12,208,184,0,17,208,65,5,0,101,0,17,0,117,0,17,0,2,93,65,7,0,53,0,17,0,69,0,17,0,85,0,17,0,3,113,65,3,0,53,0,17,0,1,93,65,3,0,132,0,17,0,1,93,184,0,37,16,184,0,18,208,184,0,18,47,184,0,29,16,184,0,25,208,184,0,20,208,184,0,29,16,184,0,26,208,184,0,26,47,0,184,0,0,69,88,184,0,34,47,27,185,0,34,0,14,62,89,184,0,0,69,88,184,0,19,47,27,185,0,19,0,6,62,89,184,0,34,16,184,0,0,220,184,0,34,16,185,0,3,0,2,244,186,0,9,0,34,0,19,17,18,57,184,0,9,47,65,3,0,15,0,9,0,1,93,185,0,12,0,2,244,184,0,19,16,185,0,18,0,2,244,184,0,12,16,184,0,25,208,184,0,9,16,184,0,28,208,48,49,1,65,3,0,8,0,31,0,1,93,65,3,0,26,0,31,0,1,93,65,3,0,9,0,32,0,1,93,65,5,0,37,0,36,0,53,0,36,0,2,93,65,3,0,70,0,36,0,1,93,0,65,5,0,7,0,31,0,23,0,31,0,2,93,65,5,0,6,0,32,0,22,0,32,0,2,93,65,5,0,54,0,36,0,70,0,36,0,2,93,65,3,0,39,0,36,0,1,93,1,46,1,35,34,14,2,29,1,51,7,35,14,3,7,33,21,33,62,3,55,35,55,51,53,52,62,2,51,50,22,23,1,160,14,45,27,31,35,18,4,192,15,183,3,5,10,17,13,1,5,254,97,25,36,24,16,5,95,14,87,13,38,69,55,69,76,14,2,57,29,27,16,34,51,36,93,86,38,54,49,49,33,86,35,68,73,83,50,86,115,40,73,57,34,49,37,0,2,0,61,0,29,2,53,2,155,0,27,0,46,1,77,184,0,11,47,65,7,0,0,0,11,0,16,0,11,0,32,0,11,0,3,93,184,0,25,220,184,0,11,16,185,0,35,0,4,244,184,0,25,16,185,0,45,0,4,244,0,184,0,4,47,184,0,18,220,185,0,30,0,3,244,184,0,4,16,185,0,40,0,3,244,48,49,1,65,5,0,10,0,1,0,26,0,1,0,2,113,65,5,0,73,0,6,0,89,0,6,0,2,93,65,5,0,73,0,16,0,89,0,16,0,2,93,65,5,0,10,0,21,0,26,0,21,0,2,113,65,5,0,40,0,28,0,56,0,28,0,2,93,65,3,0,137,0,28,0,1,93,65,3,0,134,0,32,0,1,93,65,5,0,39,0,32,0,55,0,32,0,2,93,65,5,0,38,0,38,0,54,0,38,0,2,93,65,3,0,135,0,38,0,1,93,65,3,0,136,0,42,0,1,93,65,5,0,41,0,42,0,57,0,42,0,2,93,65,3,0,136,0,43,0,1,93,0,65,5,0,71,0,6,0,87,0,6,0,2,93,65,3,0,229,0,15,0,1,93,65,5,0,72,0,16,0,88,0,16,0,2,93,65,3,0,229,0,21,0,1,93,65,5,0,40,0,32,0,56,0,32,0,2,93,65,3,0,137,0,32,0,1,93,65,5,0,39,0,38,0,55,0,38,0,2,93,65,3,0,135,0,38,0,1,93,65,5,0,38,0,42,0,54,0,42,0,2,93,65,3,0,134,0,42,0,1,93,37,7,39,6,35,34,39,7,39,55,38,53,52,55,39,55,23,54,51,50,23,55,23,7,22,21,20,7,3,38,35,34,14,2,21,20,30,2,51,50,62,2,53,52,2,52,29,79,70,73,74,69,79,28,77,79,80,78,28,78,76,68,71,72,80,28,78,79,80,53,42,77,39,60,41,22,22,41,60,39,39,60,41,22,53,24,103,38,38,103,24,102,82,111,110,83,102,24,103,38,39,104,24,103,82,110,108,86,1,76,54,29,51,70,42,42,71,51,28,29,52,70,41,85,0,0,0,0,1,0,30,0,0,2,134,2,188,0,22,1,100,187,0,9,0,4,0,10,0,4,43,65,3,0,0,0,9,0,1,93,184,0,9,16,184,0,5,208,184,0,1,208,184,0,0,208,65,3,0,40,0,0,0,1,93,65,3,0,23,0,0,0,1,93,65,3,0,86,0,0,0,1,93,184,0,5,16,184,0,6,208,184,0,6,47,184,0,2,208,184,0,2,47,65,3,0,0,0,10,0,1,93,184,0,10,16,184,0,14,208,184,0,12,208,184,0,12,47,184,0,16,208,184,0,16,47,184,0,14,16,184,0,18,208,184,0,19,208,65,3,0,89,0,19,0,1,93,65,3,0,24,0,19,0,1,93,65,3,0,39,0,19,0,1,93,185,0,20,0,4,244,186,0,21,0,18,0,1,17,18,57,184,0,0,16,185,0,22,0,4,244,0,184,0,0,69,88,184,0,20,47,27,185,0,20,0,14,62,89,184,0,0,69,88,184,0,10,47,27,185,0,10,0,6,62,89,186,0,17,0,20,0,10,17,18,57,184,0,17,47,184,0,1,208,184,0,17,16,184,0,16,220,184,0,4,208,184,0,17,16,184,0,13,220,65,5,0,32,0,13,0,48,0,13,0,2,93,184,0,5,208,184,0,13,16,184,0,12,220,184,0,8,208,186,0,21,0,20,0,10,17,18,57,65,3,0,102,0,21,0,1,93,65,3,0,41,0,21,0,1,93,65,3,0,54,0,21,0,1,93,65,3,0,131,0,21,0,1,93,184,0,20,16,184,0,22,208,48,49,65,3,0,134,0,21,0,1,93,65,3,0,9,0,21,0,1,93,9,1,51,7,35,21,51,7,35,21,35,53,35,55,51,53,35,55,51,1,51,27,1,2,134,254,253,177,21,157,178,21,157,96,178,21,157,178,21,156,254,253,93,215,215,2,188,254,128,54,62,54,146,146,54,62,54,1,128,254,205,1,51,0,0,0,0,2,0,72,255,46,0,160,2,238,0,3,0,7,0,78,184,0,6,47,65,5,0,0,0,6,0,16,0,6,0,2,93,184,0,7,220,65,3,0,128,0,7,0,1,93,184,0,0,208,184,0,6,16,184,0,1,208,0,184,0,5,47,184,0,0,69,88,184,0,2,47,27,185,0,2,0,18,62,89,184,0,1,220,184,0,5,16,184,0,6,220,48,49,19,35,17,51,17,35,17,51,160,88,88,88,88,1,52,1,186,252,64,1,117,0,0,2,0,37,255,172,1,163,2,238,0,52,0,64,3,51,186,0,51,0,26,0,3,43,65,3,0,0,0,51,0,1,93,65,3,0,143,0,26,0,1,93,65,3,0,0,0,26,0,1,93,186,0,5,0,51,0,26,17,18,57,184,0,5,47,184,0,26,16,185,0,58,0,5,244,186,0,0,0,5,0,58,17,18,57,186,0,13,0,26,0,51,17,18,57,184,0,13,47,184,0,5,16,185,0,19,0,5,244,186,0,31,0,26,0,51,17,18,57,184,0,31,47,184,0,51,16,185,0,63,0,5,244,186,0,28,0,31,0,63,17,18,57,65,3,0,25,0,28,0,1,93,65,7,0,53,0,28,0,69,0,28,0,85,0,28,0,3,93,65,3,0,116,0,28,0,1,93,186,0,38,0,51,0,26,17,18,57,184,0,38,47,184,0,31,16,185,0,44,0,5,244,186,0,53,0,63,0,31,17,18,57,186,0,60,0,58,0,5,17,18,57,0,184,0,10,47,184,0,0,69,88,184,0,36,47,27,185,0,36,0,18,62,89,186,0,60,0,10,0,36,17,18,57,184,0,60,47,184,0,22,208,65,5,0,121,0,22,0,137,0,22,0,2,93,65,3,0,72,0,22,0,1,93,186,0,0,0,60,0,22,17,18,57,184,0,10,16,184,0,14,220,184,0,10,16,185,0,16,0,3,244,186,0,53,0,36,0,10,17,18,57,184,0,53,47,184,0,47,208,65,5,0,118,0,47,0,134,0,47,0,2,93,65,3,0,22,0,47,0,1,93,65,3,0,69,0,47,0,1,93,186,0,28,0,47,0,53,17,18,57,184,0,36,16,184,0,39,220,184,0,36,16,185,0,41,0,3,244,48,49,1,65,3,0,21,0,7,0,1,93,65,3,0,38,0,7,0,1,93,65,3,0,104,0,13,0,1,93,65,3,0,72,0,23,0,1,93,65,3,0,25,0,24,0,1,93,65,3,0,73,0,24,0,1,93,65,7,0,105,0,24,0,121,0,24,0,137,0,24,0,3,93,65,3,0,73,0,25,0,1,93,65,3,0,26,0,25,0,1,93,65,3,0,139,0,27,0,1,93,65,3,0,40,0,34,0,1,93,65,3,0,25,0,34,0,1,93,65,3,0,133,0,46,0,1,93,65,5,0,103,0,48,0,119,0,48,0,2,93,65,3,0,21,0,49,0,1,93,65,5,0,118,0,49,0,134,0,49,0,2,93,65,3,0,71,0,49,0,1,93,65,3,0,103,0,49,0,1,93,65,3,0,85,0,59,0,1,93,0,65,5,0,24,0,7,0,40,0,7,0,2,93,65,5,0,121,0,12,0,137,0,12,0,2,93,65,3,0,122,0,13,0,1,93,65,3,0,107,0,13,0,1,93,65,3,0,73,0,23,0,1,93,65,3,0,25,0,24,0,1,93,65,3,0,73,0,24,0,1,93,65,5,0,105,0,24,0,121,0,24,0,2,93,65,3,0,138,0,24,0,1,93,65,3,0,133,0,27,0,1,93,65,3,0,20,0,34,0,1,93,65,3,0,37,0,34,0,1,93,65,3,0,101,0,38,0,1,93,65,3,0,133,0,38,0,1,93,65,3,0,118,0,38,0,1,93,65,3,0,135,0,46,0,1,93,65,3,0,117,0,48,0,1,93,65,3,0,102,0,48,0,1,93,65,3,0,116,0,49,0,1,93,65,3,0,21,0,49,0,1,93,65,3,0,70,0,49,0,1,93,65,3,0,102,0,49,0,1,93,65,3,0,134,0,49,0,1,93,65,3,0,83,0,59,0,1,93,65,3,0,37,0,59,0,1,93,65,3,0,41,0,64,0,1,93,65,3,0,91,0,64,0,1,93,37,30,3,21,20,14,2,35,34,38,39,55,22,51,50,54,53,52,46,4,53,52,55,46,1,53,52,62,2,51,50,23,7,38,35,34,6,21,20,30,4,21,20,39,14,3,21,20,23,62,1,53,52,1,59,21,23,12,3,20,41,64,43,43,80,20,13,68,63,48,55,40,61,71,61,40,109,39,25,19,41,62,43,86,61,13,68,62,45,52,39,59,69,59,39,215,14,35,30,20,162,36,42,188,16,26,27,30,20,30,56,42,25,22,17,63,41,41,42,35,39,24,21,37,61,53,116,33,28,51,29,35,60,43,25,40,63,43,50,36,31,37,26,25,40,63,51,99,206,1,11,23,36,25,81,42,10,58,37,81,0,0,2,0,87,2,88,1,79,2,188,0,3,0,7,0,70,184,0,5,47,65,3,0,0,0,5,0,1,93,184,0,1,220,184,0,0,220,184,0,5,16,184,0,4,220,0,184,0,5,47,65,3,0,32,0,5,0,1,93,65,3,0,64,0,5,0,1,93,184,0,1,208,184,0,5,16,184,0,6,220,184,0,2,208,48,49,1,35,53,51,7,35,53,51,1,79,70,70,178,70,70,2,88,100,100,100,0,0,0,3,0,49,0,37,2,158,2,181,0,19,0,39,0,65,3,127,184,0,0,47,184,0,10,220,65,3,0,239,0,10,0,1,93,65,3,0,111,0,10,0,1,93,65,3,0,80,0,10,0,1,93,184,0,0,16,184,0,25,220,184,0,10,16,184,0,35,220,186,0,45,0,0,0,10,17,18,57,184,0,45,47,184,0,52,220,184,0,45,16,184,0,58,220,184,0,52,16,184,0,64,208,0,184,0,5,47,184,0,15,220,184,0,5,16,184,0,20,220,184,0,15,16,184,0,30,220,186,0,40,0,5,0,15,17,18,57,184,0,40,47,65,3,0,15,0,40,0,1,93,65,3,0,111,0,40,0,1,93,184,0,50,220,65,3,0,32,0,50,0,1,93,65,3,0,0,0,50,0,1,93,184,0,53,220,184,0,50,16,184,0,55,220,65,3,0,15,0,55,0,1,113,184,0,40,16,184,0,61,220,184,0,40,16,184,0,63,220,48,49,1,65,5,0,9,0,2,0,25,0,2,0,2,93,65,3,0,41,0,2,0,1,113,65,5,0,106,0,2,0,122,0,2,0,2,93,65,5,0,8,0,3,0,24,0,3,0,2,93,65,3,0,183,0,6,0,1,93,65,3,0,37,0,7,0,1,113,65,5,0,7,0,7,0,23,0,7,0,2,93,65,5,0,101,0,8,0,117,0,8,0,2,93,65,5,0,6,0,8,0,22,0,8,0,2,93,65,5,0,7,0,12,0,23,0,12,0,2,93,65,5,0,6,0,13,0,22,0,13,0,2,93,65,5,0,103,0,13,0,119,0,13,0,2,93,65,3,0,39,0,13,0,1,113,65,5,0,9,0,17,0,25,0,17,0,2,93,65,5,0,106,0,17,0,122,0,17,0,2,93,65,3,0,42,0,17,0,1,113,65,5,0,10,0,18,0,26,0,18,0,2,93,65,9,0,169,0,42,0,185,0,42,0,201,0,42,0,217,0,42,0,4,93,65,9,0,169,0,43,0,185,0,43,0,201,0,43,0,217,0,43,0,4,93,65,3,0,42,0,43,0,1,93,65,9,0,169,0,47,0,185,0,47,0,201,0,47,0,217,0,47,0,4,93,65,3,0,42,0,47,0,1,93,65,9,0,169,0,48,0,185,0,48,0,201,0,48,0,217,0,48,0,4,93,65,9,0,167,0,52,0,183,0,52,0,199,0,52,0,215,0,52,0,4,93,0,65,5,0,6,0,2,0,22,0,2,0,2,93,65,5,0,102,0,2,0,118,0,2,0,2,93,65,3,0,38,0,2,0,1,113,65,5,0,6,0,3,0,22,0,3,0,2,93,65,3,0,182,0,6,0,1,93,65,5,0,7,0,7,0,23,0,7,0,2,93,65,3,0,39,0,7,0,1,113,65,5,0,6,0,8,0,22,0,8,0,2,93,65,5,0,103,0,8,0,119,0,8,0,2,93,65,5,0,8,0,12,0,24,0,12,0,2,93,65,3,0,41,0,13,0,1,113,65,5,0,10,0,13,0,26,0,13,0,2,93,65,5,0,106,0,13,0,122,0,13,0,2,93,65,5,0,9,0,17,0,25,0,17,0,2,93,65,5,0,105,0,17,0,121,0,17,0,2,93,65,3,0,42,0,17,0,1,113,65,5,0,8,0,18,0,24,0,18,0,2,93,65,9,0,168,0,42,0,184,0,42,0,200,0,42,0,216,0,42,0,4,93,65,3,0,40,0,43,0,1,93,65,9,0,169,0,43,0,185,0,43,0,201,0,43,0,217,0,43,0,4,93,65,3,0,38,0,47,0,1,93,65,9,0,167,0,47,0,183,0,47,0,199,0,47,0,215,0,47,0,4,93,65,9,0,165,0,48,0,181,0,48,0,197,0,48,0,213,0,48,0,4,93,65,9,0,165,0,51,0,181,0,51,0,197,0,51,0,213,0,51,0,4,93,65,9,0,165,0,52,0,181,0,52,0,197,0,52,0,213,0,52,0,4,93,65,9,0,172,0,64,0,188,0,64,0,204,0,64,0,220,0,64,0,4,93,19,52,62,2,51,50,30,2,21,20,14,2,35,34,46,2,1,34,14,2,21,20,30,2,51,50,62,2,53,52,46,2,3,34,46,2,53,52,62,2,51,50,23,7,38,35,34,6,21,20,22,51,50,55,23,6,49,46,83,114,68,68,114,82,46,46,82,114,68,68,115,82,46,1,55,63,96,66,34,33,66,97,63,63,96,66,33,34,65,96,54,35,58,42,23,23,42,58,35,48,42,7,45,38,45,46,46,45,37,46,7,38,1,109,74,121,86,47,47,87,121,73,73,120,87,48,48,86,121,1,100,41,75,104,63,63,104,75,41,42,75,104,62,62,104,75,42,254,61,24,43,61,38,38,62,43,24,19,60,19,59,48,48,59,20,59,20,0,2,0,33,1,178,1,57,2,213,0,27,0,35,1,120,184,0,9,47,65,3,0,96,0,9,0,1,93,184,0,24,220,65,3,0,159,0,24,0,1,93,184,0,0,208,184,0,0,47,184,0,24,16,185,0,29,0,5,244,184,0,4,208,184,0,29,16,184,0,14,208,186,0,19,0,24,0,9,17,18,57,184,0,19,47,184,0,9,16,185,0,32,0,5,244,0,184,0,21,47,184,0,6,220,65,3,0,96,0,6,0,1,93,65,3,0,48,0,6,0,1,93,65,3,0,208,0,6,0,1,93,184,0,2,208,186,0,14,0,21,0,6,17,18,57,184,0,14,47,184,0,21,16,185,0,16,0,3,244,184,0,21,16,184,0,18,220,184,0,6,16,185,0,34,0,3,244,184,0,27,208,184,0,14,16,184,0,29,220,48,49,1,65,3,0,151,0,7,0,1,93,65,3,0,183,0,7,0,1,93,65,3,0,217,0,7,0,1,93,65,13,0,59,0,8,0,75,0,8,0,91,0,8,0,107,0,8,0,123,0,8,0,139,0,8,0,6,93,65,3,0,40,0,11,0,1,93,65,3,0,34,0,22,0,1,93,65,13,0,53,0,22,0,69,0,22,0,85,0,22,0,101,0,22,0,117,0,22,0,133,0,22,0,6,93,65,3,0,151,0,22,0,1,93,0,65,7,0,170,0,7,0,186,0,7,0,202,0,7,0,3,93,65,3,0,155,0,7,0,1,93,65,3,0,220,0,7,0,1,93,65,3,0,38,0,11,0,1,93,65,3,0,36,0,22,0,1,93,65,15,0,53,0,22,0,69,0,22,0,85,0,22,0,101,0,22,0,117,0,22,0,133,0,22,0,149,0,22,0,7,93,1,7,35,34,39,6,35,34,38,53,52,62,2,55,38,35,34,7,39,54,51,50,29,1,20,22,51,39,53,14,1,21,20,51,50,1,57,7,27,48,19,31,61,37,50,35,52,58,23,2,51,32,51,6,54,55,109,9,17,101,35,55,40,27,1,239,61,31,31,46,39,29,38,23,10,1,42,20,60,23,108,80,30,12,12,63,1,25,22,32,0,0,0,2,0,15,0,78,2,11,1,234,0,5,0,11,0,156,184,0,8,47,65,3,0,31,0,8,0,1,93,65,3,0,143,0,8,0,1,93,184,0,2,220,184,0,4,220,184,0,0,208,185,0,1,0,4,244,184,0,3,208,184,0,2,16,185,0,5,0,4,244,184,0,8,16,184,0,10,220,184,0,6,208,184,0,10,16,185,0,9,0,4,244,184,0,7,208,184,0,8,16,185,0,11,0,4,244,65,3,0,47,0,13,0,1,93,0,25,184,0,8,47,24,184,0,7,208,184,0,7,47,184,0,1,208,184,0,8,16,184,0,11,208,184,0,2,208,184,0,8,16,184,0,9,208,184,0,9,47,184,0,3,208,184,0,2,16,184,0,5,208,48,49,37,35,39,55,51,15,1,35,39,55,51,7,2,11,101,147,147,101,148,113,100,147,147,100,147,78,206,206,206,206,206,206,206,0,0,0,0,1,0,66,0,151,2,14,1,150,0,5,0,66,184,0,0,47,65,3,0,0,0,0,0,1,93,65,3,0,208,0,0,0,1,93,184,0,1,220,65,7,0,0,0,1,0,16,0,1,0,32,0,1,0,3,113,184,0,0,16,184,0,3,220,0,184,0,3,47,184,0,4,220,184,0,1,220,48,49,37,35,53,33,53,33,2,14,55,254,107,1,204,151,195,60,0,1,0,57,0,230,1,111,1,68,0,3,0,72,184,0,1,47,65,5,0,0,0,1,0,16,0,1,0,2,93,65,3,0,48,0,1,0,1,113,184,0,0,220,65,3,0,96,0,0,0,1,93,0,184,0,1,47,184,0,2,220,65,3,0,32,0,2,0,1,113,65,5,0,112,0,2,0,128,0,2,0,2,93,48,49,37,33,53,33,1,111,254,202,1,54,230,94,0,0,0,4,0,49,0,37,2,158,2,181,0,19,0,39,0,52,0,60,2,254,184,0,0,47,184,0,10,220,65,3,0,239,0,10,0,1,93,65,3,0,111,0,10,0,1,93,65,3,0,80,0,10,0,1,93,184,0,0,16,184,0,25,220,65,3,0,79,0,25,0,1,113,184,0,10,16,184,0,35,220,65,3,0,64,0,35,0,1,113,186,0,45,0,0,0,10,17,18,57,184,0,45,47,65,3,0,64,0,45,0,1,93,184,0,50,220,184,0,45,16,184,0,44,220,65,5,0,239,0,44,0,255,0,44,0,2,93,186,0,52,0,50,0,44,17,18,57,65,5,0,69,0,52,0,85,0,52,0,2,93,65,3,0,100,0,52,0,1,93,184,0,52,16,184,0,40,208,65,5,0,233,0,40,0,249,0,40,0,2,93,184,0,52,16,184,0,42,208,184,0,41,208,184,0,44,16,184,0,55,208,184,0,50,16,184,0,58,220,0,184,0,5,47,184,0,15,220,184,0,5,16,184,0,20,220,184,0,15,16,184,0,30,220,186,0,45,0,5,0,15,17,18,57,184,0,45,47,184,0,41,208,184,0,45,16,184,0,46,220,65,3,0,32,0,46,0,1,93,65,3,0,0,0,46,0,1,93,186,0,43,0,46,0,45,17,18,57,184,0,43,47,186,0,52,0,46,0,43,17,18,57,65,3,0,88,0,52,0,1,93,184,0,46,16,184,0,54,220,184,0,43,16,184,0,55,220,48,49,1,65,5,0,9,0,2,0,25,0,2,0,2,93,65,5,0,106,0,2,0,122,0,2,0,2,93,65,5,0,9,0,3,0,25,0,3,0,2,93,65,3,0,41,0,3,0,1,113,65,5,0,6,0,7,0,22,0,7,0,2,93,65,3,0,38,0,7,0,1,113,65,5,0,6,0,8,0,22,0,8,0,2,93,65,5,0,102,0,8,0,118,0,8,0,2,93,65,3,0,35,0,12,0,1,113,65,5,0,6,0,12,0,22,0,12,0,2,93,65,5,0,102,0,12,0,118,0,12,0,2,93,65,5,0,7,0,13,0,23,0,13,0,2,93,65,5,0,103,0,13,0,119,0,13,0,2,93,65,5,0,8,0,17,0,24,0,17,0,2,93,65,5,0,9,0,18,0,25,0,18,0,2,93,65,3,0,41,0,18,0,1,113,65,5,0,25,0,40,0,41,0,40,0,2,113,65,3,0,90,0,40,0,1,113,0,65,5,0,102,0,2,0,118,0,2,0,2,93,65,5,0,7,0,2,0,23,0,2,0,2,93,65,3,0,39,0,2,0,1,113,65,5,0,6,0,3,0,22,0,3,0,2,93,65,3,0,38,0,3,0,1,113,65,3,0,37,0,7,0,1,113,65,3,0,182,0,7,0,1,93,65,5,0,7,0,7,0,23,0,7,0,2,93,65,5,0,102,0,8,0,118,0,8,0,2,93,65,5,0,7,0,8,0,23,0,8,0,2,93,65,5,0,8,0,12,0,24,0,12,0,2,93,65,5,0,104,0,12,0,120,0,12,0,2,93,65,3,0,40,0,12,0,1,113,65,5,0,9,0,13,0,25,0,13,0,2,93,65,5,0,105,0,13,0,121,0,13,0,2,93,65,5,0,8,0,17,0,24,0,17,0,2,93,65,5,0,106,0,17,0,122,0,17,0,2,93,65,5,0,8,0,18,0,24,0,18,0,2,93,65,3,0,24,0,40,0,1,113,65,3,0,41,0,40,0,1,113,19,52,62,2,51,50,30,2,21,20,14,2,35,34,46,2,1,34,14,2,21,20,30,2,51,50,62,2,53,52,46,2,19,35,39,35,21,35,17,51,50,22,21,20,7,39,35,21,51,50,53,52,38,49,46,83,114,68,68,114,82,46,46,82,114,68,68,115,82,46,1,55,63,97,66,34,33,66,97,64,63,97,65,34,34,66,96,66,63,65,55,62,118,54,56,54,70,42,40,61,26,1,109,74,121,86,47,47,87,121,73,73,120,87,48,48,86,121,1,101,42,75,105,62,62,105,76,41,41,76,105,62,62,105,75,42,254,73,117,117,1,65,45,55,51,36,138,99,50,24,25,0,0,0,0,2,0,34,1,226,1,43,2,243,0,16,0,34,1,110,184,0,5,47,65,3,0,246,0,2,0,1,93,184,0,15,220,65,3,0,79,0,15,0,1,93,65,3,0,15,0,15,0,1,93,184,0,5,16,184,0,22,220,65,3,0,143,0,22,0,1,113,65,5,0,239,0,22,0,255,0,22,0,2,114,184,0,15,16,184,0,30,220,0,184,0,0,69,88,184,0,10,47,27,185,0,10,0,18,62,89,184,0,2,220,65,3,0,255,0,2,0,1,93,65,3,0,0,0,2,0,1,93,184,0,10,16,184,0,17,220,184,0,2,16,184,0,25,220,48,49,1,65,7,0,21,0,0,0,37,0,0,0,53,0,0,0,3,93,65,3,0,6,0,0,0,1,93,65,7,0,26,0,4,0,42,0,4,0,58,0,4,0,3,93,65,3,0,11,0,4,0,1,93,65,7,0,25,0,7,0,41,0,7,0,57,0,7,0,3,93,65,3,0,10,0,7,0,1,93,65,7,0,24,0,8,0,40,0,8,0,56,0,8,0,3,93,65,7,0,22,0,12,0,38,0,12,0,54,0,12,0,3,93,65,3,0,7,0,12,0,1,93,65,3,0,6,0,13,0,1,93,0,65,9,0,9,0,0,0,25,0,0,0,41,0,0,0,57,0,0,0,4,93,65,9,0,9,0,3,0,25,0,3,0,41,0,3,0,57,0,3,0,4,93,65,3,0,6,0,7,0,1,93,65,7,0,23,0,8,0,39,0,8,0,55,0,8,0,3,93,65,7,0,22,0,12,0,38,0,12,0,54,0,12,0,3,93,65,3,0,7,0,12,0,1,93,65,3,0,7,0,13,0,1,93,1,6,35,34,38,53,52,62,2,51,50,30,2,21,20,39,34,14,2,21,20,22,51,50,62,2,53,52,46,2,1,7,36,61,63,69,18,35,49,30,30,50,34,19,133,21,32,23,12,49,44,21,30,21,10,11,22,32,2,8,38,77,59,30,50,36,21,21,37,50,29,59,170,18,30,41,22,48,62,19,31,36,24,22,40,31,18,0,0,0,0,2,0,64,0,42,1,178,2,20,0,11,0,15,0,121,184,0,4,47,65,3,0,0,0,4,0,1,93,184,0,1,220,65,3,0,239,0,1,0,1,93,184,0,0,220,184,0,4,16,184,0,5,220,184,0,4,16,184,0,7,208,184,0,1,16,184,0,10,208,184,0,5,16,184,0,14,208,184,0,0,16,184,0,15,208,0,184,0,13,47,184,0,5,220,184,0,1,208,184,0,5,16,184,0,3,220,184,0,5,16,184,0,6,220,184,0,8,220,184,0,6,16,184,0,10,208,184,0,13,16,184,0,14,220,48,49,1,35,21,35,53,35,53,51,53,51,21,51,17,33,53,33,1,178,153,64,153,153,64,153,254,142,1,114,1,71,144,144,67,138,138,254,160,67,0,0,1,0,25,1,64,1,17,2,194,0,23,1,117,186,0,20,0,12,0,3,43,65,3,0,80,0,12,0,1,93,184,0,12,16,184,0,1,208,65,3,0,80,0,20,0,1,93,65,3,0,32,0,20,0,1,93,184,0,20,16,185,0,6,0,5,244,184,0,1,16,184,0,22,208,65,3,0,102,0,22,0,1,93,65,3,0,38,0,22,0,1,93,65,7,0,21,0,22,0,37,0,22,0,53,0,22,0,3,113,184,0,20,16,184,0,23,208,184,0,23,47,0,184,0,0,69,88,184,0,15,47,27,185,0,15,0,14,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,10,62,89,185,0,23,0,1,244,184,0,2,208,184,0,15,16,185,0,9,0,3,244,184,0,15,16,184,0,11,220,65,3,0,239,0,11,0,1,93,184,0,12,220,48,49,1,65,3,0,136,0,3,0,1,93,65,11,0,72,0,13,0,88,0,13,0,104,0,13,0,120,0,13,0,136,0,13,0,5,93,65,11,0,55,0,17,0,71,0,17,0,87,0,17,0,103,0,17,0,119,0,17,0,5,93,65,11,0,54,0,18,0,70,0,18,0,86,0,18,0,102,0,18,0,118,0,18,0,5,93,65,7,0,150,0,22,0,166,0,22,0,182,0,22,0,3,93,0,65,3,0,135,0,3,0,1,93,65,11,0,70,0,13,0,86,0,13,0,102,0,13,0,118,0,13,0,134,0,13,0,5,93,65,11,0,55,0,17,0,71,0,17,0,87,0,17,0,103,0,17,0,119,0,17,0,5,93,65,11,0,55,0,18,0,71,0,18,0,87,0,18,0,103,0,18,0,119,0,18,0,5,93,1,35,62,3,53,52,38,35,34,7,39,62,1,51,50,30,2,21,20,7,51,1,17,248,57,66,33,8,30,27,51,42,9,11,61,45,30,42,27,13,106,120,1,64,77,97,60,30,9,25,28,59,65,19,35,16,28,37,21,68,146,0,1,0,19,1,56,1,21,2,194,0,38,1,205,186,0,34,0,5,0,3,43,65,3,0,159,0,5,0,1,93,65,3,0,111,0,5,0,1,93,65,3,0,95,0,5,0,1,113,65,3,0,240,0,5,0,1,93,65,3,0,32,0,5,0,1,113,65,5,0,16,0,34,0,32,0,34,0,2,93,65,3,0,159,0,34,0,1,93,65,3,0,240,0,34,0,1,93,65,3,0,80,0,34,0,1,93,65,3,0,32,0,34,0,1,113,184,0,34,16,185,0,10,0,5,244,186,0,14,0,5,0,34,17,18,57,184,0,14,47,65,3,0,15,0,14,0,1,93,186,0,30,0,34,0,5,17,18,57,184,0,30,47,185,0,18,0,5,244,186,0,23,0,5,0,34,17,18,57,184,0,23,47,186,0,32,0,14,0,30,17,18,57,65,7,0,38,0,32,0,54,0,32,0,70,0,32,0,3,93,65,5,0,85,0,32,0,101,0,32,0,2,93,0,184,0,0,69,88,184,0,25,47,27,185,0,25,0,14,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,10,62,89,184,0,6,220,65,5,0,112,0,6,0,128,0,6,0,2,93,184,0,0,16,185,0,8,0,1,244,186,0,16,0,25,0,0,17,18,57,184,0,16,47,65,3,0,31,0,16,0,1,93,185,0,13,0,3,244,184,0,25,16,185,0,20,0,3,244,184,0,25,16,184,0,22,220,186,0,32,0,16,0,13,17,18,57,48,49,1,65,3,0,38,0,27,0,1,93,65,3,0,70,0,27,0,1,93,65,3,0,55,0,27,0,1,93,65,3,0,87,0,27,0,1,93,65,3,0,104,0,27,0,1,93,65,3,0,38,0,37,0,1,93,65,3,0,71,0,37,0,1,93,0,65,3,0,101,0,27,0,1,93,65,9,0,38,0,27,0,54,0,27,0,70,0,27,0,86,0,27,0,4,93,65,3,0,118,0,27,0,1,93,65,3,0,41,0,37,0,1,93,65,3,0,73,0,37,0,1,93,65,3,0,58,0,37,0,1,93,19,34,46,2,39,55,22,51,50,53,52,38,43,1,55,51,50,53,52,35,34,7,39,54,51,50,30,2,21,20,7,22,21,20,14,2,128,17,35,30,23,4,18,32,56,78,31,43,52,6,27,77,60,49,22,11,26,65,36,48,29,13,39,54,24,41,54,1,56,6,9,10,5,66,26,52,30,34,55,48,44,17,53,25,18,28,36,19,53,22,32,61,30,46,32,17,0,0,1,0,58,2,84,0,245,2,220,0,3,0,105,184,0,2,47,65,3,0,0,0,2,0,1,93,184,0,0,220,0,184,0,1,47,65,3,0,64,0,1,0,1,93,65,3,0,32,0,1,0,1,93,65,3,0,16,0,1,0,1,113,184,0,3,220,65,5,0,15,0,3,0,31,0,3,0,2,93,184,0,0,220,65,11,0,89,0,0,0,105,0,0,0,121,0,0,0,137,0,0,0,153,0,0,0,5,93,184,0,1,16,184,0,2,220,48,49,19,7,53,55,245,187,187,2,148,64,41,95,0,0,1,0,73,255,14,2,44,1,234,0,27,0,252,186,0,23,0,13,0,3,43,65,3,0,143,0,23,0,1,93,65,3,0,0,0,23,0,1,93,65,3,0,32,0,23,0,1,93,184,0,23,16,185,0,22,0,4,244,186,0,4,0,22,0,23,17,18,57,65,3,0,143,0,13,0,1,93,65,3,0,0,0,13,0,1,93,65,3,0,32,0,13,0,1,93,184,0,13,16,185,0,14,0,4,244,184,0,10,208,0,184,0,0,69,88,184,0,14,47,27,185,0,14,0,12,62,89,184,0,0,69,88,184,0,7,47,27,185,0,7,0,6,62,89,184,0,0,69,88,184,0,1,47,27,185,0,1,0,6,62,89,184,0,0,69,88,184,0,12,47,27,185,0,12,0,8,62,89,184,0,1,16,185,0,0,0,1,244,184,0,14,16,184,0,22,208,186,0,4,0,7,0,22,17,18,57,186,0,10,0,14,0,7,17,18,57,65,5,0,122,0,10,0,138,0,10,0,2,93,184,0,7,16,185,0,18,0,2,244,48,49,1,65,5,0,85,0,17,0,101,0,17,0,2,93,0,65,3,0,88,0,17,0,1,93,37,7,35,34,39,14,1,35,34,38,39,17,35,17,51,17,20,22,51,50,54,55,17,51,17,20,22,51,2,44,16,26,79,28,33,57,44,32,47,33,88,89,53,69,38,50,28,87,19,28,62,72,73,38,36,15,23,254,243,2,220,254,254,84,79,26,32,1,107,254,192,57,51,0,0,1,0,33,0,0,2,68,2,188,0,19,0,140,184,0,7,47,65,5,0,0,0,7,0,16,0,7,0,2,93,184,0,3,220,65,5,0,15,0,3,0,31,0,3,0,2,93,184,0,2,220,184,0,0,220,184,0,7,16,184,0,6,220,184,0,7,16,184,0,13,220,65,5,0,15,0,13,0,31,0,13,0,2,93,0,184,0,0,69,88,184,0,19,47,27,185,0,19,0,14,62,89,184,0,0,69,88,184,0,6,47,27,185,0,6,0,6,62,89,184,0,19,16,184,0,0,220,184,0,6,16,184,0,3,208,184,0,0,16,184,0,4,208,184,0,19,16,184,0,8,220,48,49,1,35,17,35,17,35,17,35,53,46,3,53,52,62,2,51,33,2,68,75,48,101,41,70,105,71,36,38,73,108,69,1,3,2,121,253,135,2,121,253,135,243,4,40,63,80,44,45,82,62,37,0,0,0,0,1,0,57,0,213,0,181,1,87,0,3,0,76,184,0,1,47,65,5,0,32,0,1,0,48,0,1,0,2,113,65,5,0,0,0,1,0,16,0,1,0,2,93,184,0,0,220,65,3,0,191,0,0,0,1,93,65,3,0,63,0,0,0,1,93,65,5,0,47,0,0,0,63,0,0,0,2,113,0,184,0,1,47,184,0,2,220,48,49,55,35,53,51,181,124,124,213,130,0,0,1,0,144,255,64,1,22,255,202,0,3,0,54,184,0,2,47,65,3,0,32,0,2,0,1,93,184,0,0,220,65,5,0,31,0,0,0,47,0,0,0,2,93,0,184,0,4,47,184,0,0,220,184,0,2,220,65,3,0,16,0,2,0,1,93,48,49,5,15,1,55,1,22,88,46,68,54,133,5,132,0,0,0,0,1,0,23,1,64,0,155,2,186,0,11,0,171,187,0,0,0,5,0,1,0,4,43,65,5,0,143,0,0,0,159,0,0,0,2,93,65,3,0,207,0,0,0,1,93,65,7,0,0,0,0,0,16,0,0,0,32,0,0,0,3,93,65,5,0,143,0,1,0,159,0,1,0,2,93,65,3,0,207,0,1,0,1,93,65,7,0,0,0,1,0,16,0,1,0,32,0,1,0,3,93,184,0,1,16,184,0,5,208,184,0,5,47,186,0,10,0,1,0,0,17,18,57,0,184,0,0,69,88,184,0,11,47,27,185,0,11,0,14,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,10,62,89,184,0,11,16,184,0,4,220,186,0,2,0,4,0,11,17,18,57,185,0,5,0,3,244,48,49,19,35,17,6,7,39,62,3,55,51,155,75,32,19,6,9,24,21,18,3,57,1,64,1,20,14,3,60,1,13,16,20,9,0,0,0,2,0,33,1,178,1,81,2,213,0,18,0,31,0,233,184,0,7,47,65,3,0,96,0,7,0,1,93,184,0,17,220,184,0,7,16,185,0,24,0,5,244,184,0,17,16,185,0,30,0,5,244,0,184,0,12,47,184,0,2,220,65,3,0,208,0,2,0,1,93,65,3,0,96,0,2,0,1,93,65,3,0,48,0,2,0,1,93,184,0,12,16,185,0,21,0,3,244,184,0,2,16,185,0,27,0,3,244,48,49,1,65,7,0,6,0,0,0,22,0,0,0,38,0,0,0,3,93,65,7,0,9,0,5,0,25,0,5,0,41,0,5,0,3,93,65,7,0,8,0,10,0,24,0,10,0,40,0,10,0,3,93,65,7,0,6,0,14,0,22,0,14,0,38,0,14,0,3,93,0,65,7,0,9,0,0,0,25,0,0,0,41,0,0,0,3,93,65,7,0,8,0,5,0,24,0,5,0,40,0,5,0,3,93,65,7,0,6,0,10,0,22,0,10,0,38,0,10,0,3,93,65,7,0,6,0,14,0,22,0,14,0,38,0,14,0,3,93,1,6,35,34,46,2,53,52,62,2,51,50,30,2,21,20,39,38,35,34,6,21,20,22,51,50,54,53,52,1,39,41,69,35,56,39,22,21,39,57,35,35,56,40,21,97,20,35,35,40,40,35,35,40,1,220,42,23,39,53,31,30,53,39,23,23,39,53,30,61,123,24,49,37,38,48,48,38,37,0,2,0,41,0,78,2,36,1,234,0,5,0,11,0,195,184,0,0,47,65,3,0,0,0,0,0,1,93,184,0,4,220,184,0,5,220,65,7,0,96,0,5,0,112,0,5,0,128,0,5,0,3,93,65,7,0,0,0,5,0,16,0,5,0,32,0,5,0,3,113,184,0,1,208,184,0,4,16,184,0,2,208,184,0,0,16,185,0,3,0,4,244,184,0,0,16,184,0,6,220,184,0,10,220,185,0,11,0,4,244,184,0,7,208,184,0,10,16,184,0,8,208,184,0,6,16,185,0,9,0,4,244,65,3,0,47,0,13,0,1,93,0,25,184,0,0,47,24,184,0,1,208,184,0,1,47,184,0,0,16,184,0,3,208,184,0,0,16,184,0,5,208,184,0,5,47,184,0,3,16,184,0,6,208,184,0,1,16,184,0,7,208,184,0,6,16,184,0,9,208,184,0,5,16,184,0,11,208,48,49,1,7,35,55,39,51,15,1,35,55,39,51,2,36,147,100,147,147,100,112,147,101,148,148,101,1,28,206,206,206,206,206,206,206,0,0,0,255,255,0,39,255,171,2,171,2,188,0,38,0,120,16,0,0,38,0,16,42,0,1,7,0,223,1,124,254,193,0,58,0,184,0,0,69,88,184,0,11,47,27,185,0,11,0,14,62,89,184,0,0,69,88,184,0,15,47,27,185,0,15,0,14,62,89,184,0,0,69,88,184,0,18,47,27,185,0,18,0,6,62,89,184,0,26,208,48,49,0,0,255,255,0,36,255,171,2,182,2,188,0,38,0,120,13,0,0,38,0,16,39,0,1,7,0,113,1,165,254,192,0,54,0,184,0,0,69,88,184,0,11,47,27,185,0,11,0,14,62,89,184,0,0,69,88,184,0,15,47,27,185,0,15,0,14,62,89,184,0,0,69,88,184,0,16,47,27,185,0,16,0,6,62,89,48,49,0,0,255,255,0,32,255,171,3,83,2,194,0,38,0,114,13,0,0,39,0,16,0,212,0,0,1,7,0,223,2,36,254,193,0,58,0,184,0,0,69,88,184,0,25,47,27,185,0,25,0,14,62,89,184,0,0,69,88,184,0,42,47,27,185,0,42,0,14,62,89,184,0,0,69,88,184,0,45,47,27,185,0,45,0,6,62,89,184,0,53,208,48,49,0,2,0,62,255,6,1,173,1,244,0,36,0,40,1,65,186,0,21,0,29,0,3,43,186,0,1,0,21,0,29,17,18,57,184,0,1,47,65,5,0,31,0,1,0,47,0,1,0,2,113,184,0,0,220,184,0,29,16,184,0,10,220,65,7,0,63,0,10,0,79,0,10,0,95,0,10,0,3,113,186,0,39,0,29,0,21,17,18,57,184,0,39,47,185,0,40,0,4,244,0,184,0,0,69,88,184,0,37,47,27,185,0,37,0,12,62,89,184,0,0,69,88,184,0,24,47,27,185,0,24,0,8,62,89,184,0,37,16,184,0,40,220,65,3,0,48,0,40,0,1,113,184,0,0,220,184,0,24,16,185,0,15,0,1,244,184,0,24,16,184,0,20,220,48,49,1,65,3,0,118,0,8,0,1,93,65,3,0,135,0,8,0,1,93,65,7,0,54,0,22,0,70,0,22,0,86,0,22,0,3,93,65,3,0,9,0,26,0,1,93,65,7,0,105,0,27,0,121,0,27,0,137,0,27,0,3,93,65,3,0,40,0,33,0,1,93,65,3,0,25,0,33,0,1,93,0,65,3,0,120,0,8,0,1,93,65,3,0,137,0,8,0,1,93,65,7,0,57,0,22,0,73,0,22,0,89,0,22,0,3,93,65,3,0,9,0,26,0,1,93,65,3,0,104,0,27,0,1,93,65,3,0,136,0,27,0,1,93,65,3,0,22,0,33,0,1,93,65,3,0,39,0,33,0,1,93,19,51,22,21,20,14,4,21,20,30,2,51,50,62,2,55,23,14,1,35,34,46,2,53,52,54,63,1,62,1,47,1,51,21,35,233,59,3,22,34,38,34,22,21,35,46,26,22,42,36,26,5,25,19,86,54,47,77,54,30,35,25,50,26,36,1,18,91,91,1,44,41,4,31,53,49,47,49,55,32,30,46,31,16,13,20,24,11,67,29,38,33,52,67,35,35,76,32,65,33,65,30,227,86,0,0,0,255,255,0,7,0,0,2,97,3,173,2,38,0,34,0,0,1,7,0,65,0,157,0,209,0,70,65,5,0,64,0,12,0,80,0,12,0,2,113,65,3,0,16,0,12,0,1,93,65,3,0,112,0,12,0,1,93,65,3,0,48,0,12,0,1,93,0,65,3,0,47,0,11,0,1,93,65,3,0,31,0,11,0,1,113,65,3,0,255,0,11,0,1,93,48,49,255,255,0,7,0,0,2,97,3,173,2,38,0,34,0,0,1,7,0,115,0,157,0,209,0,48,65,3,0,159,0,12,0,1,93,65,3,0,15,0,12,0,1,93,65,3,0,79,0,12,0,1,93,65,3,0,16,0,12,0,1,93,0,65,3,0,47,0,12,0,1,93,48,49,0,0,255,255,0,7,0,0,2,97,3,186,2,38,0,34,0,0,1,7,0,203,0,86,0,209,0,39,65,3,0,79,0,14,0,1,93,65,3,0,143,0,14,0,1,93,65,3,0,16,0,14,0,1,93,0,65,3,0,47,0,14,0,1,93,48,49,0,0,0,255,255,0,7,0,0,2,97,3,143,2,38,0,34,0,0,1,7,0,206,0,44,0,209,0,39,65,3,0,15,0,19,0,1,93,65,3,0,47,0,19,0,1,113,65,3,0,47,0,19,0,1,93,0,65,3,0,47,0,11,0,1,93,48,49,0,0,0,255,255,0,7,0,0,2,97,3,141,2,38,0,34,0,0,1,7,0,104,0,98,0,209,0,77,184,0,16,47,65,3,0,15,0,16,0,1,113,65,5,0,79,0,16,0,95,0,16,0,2,93,65,3,0,16,0,16,0,1,93,65,3,0,64,0,16,0,1,113,184,0,12,208,0,184,0,15,47,65,3,0,47,0,15,0,1,93,65,3,0,175,0,15,0,1,93,184,0,12,208,48,49,0,255,255,0,7,0,0,2,97,3,196,2,38,0,34,0,0,1,7,0,205,0,163,0,209,0,91,184,0,14,47,65,3,0,15,0,14,0,1,93,65,3,0,47,0,14,0,1,93,65,3,0,112,0,14,0,1,93,184,0,26,208,0,184,0,25,47,65,3,0,111,0,25,0,1,93,65,3,0,47,0,25,0,1,93,65,3,0,15,0,25,0,1,113,65,3,0,32,0,25,0,1,113,65,3,0,224,0,25,0,1,93,184,0,29,208,48,49,0,0,0,0,2,255,249,0,0,3,60,2,188,0,15,0,18,1,163,186,0,0,0,1,0,3,43,65,3,0,64,0,0,0,1,93,65,3,0,176,0,0,0,1,93,65,3,0,96,0,0,0,1,93,65,3,0,223,0,1,0,1,93,184,0,1,16,184,0,16,208,184,0,1,16,184,0,5,208,65,3,0,89,0,5,0,1,93,65,3,0,9,0,5,0,1,93,65,3,0,245,0,5,0,1,93,185,0,4,0,4,244,186,0,3,0,16,0,4,17,18,57,65,3,0,138,0,3,0,1,93,184,0,16,16,184,0,6,208,65,3,0,139,0,6,0,1,93,65,3,0,42,0,6,0,1,113,65,3,0,249,0,6,0,1,93,65,5,0,9,0,6,0,25,0,6,0,2,113,184,0,0,16,184,0,8,208,184,0,8,47,184,0,1,16,184,0,14,220,65,5,0,96,0,14,0,112,0,14,0,2,113,65,7,0,208,0,14,0,224,0,14,0,240,0,14,0,3,93,65,7,0,0,0,14,0,16,0,14,0,32,0,14,0,3,113,65,9,0,80,0,14,0,96,0,14,0,112,0,14,0,128,0,14,0,4,93,184,0,10,208,184,0,0,16,184,0,12,208,184,0,12,47,186,0,18,0,16,0,4,17,18,57,65,3,0,22,0,18,0,1,113,0,184,0,0,69,88,184,0,6,47,27,185,0,6,0,14,62,89,184,0,0,69,88,184,0,1,47,27,185,0,1,0,6,62,89,186,0,16,0,1,0,6,17,18,57,184,0,16,47,185,0,2,0,2,244,184,0,1,16,184,0,4,208,184,0,6,16,185,0,9,0,2,244,186,0,10,0,6,0,1,17,18,57,184,0,10,47,185,0,13,0,2,244,184,0,1,16,185,0,14,0,2,244,184,0,9,16,184,0,17,208,48,49,1,65,5,0,105,0,6,0,121,0,6,0,2,93,65,3,0,117,0,18,0,1,93,41,1,53,35,7,35,1,33,21,33,21,51,21,35,21,33,37,17,3,3,60,254,76,214,92,93,1,86,1,227,254,200,241,241,1,66,254,76,171,180,180,2,188,87,204,86,237,186,1,83,254,173,0,255,255,0,39,255,64,2,71,2,202,2,38,0,36,0,0,0,6,0,119,96,0,0,0,255,255,0,80,0,0,2,4,3,173,2,38,0,38,0,0,1,7,0,65,0,126,0,209,0,74,65,7,0,48,0,13,0,64,0,13,0,80,0,13,0,3,93,65,3,0,47,0,13,0,1,93,65,3,0,80,0,13,0,1,113,65,3,0,48,0,13,0,1,113,0,65,3,0,47,0,12,0,1,93,65,3,0,31,0,12,0,1,113,65,3,0,255,0,12,0,1,93,48,49,255,255,0,80,0,0,2,4,3,173,2,38,0,38,0,0,1,7,0,115,0,125,0,209,0,60,65,7,0,143,0,14,0,159,0,14,0,175,0,14,0,3,93,65,3,0,255,0,14,0,1,93,65,3,0,15,0,14,0,1,113,65,5,0,48,0,14,0,64,0,14,0,2,113,0,65,3,0,47,0,13,0,1,93,48,49,0,0,255,255,0,80,0,0,2,4,3,186,2,38,0,38,0,0,1,7,0,203,0,53,0,209,0,30,65,3,0,143,0,15,0,1,93,65,3,0,16,0,15,0,1,93,0,65,3,0,47,0,15,0,1,93,48,49,255,255,0,80,0,0,2,4,3,141,2,38,0,38,0,0,1,7,0,104,0,65,0,209,0,55,184,0,17,47,65,3,0,143,0,17,0,1,93,65,3,0,175,0,17,0,1,93,184,0,13,208,0,184,0,16,47,65,3,0,47,0,16,0,1,93,65,3,0,175,0,16,0,1,93,184,0,13,208,48,49,0,0,0,255,255,0,35,0,0,0,222,3,173,2,38,0,42,0,0,1,7,0,65,255,233,0,209,0,86,65,5,0,239,0,5,0,255,0,5,0,2,93,65,3,0,15,0,5,0,1,113,65,3,0,0,0,5,0,1,93,65,11,0,48,0,5,0,64,0,5,0,80,0,5,0,96,0,5,0,112,0,5,0,5,93,0,65,3,0,47,0,4,0,1,93,65,3,0,31,0,4,0,1,113,65,3,0,255,0,4,0,1,93,48,49,255,255,0,36,0,0,0,223,3,173,2,38,0,42,0,0,1,7,0,115,255,234,0,209,0,12,0,65,3,0,47,0,5,0,1,93,48,49,0,0,255,255,255,240,0,0,1,22,3,186,2,38,0,42,0,0,1,7,0,203,255,164,0,209,0,47,65,3,0,143,0,7,0,1,93,65,7,0,80,0,7,0,96,0,7,0,112,0,7,0,3,93,65,3,0,32,0,7,0,1,113,0,65,3,0,47,0,7,0,1,93,48,49,0,0,0,255,255,0,5,0,0,0,253,3,141,2,38,0,42,0,0,1,7,0,104,255,174,0,209,0,59,184,0,9,47,65,3,0,175,0,9,0,1,93,65,5,0,64,0,9,0,80,0,9,0,2,113,184,0,5,208,0,184,0,8,47,65,3,0,47,0,8,0,1,93,65,3,0,175,0,8,0,1,93,184,0,5,208,48,49,0,0,0,0,2,255,245,0,0,2,175,2,188,0,16,0,31,1,145,186,0,12,0,1,0,3,43,65,3,0,127,0,1,0,1,93,65,3,0,47,0,1,0,1,113,65,3,0,16,0,1,0,1,93,184,0,1,16,184,0,3,208,184,0,3,47,184,0,1,16,184,0,5,208,65,5,0,16,0,12,0,32,0,12,0,2,93,65,3,0,128,0,12,0,1,93,65,3,0,192,0,12,0,1,93,65,3,0,64,0,12,0,1,93,65,3,0,224,0,12,0,1,93,65,3,0,16,0,12,0,1,113,184,0,1,16,185,0,23,0,4,244,184,0,19,208,184,0,23,16,184,0,21,208,184,0,21,47,184,0,12,16,185,0,27,0,4,244,0,184,0,0,69,88,184,0,7,47,27,185,0,7,0,14,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,186,0,19,0,7,0,0,17,18,57,184,0,19,47,65,3,0,47,0,19,0,1,93,65,3,0,15,0,19,0,1,93,65,3,0,95,0,19,0,1,93,185,0,22,0,1,244,184,0,2,208,184,0,19,16,184,0,5,208,184,0,7,16,185,0,17,0,2,244,184,0,0,16,185,0,24,0,2,244,48,49,1,65,3,0,86,0,9,0,1,93,65,3,0,103,0,9,0,1,93,65,3,0,86,0,10,0,1,93,65,3,0,119,0,10,0,1,93,65,3,0,87,0,14,0,1,93,65,3,0,86,0,15,0,1,93,65,5,0,103,0,15,0,119,0,15,0,2,93,0,65,5,0,86,0,9,0,102,0,9,0,2,93,65,3,0,87,0,10,0,1,93,65,3,0,119,0,10,0,1,93,65,3,0,88,0,14,0,1,93,65,3,0,120,0,15,0,1,93,65,3,0,105,0,15,0,1,93,65,3,0,90,0,15,0,1,93,41,1,17,35,53,51,17,33,50,30,2,21,20,14,2,3,35,21,51,21,35,21,51,50,54,53,52,46,2,1,86,255,0,97,97,1,0,76,127,92,50,50,90,127,78,166,133,133,166,118,125,32,61,91,1,57,64,1,67,49,90,130,81,81,129,91,49,2,102,237,64,226,140,123,61,98,68,37,0,255,255,0,80,0,0,2,112,3,143,2,38,0,47,0,0,1,7,0,206,0,87,0,209,0,25,65,5,0,144,0,18,0,160,0,18,0,2,93,0,65,3,0,47,0,10,0,1,93,48,49,0,255,255,0,39,255,242,2,217,3,173,2,38,0,48,0,0,1,7,0,65,0,233,0,209,0,30,0,65,3,0,47,0,38,0,1,93,65,3,0,31,0,38,0,1,113,65,3,0,255,0,38,0,1,93,48,49,255,255,0,39,255,242,2,217,3,173,2,38,0,48,0,0,1,7,0,115,0,232,0,209,0,48,65,3,0,239,0,40,0,1,93,65,3,0,15,0,40,0,1,93,65,3,0,175,0,40,0,1,93,65,3,0,32,0,40,0,1,93,0,65,3,0,47,0,39,0,1,93,48,49,0,0,255,255,0,39,255,242,2,217,3,186,2,38,0,48,0,0,1,7,0,203,0,161,0,209,0,34,65,3,0,15,0,41,0,1,93,65,5,0,16,0,41,0,32,0,41,0,2,93,0,65,3,0,47,0,41,0,1,93,48,49,255,255,0,39,255,242,2,217,3,143,2,38,0,48,0,0,1,7,0,206,0,119,0,209,0,30,65,3,0,15,0,46,0,1,93,65,3,0,63,0,46,0,1,93,0,65,3,0,47,0,38,0,1,93,48,49,255,255,0,39,255,242,2,217,3,141,2,38,0,48,0,0,1,7,0,104,0,173,0,209,0,59,184,0,43,47,65,3,0,95,0,43,0,1,93,65,5,0,16,0,43,0,32,0,43,0,2,93,184,0,39,208,0,184,0,42,47,65,3,0,47,0,42,0,1,93,65,3,0,175,0,42,0,1,93,184,0,39,208,48,49,0,0,0,0,1,0,61,0,119,1,122,1,179,0,11,0,109,184,0,4,47,65,3,0,239,0,4,0,1,93,65,5,0,0,0,4,0,16,0,4,0,2,93,184,0,0,220,186,0,5,0,4,0,0,17,18,57,184,0,4,16,184,0,6,208,184,0,0,16,184,0,10,208,186,0,11,0,0,0,4,17,18,57,0,184,0,3,47,184,0,1,208,184,0,3,16,184,0,7,220,186,0,2,0,3,0,7,17,18,57,186,0,8,0,7,0,3,17,18,57,184,0,9,208,48,49,37,7,39,7,39,55,39,55,23,55,23,7,1,122,36,123,122,36,123,123,36,122,123,36,124,155,36,123,123,36,122,122,36,123,123,36,122,0,3,0,39,255,226,2,217,2,204,0,23,0,33,0,43,3,133,186,0,19,0,7,0,3,43,65,3,0,15,0,7,0,1,93,65,5,0,79,0,7,0,95,0,7,0,2,93,65,3,0,32,0,19,0,1,93,65,5,0,176,0,19,0,192,0,19,0,2,93,65,5,0,224,0,19,0,240,0,19,0,2,93,65,5,0,112,0,19,0,128,0,19,0,2,93,65,3,0,32,0,19,0,1,113,186,0,2,0,7,0,19,17,18,57,184,0,2,16,184,0,3,208,186,0,5,0,7,0,19,17,18,57,65,3,0,121,0,5,0,1,93,184,0,5,16,184,0,4,208,65,3,0,25,0,4,0,1,93,186,0,14,0,19,0,7,17,18,57,184,0,14,16,184,0,15,208,65,3,0,138,0,15,0,1,93,186,0,17,0,19,0,7,17,18,57,65,3,0,118,0,17,0,1,93,184,0,17,16,184,0,16,208,65,3,0,57,0,16,0,1,93,184,0,19,16,185,0,32,0,4,244,184,0,7,16,185,0,39,0,4,244,186,0,24,0,32,0,39,17,18,57,186,0,25,0,39,0,32,17,18,57,65,5,0,54,0,25,0,70,0,25,0,2,93,65,7,0,6,0,25,0,22,0,25,0,38,0,25,0,3,113,65,5,0,117,0,25,0,133,0,25,0,2,93,186,0,41,0,39,0,32,17,18,57,186,0,42,0,32,0,39,17,18,57,65,3,0,122,0,42,0,1,93,65,3,0,139,0,42,0,1,93,65,5,0,57,0,42,0,73,0,42,0,2,93,65,7,0,9,0,42,0,25,0,42,0,41,0,42,0,3,113,65,3,0,15,0,44,0,1,93,0,184,0,0,69,88,184,0,12,47,27,185,0,12,0,14,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,186,0,2,0,0,0,12,17,18,57,184,0,3,208,184,0,3,47,186,0,5,0,0,0,12,17,18,57,186,0,14,0,12,0,0,17,18,57,65,7,0,6,0,14,0,22,0,14,0,38,0,14,0,3,113,184,0,12,16,184,0,15,208,184,0,15,47,186,0,17,0,12,0,0,17,18,57,184,0,12,16,185,0,34,0,2,244,184,0,0,16,185,0,27,0,2,244,186,0,24,0,34,0,27,17,18,57,65,3,0,138,0,24,0,1,93,65,7,0,9,0,24,0,25,0,24,0,41,0,24,0,3,113,65,3,0,121,0,24,0,1,93,186,0,25,0,27,0,34,17,18,57,186,0,41,0,27,0,34,17,18,57,65,7,0,6,0,41,0,22,0,41,0,38,0,41,0,3,113,65,5,0,118,0,41,0,134,0,41,0,2,93,186,0,42,0,34,0,27,17,18,57,48,49,1,65,3,0,105,0,4,0,1,93,65,3,0,137,0,4,0,1,93,65,3,0,90,0,4,0,1,93,65,3,0,89,0,9,0,1,93,65,3,0,121,0,9,0,1,93,65,5,0,88,0,10,0,104,0,10,0,2,93,65,3,0,137,0,14,0,1,93,65,3,0,86,0,17,0,1,93,65,5,0,86,0,21,0,102,0,21,0,2,93,65,3,0,117,0,22,0,1,93,65,3,0,86,0,22,0,1,93,65,3,0,103,0,24,0,1,93,65,3,0,138,0,30,0,1,93,65,3,0,133,0,37,0,1,93,65,3,0,105,0,41,0,1,93,65,3,0,89,0,42,0,1,93,0,65,3,0,90,0,2,0,1,93,65,3,0,85,0,9,0,1,93,65,3,0,118,0,9,0,1,93,65,3,0,101,0,10,0,1,93,65,3,0,86,0,10,0,1,93,65,3,0,86,0,14,0,1,93,65,3,0,135,0,14,0,1,93,65,3,0,87,0,17,0,1,93,65,3,0,88,0,21,0,1,93,65,3,0,105,0,21,0,1,93,65,3,0,90,0,22,0,1,93,65,3,0,122,0,22,0,1,93,65,3,0,107,0,24,0,1,93,65,3,0,136,0,37,0,1,93,65,3,0,101,0,41,0,1,93,65,3,0,87,0,42,0,1,93,5,34,39,7,35,55,38,53,52,62,2,51,50,23,55,51,7,22,21,20,14,2,19,1,22,51,50,62,2,53,52,39,34,14,2,21,20,23,1,38,1,127,91,85,42,93,73,106,52,91,127,75,86,86,31,92,61,111,51,91,128,104,254,209,69,55,58,89,60,30,238,57,88,60,31,55,1,45,66,12,43,61,105,113,162,83,134,95,52,42,44,89,111,167,81,133,95,52,2,48,254,69,29,41,74,101,60,126,147,41,74,101,60,98,95,1,185,28,0,0,0,255,255,0,72,255,242,2,140,3,173,0,38,0,54,0,0,1,7,0,65,0,211,0,209,0,56,65,3,0,47,0,23,0,1,93,65,7,0,48,0,23,0,64,0,23,0,80,0,23,0,3,93,0,65,3,0,47,0,22,0,1,93,65,3,0,31,0,22,0,1,113,65,3,0,255,0,22,0,1,93,48,49,0,0,255,255,0,72,255,242,2,140,3,173,0,38,0,54,0,0,1,7,0,115,0,211,0,209,0,47,65,3,0,15,0,23,0,1,93,65,7,0,175,0,24,0,191,0,24,0,207,0,24,0,3,93,65,3,0,15,0,24,0,1,113,0,65,3,0,47,0,22,0,1,93,48,49,0,0,0,255,255,0,72,255,242,2,140,3,186,0,38,0,54,0,0,1,7,0,203,0,139,0,209,0,39,65,3,0,15,0,25,0,1,93,65,3,0,143,0,25,0,1,93,65,3,0,32,0,25,0,1,113,0,65,3,0,47,0,25,0,1,93,48,49,0,0,0,255,255,0,72,255,242,2,140,3,141,0,38,0,54,0,0,1,7,0,104,0,152,0,209,0,64,184,0,27,47,65,3,0,15,0,27,0,1,93,65,3,0,16,0,27,0,1,93,65,3,0,80,0,27,0,1,113,184,0,23,208,0,184,0,26,47,65,3,0,47,0,26,0,1,93,65,3,0,175,0,26,0,1,93,184,0,23,208,48,49,0,0,255,255,255,253,0,0,2,57,3,173,2,38,0,58,0,0,1,7,0,115,0,144,0,209,0,52,65,5,0,239,0,11,0,255,0,11,0,2,93,65,3,0,15,0,11,0,1,93,65,3,0,175,0,11,0,1,93,65,3,0,32,0,11,0,1,93,0,65,3,0,47,0,10,0,1,93,48,49,0,0,0,2,0,80,0,0,2,36,2,188,0,16,0,27,1,80,186,0,11,0,2,0,3,43,65,5,0,0,0,2,0,16,0,2,0,2,93,65,3,0,143,0,2,0,1,93,65,3,0,144,0,2,0,1,93,65,3,0,112,0,2,0,1,93,184,0,2,16,185,0,1,0,4,244,184,0,18,208,184,0,5,208,65,3,0,192,0,11,0,1,93,65,3,0,80,0,11,0,1,93,65,3,0,112,0,11,0,1,93,65,5,0,0,0,11,0,16,0,11,0,2,93,65,3,0,224,0,11,0,1,93,65,3,0,32,0,11,0,1,113,184,0,11,16,185,0,22,0,4,244,0,184,0,0,69,88,184,0,4,47,27,185,0,4,0,14,62,89,184,0,0,69,88,184,0,1,47,27,185,0,1,0,6,62,89,186,0,0,0,4,0,1,17,18,57,184,0,0,47,65,7,0,15,0,0,0,31,0,0,0,47,0,0,0,3,113,65,3,0,143,0,0,0,1,93,65,3,0,47,0,0,0,1,93,186,0,5,0,4,0,1,17,18,57,184,0,5,47,185,0,17,0,2,244,184,0,0,16,185,0,18,0,2,244,48,49,1,65,5,0,118,0,8,0,134,0,8,0,2,93,65,7,0,102,0,9,0,118,0,9,0,134,0,9,0,3,93,65,3,0,7,0,9,0,1,93,0,65,3,0,116,0,8,0,1,93,65,3,0,133,0,8,0,1,93,65,3,0,5,0,9,0,1,93,65,3,0,101,0,9,0,1,93,65,3,0,135,0,9,0,1,93,55,21,35,17,51,21,51,50,30,2,21,20,14,2,35,3,17,51,50,54,53,52,46,2,35,180,100,100,124,49,88,67,40,41,64,76,35,152,134,73,62,16,38,63,46,125,125,2,188,120,15,47,86,70,68,91,55,23,1,114,254,227,77,71,37,53,32,15,0,1,0,16,255,120,2,39,2,238,0,62,2,25,186,0,58,0,31,0,3,43,65,3,0,0,0,31,0,1,93,65,3,0,31,0,31,0,1,113,65,3,0,80,0,31,0,1,93,65,3,0,32,0,31,0,1,93,184,0,31,16,185,0,30,0,4,244,65,3,0,32,0,58,0,1,93,65,3,0,160,0,58,0,1,93,65,3,0,80,0,58,0,1,113,65,11,0,64,0,58,0,80,0,58,0,96,0,58,0,112,0,58,0,128,0,58,0,5,93,65,3,0,0,0,58,0,1,93,65,3,0,48,0,58,0,1,113,184,0,58,16,185,0,9,0,4,244,186,0,3,0,30,0,9,17,18,57,184,0,3,47,186,0,16,0,30,0,9,17,18,57,184,0,16,47,186,0,46,0,58,0,31,17,18,57,184,0,46,47,185,0,21,0,4,244,184,0,31,16,184,0,35,208,184,0,33,220,184,0,16,16,185,0,51,0,4,244,0,184,0,30,47,184,0,0,69,88,184,0,41,47,27,185,0,41,0,18,62,89,184,0,0,69,88,184,0,34,47,27,185,0,34,0,12,62,89,184,0,0,69,88,184,0,3,47,27,185,0,3,0,6,62,89,185,0,4,0,1,244,186,0,16,0,41,0,3,17,18,57,25,184,0,16,47,24,184,0,41,16,185,0,26,0,2,244,184,0,34,16,185,0,33,0,1,244,184,0,16,16,184,0,51,208,48,49,1,65,3,0,72,0,12,0,1,93,65,3,0,73,0,19,0,1,93,65,3,0,138,0,19,0,1,93,65,3,0,123,0,19,0,1,93,65,3,0,9,0,38,0,1,93,65,3,0,7,0,43,0,1,93,65,3,0,39,0,43,0,1,93,65,5,0,6,0,44,0,22,0,44,0,2,93,65,3,0,54,0,49,0,1,93,65,7,0,87,0,55,0,103,0,55,0,119,0,55,0,3,93,65,3,0,7,0,60,0,1,93,65,3,0,6,0,61,0,1,93,0,65,3,0,119,0,19,0,1,93,65,3,0,5,0,38,0,1,93,65,3,0,6,0,43,0,1,93,65,3,0,38,0,43,0,1,93,65,5,0,7,0,44,0,23,0,44,0,2,93,65,3,0,57,0,49,0,1,93,65,3,0,101,0,55,0,1,93,65,3,0,86,0,55,0,1,93,65,3,0,119,0,56,0,1,93,65,3,0,8,0,60,0,1,93,65,3,0,9,0,61,0,1,93,5,34,38,39,53,50,62,2,53,52,46,4,53,52,62,2,53,52,46,2,35,34,6,21,17,35,17,35,55,51,53,52,62,2,51,50,30,2,21,20,14,2,21,20,30,4,21,20,14,2,1,72,18,20,12,42,68,46,25,25,38,44,38,25,33,41,33,16,27,36,20,54,52,90,85,12,73,31,54,72,41,35,68,53,32,31,36,31,24,36,42,36,24,38,62,81,10,2,1,77,3,13,29,27,28,47,41,35,33,30,15,18,42,51,63,39,26,33,20,7,51,71,253,84,2,44,70,87,42,64,44,23,18,39,62,45,45,69,50,34,10,8,23,29,38,47,56,34,42,58,36,17,0,255,255,0,24,255,246,1,216,2,220,2,38,0,66,0,0,1,6,0,65,89,0,0,29,65,3,0,0,0,45,0,1,93,65,3,0,80,0,45,0,1,113,65,3,0,160,0,45,0,1,93,48,49,0,0,0,255,255,0,24,255,246,1,216,2,220,2,38,0,66,0,0,1,6,0,115,88,0,0,29,65,3,0,127,0,46,0,1,93,65,3,0,255,0,46,0,1,93,65,3,0,80,0,46,0,1,113,48,49,0,0,0,255,255,0,24,255,246,1,216,2,233,2,38,0,66,0,0,1,6,0,203,17,0,0,24,65,5,0,127,0,47,0,143,0,47,0,2,93,65,3,0,223,0,47,0,1,93,48,49,255,255,0,24,255,246,1,216,2,190,2,38,0,66,0,0,1,6,0,206,228,0,0,29,65,3,0,255,0,52,0,1,93,65,3,0,32,0,52,0,1,93,65,3,0,64,0,52,0,1,93,48,49,0,0,0,255,255,0,24,255,246,1,216,2,188,2,38,0,66,0,0,1,6,0,104,29,0,0,62,184,0,49,47,65,3,0,160,0,49,0,1,93,65,7,0,95,0,49,0,111,0,49,0,127,0,49,0,3,93,65,3,0,64,0,49,0,1,113,65,7,0,192,0,49,0,208,0,49,0,224,0,49,0,3,93,184,0,45,208,48,49,0,0,255,255,0,24,255,246,1,216,2,243,2,38,0,66,0,0,1,6,0,205,95,0,0,37,184,0,47,47,65,3,0,0,0,47,0,1,93,65,3,0,160,0,47,0,1,93,65,3,0,64,0,47,0,1,93,184,0,59,208,48,49,0,0,0,0,3,0,22,255,242,3,0,1,244,0,45,0,50,0,65,3,170,186,0,43,0,20,0,3,43,65,3,0,255,0,20,0,1,93,65,3,0,15,0,20,0,1,113,65,5,0,63,0,20,0,79,0,20,0,2,93,65,3,0,79,0,20,0,1,113,65,5,0,191,0,20,0,207,0,20,0,2,93,65,7,0,111,0,20,0,127,0,20,0,143,0,20,0,3,93,65,3,0,160,0,43,0,1,93,65,3,0,48,0,43,0,1,113,65,3,0,224,0,43,0,1,93,65,5,0,64,0,43,0,80,0,43,0,2,93,65,3,0,0,0,43,0,1,93,186,0,63,0,20,0,43,17,18,57,184,0,63,47,185,0,1,0,4,244,186,0,10,0,63,0,43,17,18,57,184,0,10,47,186,0,14,0,1,0,63,17,18,57,184,0,63,16,184,0,22,208,186,0,28,0,20,0,1,17,18,57,184,0,28,47,186,0,35,0,63,0,1,17,18,57,184,0,1,16,184,0,48,208,184,0,43,16,185,0,49,0,4,244,184,0,20,16,185,0,56,0,4,244,0,184,0,0,69,88,184,0,30,47,27,185,0,30,0,12,62,89,184,0,0,69,88,184,0,40,47,27,185,0,40,0,12,62,89,184,0,0,69,88,184,0,12,47,27,185,0,12,0,6,62,89,184,0,0,69,88,184,0,17,47,27,185,0,17,0,6,62,89,186,0,1,0,40,0,12,17,18,57,184,0,1,47,65,5,0,144,0,1,0,160,0,1,0,2,93,65,5,0,16,0,1,0,32,0,1,0,2,93,184,0,12,16,185,0,4,0,1,244,184,0,12,16,184,0,9,220,186,0,14,0,12,0,40,17,18,57,186,0,22,0,30,0,17,17,18,57,184,0,22,47,65,3,0,0,0,22,0,1,93,184,0,30,16,185,0,25,0,2,244,184,0,30,16,184,0,27,220,186,0,35,0,40,0,12,17,18,57,65,3,0,135,0,35,0,1,93,184,0,40,16,185,0,46,0,2,244,184,0,1,16,184,0,48,220,65,15,0,159,0,48,0,175,0,48,0,191,0,48,0,207,0,48,0,223,0,48,0,239,0,48,0,255,0,48,0,7,93,184,0,22,16,184,0,51,220,65,15,0,144,0,51,0,160,0,51,0,176,0,51,0,192,0,51,0,208,0,51,0,224,0,51,0,240,0,51,0,7,93,184,0,17,16,185,0,58,0,1,244,48,49,1,65,5,0,52,0,3,0,68,0,3,0,2,93,65,5,0,89,0,13,0,105,0,13,0,2,93,65,5,0,85,0,15,0,101,0,15,0,2,93,65,3,0,72,0,18,0,1,93,65,3,0,26,0,19,0,1,93,65,3,0,43,0,19,0,1,93,65,3,0,120,0,21,0,1,93,65,3,0,137,0,21,0,1,93,65,3,0,120,0,23,0,1,93,65,9,0,87,0,28,0,103,0,28,0,119,0,28,0,135,0,28,0,4,93,65,3,0,134,0,33,0,1,93,65,3,0,135,0,41,0,1,93,65,3,0,133,0,42,0,1,93,65,3,0,101,0,54,0,1,93,65,3,0,86,0,54,0,1,93,0,65,3,0,72,0,3,0,1,93,65,9,0,91,0,10,0,107,0,10,0,123,0,10,0,139,0,10,0,4,93,65,9,0,91,0,11,0,107,0,11,0,123,0,11,0,139,0,11,0,4,93,65,3,0,89,0,13,0,1,93,65,3,0,106,0,13,0,1,93,65,3,0,25,0,18,0,1,93,65,3,0,105,0,18,0,1,93,65,7,0,58,0,18,0,74,0,18,0,90,0,18,0,3,93,65,3,0,134,0,21,0,1,93,65,3,0,119,0,21,0,1,93,65,3,0,88,0,23,0,1,93,65,3,0,121,0,23,0,1,93,65,3,0,106,0,23,0,1,93,65,9,0,84,0,28,0,100,0,28,0,116,0,28,0,132,0,28,0,4,93,65,9,0,86,0,29,0,102,0,29,0,118,0,29,0,134,0,29,0,4,93,65,3,0,134,0,33,0,1,93,65,3,0,101,0,35,0,1,93,65,3,0,101,0,37,0,1,93,65,3,0,133,0,41,0,1,93,65,3,0,135,0,42,0,1,93,65,3,0,104,0,54,0,1,93,37,33,20,22,51,50,62,2,55,23,6,35,34,39,14,1,35,34,38,53,52,37,46,1,35,34,7,39,54,51,50,30,2,23,62,3,51,50,22,21,20,6,39,34,7,51,52,5,34,14,2,21,20,51,50,62,2,53,52,38,2,252,254,176,90,75,18,26,29,35,26,17,87,76,148,53,26,110,72,75,75,1,45,9,53,56,53,69,8,84,72,20,50,47,36,6,10,37,49,59,32,88,103,2,193,107,30,246,254,161,36,76,64,41,78,28,51,39,23,1,245,90,93,3,9,14,11,69,40,113,57,60,69,63,174,15,61,52,29,70,39,11,27,46,36,31,45,30,14,104,96,11,28,159,113,113,175,12,29,45,33,64,17,34,51,34,14,24,255,255,0,33,255,64,1,171,1,244,2,38,0,68,0,0,1,6,0,119,48,0,0,19,65,7,0,32,0,28,0,48,0,28,0,64,0,28,0,3,93,48,49,0,255,255,0,31,255,246,1,226,2,220,2,38,0,70,0,0,1,6,0,65,103,0,0,24,65,5,0,239,0,32,0,255,0,32,0,2,93,65,3,0,80,0,32,0,1,113,48,49,255,255,0,31,255,246,1,226,2,220,2,38,0,70,0,0,1,6,0,115,104,0,0,24,65,3,0,79,0,33,0,1,93,65,5,0,223,0,33,0,239,0,33,0,2,93,48,49,255,255,0,31,255,246,1,226,2,233,2,38,0,70,0,0,1,6,0,203,32,0,0,33,65,3,0,15,0,34,0,1,93,65,5,0,63,0,34,0,79,0,34,0,2,93,65,3,0,144,0,34,0,1,93,48,49,0,0,0,255,255,0,31,255,246,1,226,2,188,2,38,0,70,0,0,1,6,0,104,44,0,0,19,184,0,36,47,65,3,0,47,0,36,0,1,113,184,0,32,208,48,49,0,255,255,0,13,0,0,0,200,2,220,2,38,0,193,0,0,1,6,0,65,211,0,0,56,65,3,0,0,0,5,0,1,93,65,3,0,255,0,5,0,1,93,65,3,0,143,0,5,0,1,93,65,3,0,223,0,5,0,1,93,65,3,0,80,0,5,0,1,113,65,3,0,32,0,5,0,1,93,48,49,255,255,0,14,0,0,0,201,2,220,2,38,0,193,0,0,1,6,0,115,212,0,0,55,65,3,0,223,0,6,0,1,93,65,5,0,63,0,6,0,79,0,6,0,2,93,65,3,0,255,0,6,0,1,93,65,5,0,143,0,6,0,159,0,6,0,2,93,65,3,0,32,0,6,0,1,93,48,49,0,255,255,255,217,0,0,0,255,2,233,2,38,0,193,0,0,1,6,0,203,141,0,0,29,65,3,0,223,0,7,0,1,93,65,3,0,32,0,7,0,1,93,65,3,0,143,0,8,0,1,93,48,49,0,0,0,255,255,255,239,0,0,0,231,2,188,2,38,0,193,0,0,1,6,0,104,152,0,0,55,184,0,9,47,65,3,0,15,0,9,0,1,113,65,3,0,143,0,9,0,1,93,65,3,0,63,0,9,0,1,113,65,3,0,32,0,9,0,1,93,65,3,0,224,0,9,0,1,93,184,0,5,208,48,49,0,0,2,0,28,255,244,1,228,2,198,0,41,0,57,2,47,186,0,37,0,5,0,3,43,65,3,0,207,0,5,0,1,93,65,3,0,79,0,5,0,1,93,65,3,0,143,0,5,0,1,93,65,3,0,111,0,5,0,1,93,65,3,0,112,0,37,0,1,93,65,3,0,16,0,37,0,1,93,65,3,0,16,0,37,0,1,113,65,3,0,80,0,37,0,1,93,184,0,37,16,185,0,55,0,4,244,184,0,12,208,186,0,24,0,5,0,37,17,18,57,184,0,24,47,186,0,22,0,24,0,12,17,18,57,186,0,32,0,37,0,24,17,18,57,65,3,0,54,0,32,0,1,93,186,0,17,0,22,0,32,17,18,57,184,0,22,16,184,0,20,208,184,0,20,47,186,0,27,0,22,0,32,17,18,57,65,3,0,55,0,27,0,1,93,65,3,0,86,0,27,0,1,93,65,3,0,69,0,27,0,1,93,184,0,32,16,184,0,30,208,184,0,30,47,184,0,5,16,185,0,47,0,4,244,0,184,0,0,69,88,184,0,25,47,27,185,0,25,0,14,62,89,184,0,0,69,88,184,0,29,47,27,185,0,29,0,14,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,65,3,0,200,0,5,0,1,93,184,0,10,220,186,0,17,0,10,0,25,17,18,57,184,0,17,16,184,0,19,208,184,0,19,47,186,0,27,0,25,0,10,17,18,57,65,3,0,55,0,27,0,1,93,65,5,0,70,0,27,0,86,0,27,0,2,93,186,0,22,0,27,0,17,17,18,57,184,0,25,16,184,0,24,220,186,0,32,0,17,0,27,17,18,57,184,0,10,16,185,0,42,0,2,244,184,0,0,16,185,0,52,0,2,244,48,49,1,65,3,0,121,0,2,0,1,93,65,3,0,107,0,2,0,1,93,65,5,0,105,0,8,0,121,0,8,0,2,93,65,3,0,103,0,11,0,1,93,65,3,0,120,0,11,0,1,93,65,3,0,136,0,17,0,1,93,65,3,0,135,0,18,0,1,93,65,3,0,119,0,40,0,1,93,0,65,3,0,122,0,2,0,1,93,65,3,0,107,0,2,0,1,93,65,5,0,102,0,8,0,118,0,8,0,2,93,65,3,0,115,0,11,0,1,93,65,3,0,100,0,11,0,1,93,65,3,0,133,0,11,0,1,93,65,3,0,140,0,17,0,1,93,65,3,0,138,0,18,0,1,93,65,3,0,121,0,40,0,1,93,65,3,0,106,0,40,0,1,93,23,34,46,2,53,52,62,2,51,50,23,46,3,39,6,7,39,54,55,38,35,55,50,23,54,55,23,6,7,30,3,21,20,14,2,3,34,14,2,21,20,30,2,51,50,54,53,52,38,249,48,81,59,33,28,53,79,51,86,49,4,16,23,28,15,77,64,30,65,63,60,61,32,72,77,31,28,46,23,46,32,53,37,21,43,68,84,35,29,46,33,18,18,33,46,28,54,66,65,12,32,57,78,46,42,81,63,39,55,24,55,53,45,12,53,9,55,9,43,54,42,55,28,36,12,33,51,29,81,94,102,51,77,104,62,26,1,99,21,37,48,27,30,50,38,21,77,60,60,75,0,0,0,255,255,0,61,0,0,1,247,2,190,2,38,0,79,0,0,1,6,0,206,15,0,0,11,65,3,0,255,0,25,0,1,93,48,49,0,255,255,0,32,255,246,2,6,2,220,2,38,0,80,0,0,1,6,0,65,123,0,0,24,65,3,0,47,0,33,0,1,113,65,5,0,64,0,33,0,80,0,33,0,2,93,48,49,255,255,0,32,255,246,2,6,2,220,2,38,0,80,0,0,1,6,0,115,123,0,0,51,65,3,0,255,0,34,0,1,93,65,3,0,15,0,34,0,1,113,65,3,0,63,0,34,0,1,93,65,3,0,191,0,34,0,1,93,65,5,0,143,0,34,0,159,0,34,0,2,93,48,49,0,255,255,0,32,255,246,2,6,2,233,2,38,0,80,0,0,1,6,0,203,52,0,0,29,65,3,0,15,0,35,0,1,93,65,3,0,32,0,35,0,1,93,65,3,0,160,0,35,0,1,93,48,49,0,0,0,255,255,0,32,255,246,2,6,2,190,2,38,0,80,0,0,1,6,0,206,10,0,0,24,65,5,0,15,0,40,0,31,0,40,0,2,93,65,3,0,47,0,40,0,1,113,48,49,255,255,0,32,255,246,2,6,2,188,2,38,0,80,0,0,1,6,0,104,64,0,0,28,184,0,37,47,65,3,0,143,0,37,0,1,93,65,3,0,32,0,37,0,1,93,184,0,33,208,48,49,0,3,0,66,0,20,2,14,2,22,0,3,0,7,0,11,0,76,184,0,10,47,184,0,11,220,184,0,0,208,184,0,10,16,184,0,1,208,184,0,11,16,184,0,4,220,184,0,10,16,184,0,5,220,0,184,0,5,47,184,0,6,220,184,0,2,220,184,0,1,220,184,0,5,16,184,0,9,220,65,3,0,191,0,9,0,1,93,184,0,10,220,48,49,1,35,53,51,19,33,53,33,3,35,53,51,1,80,89,89,190,254,52,1,204,190,89,89,1,184,94,254,223,74,254,213,94,0,0,3,0,33,255,216,2,27,2,17,0,23,0,36,0,46,2,114,186,0,19,0,7,0,3,43,65,3,0,143,0,7,0,1,93,65,3,0,31,0,7,0,1,93,65,3,0,175,0,7,0,1,93,65,3,0,111,0,7,0,1,93,65,5,0,63,0,7,0,79,0,7,0,2,93,65,3,0,80,0,19,0,1,93,65,3,0,144,0,19,0,1,93,65,3,0,224,0,19,0,1,93,65,3,0,32,0,19,0,1,113,65,3,0,0,0,19,0,1,113,65,3,0,192,0,19,0,1,93,65,3,0,112,0,19,0,1,93,65,3,0,32,0,19,0,1,93,65,3,0,0,0,19,0,1,93,186,0,2,0,7,0,19,17,18,57,186,0,5,0,7,0,19,17,18,57,186,0,14,0,19,0,7,17,18,57,186,0,17,0,19,0,7,17,18,57,184,0,19,16,185,0,32,0,4,244,184,0,7,16,185,0,42,0,4,244,186,0,24,0,32,0,42,17,18,57,186,0,25,0,42,0,32,17,18,57,65,3,0,102,0,25,0,1,93,65,3,0,134,0,25,0,1,93,186,0,44,0,42,0,32,17,18,57,186,0,45,0,32,0,42,17,18,57,65,3,0,105,0,45,0,1,93,65,3,0,137,0,45,0,1,93,65,3,0,128,0,48,0,1,93,0,184,0,0,69,88,184,0,12,47,27,185,0,12,0,12,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,186,0,2,0,0,0,12,17,18,57,184,0,3,208,184,0,3,47,186,0,5,0,0,0,12,17,18,57,186,0,14,0,12,0,0,17,18,57,184,0,12,16,184,0,15,208,184,0,15,47,65,3,0,144,0,15,0,1,93,186,0,17,0,12,0,0,17,18,57,184,0,12,16,185,0,37,0,1,244,184,0,0,16,185,0,27,0,1,244,186,0,24,0,37,0,27,17,18,57,65,3,0,137,0,24,0,1,93,65,3,0,105,0,24,0,1,93,65,3,0,38,0,24,0,1,93,186,0,25,0,27,0,37,17,18,57,186,0,44,0,27,0,37,17,18,57,65,3,0,102,0,44,0,1,93,65,3,0,134,0,44,0,1,93,186,0,45,0,37,0,27,17,18,57,48,49,1,65,3,0,92,0,6,0,1,93,65,3,0,90,0,10,0,1,93,65,3,0,86,0,17,0,1,93,65,3,0,85,0,22,0,1,93,65,3,0,73,0,24,0,1,93,65,3,0,70,0,25,0,1,93,65,3,0,87,0,25,0,1,93,65,3,0,74,0,30,0,1,93,65,3,0,69,0,39,0,1,93,65,5,0,73,0,45,0,89,0,45,0,2,93,0,65,3,0,85,0,10,0,1,93,65,3,0,86,0,17,0,1,93,65,3,0,91,0,22,0,1,93,65,3,0,87,0,25,0,1,93,5,34,39,7,35,55,38,53,52,62,2,51,50,23,55,51,7,22,21,20,14,2,19,3,22,51,50,62,2,53,52,46,2,39,34,14,2,21,20,23,19,38,1,30,33,53,19,71,32,109,35,66,93,58,36,48,19,74,34,111,35,66,94,51,163,42,13,37,58,39,21,6,12,17,123,36,57,40,21,46,161,38,13,11,38,66,81,137,54,94,69,40,12,40,66,84,136,54,94,69,39,1,150,254,182,6,29,50,68,39,21,46,41,33,47,28,50,69,41,68,80,1,73,7,255,255,0,56,255,246,1,207,2,220,2,38,0,86,0,0,1,6,0,65,127,0,0,37,65,3,0,255,0,17,0,1,93,65,7,0,48,0,17,0,64,0,17,0,80,0,17,0,3,93,65,3,0,176,0,17,0,1,93,48,49,0,0,0,255,255,0,56,255,246,1,207,2,220,2,38,0,86,0,0,1,6,0,115,127,0,0,59,65,3,0,255,0,17,0,1,93,65,3,0,15,0,17,0,1,113,65,5,0,15,0,17,0,31,0,17,0,2,93,65,3,0,223,0,17,0,1,93,65,7,0,143,0,17,0,159,0,17,0,175,0,17,0,3,93,48,49,0,255,255,0,56,255,246,1,207,2,233,2,38,0,86,0,0,1,6,0,203,56,0,0,56,65,3,0,32,0,19,0,1,113,65,3,0,223,0,19,0,1,93,65,3,0,143,0,19,0,1,93,65,3,0,32,0,19,0,1,93,65,3,0,144,0,19,0,1,93,65,3,0,80,0,19,0,1,93,48,49,255,255,0,56,255,246,1,207,2,188,2,38,0,86,0,0,1,6,0,104,68,0,0,46,184,0,21,47,65,3,0,32,0,21,0,1,93,65,3,0,143,0,21,0,1,93,65,3,0,0,0,21,0,1,113,65,3,0,224,0,21,0,1,93,184,0,17,208,48,49,0,0,255,255,0,7,255,14,1,242,2,220,2,38,0,90,0,0,1,6,0,115,101,0,0,11,65,3,0,79,0,9,0,1,93,48,49,0,0,2,0,60,255,15,2,36,2,238,0,18,0,30,1,158,186,0,14,0,4,0,3,43,65,3,0,255,0,4,0,1,93,65,3,0,223,0,4,0,1,93,65,3,0,31,0,4,0,1,113,65,3,0,0,0,4,0,1,93,65,3,0,32,0,4,0,1,93,184,0,4,16,185,0,3,0,4,244,184,0,6,208,65,17,0,0,0,14,0,16,0,14,0,32,0,14,0,48,0,14,0,64,0,14,0,80,0,14,0,96,0,14,0,112,0,14,0,8,93,65,3,0,0,0,14,0,1,113,65,3,0,144,0,14,0,1,93,65,5,0,32,0,14,0,48,0,14,0,2,113,65,3,0,80,0,14,0,1,113,184,0,3,16,184,0,19,208,184,0,14,16,185,0,25,0,4,244,65,3,0,64,0,32,0,1,93,65,3,0,96,0,32,0,1,93,65,3,0,128,0,32,0,1,93,0,184,0,0,69,88,184,0,6,47,27,185,0,6,0,18,62,89,184,0,0,69,88,184,0,9,47,27,185,0,9,0,12,62,89,184,0,0,69,88,184,0,3,47,27,185,0,3,0,8,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,186,0,2,0,0,0,9,17,18,57,186,0,7,0,9,0,0,17,18,57,185,0,22,0,1,244,184,0,9,16,185,0,28,0,2,244,48,49,1,65,3,0,105,0,1,0,1,93,65,3,0,102,0,11,0,1,93,65,3,0,87,0,11,0,1,93,65,3,0,102,0,17,0,1,93,65,3,0,87,0,17,0,1,93,0,65,3,0,105,0,1,0,1,93,65,3,0,91,0,1,0,1,93,65,5,0,85,0,8,0,101,0,8,0,2,93,65,3,0,86,0,11,0,1,93,65,3,0,103,0,11,0,1,93,65,5,0,89,0,17,0,105,0,17,0,2,93,65,3,0,149,0,29,0,1,93,5,34,39,17,35,17,51,17,54,51,50,30,2,21,20,14,2,39,20,22,51,50,54,53,52,38,35,34,6,1,46,103,49,90,90,62,96,55,88,63,34,33,63,92,217,74,77,78,85,85,78,78,73,10,66,254,215,3,223,254,200,62,40,69,93,53,53,93,69,40,255,82,101,101,82,81,94,94,255,255,0,7,255,14,1,242,2,188,2,38,0,90,0,0,1,6,0,104,40,0,0,28,184,0,13,47,65,3,0,15,0,13,0,1,93,65,3,0,63,0,13,0,1,93,184,0,9,208,48,49,255,255,0,39,255,242,2,71,3,181,2,38,0,36,0,0,1,7,0,204,0,178,0,209,0,34,65,5,0,0,0,41,0,16,0,41,0,2,93,65,3,0,176,0,41,0,1,93,0,65,3,0,47,0,40,0,1,93,48,49,255,255,0,33,255,246,1,171,2,228,2,38,0,68,0,0,1,6,0,204,45,0,0,20,65,3,0,31,0,28,0,1,93,65,3,0,32,0,28,0,1,93,48,49,0,1,0,61,0,0,0,151,1,234,0,3,0,119,187,0,3,0,4,0,2,0,4,43,65,3,0,63,0,2,0,1,113,65,3,0,143,0,2,0,1,93,65,3,0,223,0,2,0,1,93,65,3,0,32,0,2,0,1,93,65,3,0,63,0,3,0,1,113,65,3,0,143,0,3,0,1,93,65,3,0,223,0,3,0,1,93,65,3,0,32,0,3,0,1,93,0,184,0,0,69,88,184,0,3,47,27,185,0,3,0,12,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,48,49,51,35,17,51,151,90,90,1,234,0,0,0,2,0,40,255,242,4,10,2,202,0,28,0,48,2,150,186,0,28,0,1,0,3,43,65,3,0,176,0,1,0,1,93,184,0,1,16,184,0,10,208,184,0,10,47,65,5,0,63,0,10,0,79,0,10,0,2,93,65,3,0,159,0,10,0,1,93,65,3,0,47,0,10,0,1,113,65,3,0,111,0,10,0,1,93,65,3,0,15,0,10,0,1,93,65,3,0,191,0,10,0,1,93,184,0,1,16,184,0,18,208,65,3,0,176,0,28,0,1,93,184,0,28,16,184,0,21,208,184,0,21,47,184,0,1,16,185,0,27,0,4,244,184,0,23,208,184,0,28,16,184,0,25,208,184,0,25,47,184,0,10,16,185,0,34,0,4,244,184,0,1,16,184,0,44,208,65,3,0,137,0,44,0,1,93,65,7,0,9,0,44,0,25,0,44,0,41,0,44,0,3,113,65,3,0,169,0,44,0,1,93,65,3,0,72,0,44,0,1,93,0,184,0,0,69,88,184,0,15,47,27,185,0,15,0,14,62,89,184,0,0,69,88,184,0,19,47,27,185,0,19,0,14,62,89,184,0,0,69,88,184,0,5,47,27,185,0,5,0,6,62,89,184,0,0,69,88,184,0,1,47,27,185,0,1,0,6,62,89,186,0,2,0,5,0,15,17,18,57,65,3,0,92,0,2,0,1,93,65,7,0,12,0,2,0,28,0,2,0,44,0,2,0,3,113,65,3,0,107,0,2,0,1,93,65,5,0,122,0,2,0,138,0,2,0,2,93,65,3,0,66,0,10,0,1,93,186,0,18,0,15,0,5,17,18,57,65,3,0,100,0,18,0,1,93,65,3,0,118,0,18,0,1,93,65,3,0,133,0,18,0,1,93,65,3,0,83,0,18,0,1,93,65,7,0,3,0,18,0,19,0,18,0,35,0,18,0,3,113,184,0,19,16,185,0,22,0,2,244,186,0,23,0,19,0,1,17,18,57,184,0,23,47,185,0,26,0,2,244,184,0,1,16,185,0,27,0,2,244,184,0,15,16,185,0,29,0,2,244,184,0,5,16,185,0,39,0,2,244,48,49,1,65,3,0,120,0,3,0,1,93,65,7,0,89,0,7,0,105,0,7,0,121,0,7,0,3,93,65,3,0,90,0,8,0,1,93,65,3,0,89,0,12,0,1,93,65,3,0,121,0,12,0,1,93,65,3,0,104,0,13,0,1,93,65,3,0,89,0,13,0,1,93,65,3,0,120,0,17,0,1,93,0,65,5,0,89,0,3,0,105,0,3,0,2,93,65,3,0,122,0,3,0,1,93,65,5,0,104,0,7,0,120,0,7,0,2,93,65,3,0,89,0,7,0,1,93,65,3,0,88,0,8,0,1,93,65,3,0,86,0,12,0,1,93,65,3,0,118,0,12,0,1,93,65,5,0,86,0,13,0,102,0,13,0,2,93,65,3,0,84,0,17,0,1,93,65,5,0,102,0,17,0,118,0,17,0,2,93,65,3,0,114,0,18,0,1,93,41,1,53,14,1,35,34,46,2,53,52,62,2,51,50,22,23,53,33,21,33,21,51,21,35,21,33,1,34,14,2,21,20,30,2,51,50,62,2,53,52,46,2,4,10,254,102,69,115,62,75,124,90,49,50,90,124,74,62,115,69,1,145,254,202,238,238,1,63,253,112,58,89,60,31,30,60,89,59,58,89,60,30,31,60,89,83,53,44,52,96,134,82,82,135,95,52,44,53,82,85,205,86,237,2,30,41,74,102,61,60,102,74,42,42,74,102,60,61,102,74,41,0,3,0,32,255,246,3,104,1,244,0,43,0,49,0,61,3,73,186,0,42,0,22,0,3,43,65,9,0,63,0,22,0,79,0,22,0,95,0,22,0,111,0,22,0,4,93,65,3,0,207,0,22,0,1,93,65,5,0,96,0,42,0,112,0,42,0,2,93,65,3,0,240,0,42,0,1,93,65,7,0,16,0,42,0,32,0,42,0,48,0,42,0,3,113,65,7,0,144,0,42,0,160,0,42,0,176,0,42,0,3,93,65,3,0,64,0,42,0,1,93,65,5,0,0,0,42,0,16,0,42,0,2,93,186,0,59,0,22,0,42,17,18,57,184,0,59,47,185,0,1,0,4,244,184,0,42,16,184,0,9,208,184,0,9,47,186,0,14,0,1,0,59,17,18,57,186,0,32,0,59,0,1,17,18,57,184,0,1,16,184,0,46,208,184,0,42,16,185,0,47,0,4,244,184,0,22,16,185,0,53,0,4,244,65,3,0,64,0,63,0,1,93,65,3,0,96,0,63,0,1,93,65,3,0,240,0,63,0,1,93,0,184,0,0,69,88,184,0,27,47,27,185,0,27,0,12,62,89,184,0,0,69,88,184,0,37,47,27,185,0,37,0,12,62,89,184,0,0,69,88,184,0,17,47,27,185,0,17,0,6,62,89,184,0,0,69,88,184,0,11,47,27,185,0,11,0,6,62,89,186,0,1,0,37,0,11,17,18,57,184,0,1,47,65,5,0,16,0,1,0,32,0,1,0,2,93,65,5,0,144,0,1,0,160,0,1,0,2,93,184,0,11,16,185,0,6,0,1,244,184,0,11,16,184,0,8,220,186,0,14,0,11,0,37,17,18,57,186,0,32,0,37,0,11,17,18,57,184,0,37,16,185,0,44,0,2,244,184,0,1,16,184,0,46,220,65,15,0,159,0,46,0,175,0,46,0,191,0,46,0,207,0,46,0,223,0,46,0,239,0,46,0,255,0,46,0,7,93,184,0,27,16,185,0,50,0,2,244,184,0,17,16,185,0,56,0,2,244,48,49,1,65,3,0,54,0,3,0,1,93,65,3,0,71,0,3,0,1,93,65,3,0,89,0,13,0,1,93,65,3,0,106,0,13,0,1,93,65,3,0,123,0,13,0,1,93,65,3,0,84,0,15,0,1,93,65,3,0,102,0,15,0,1,93,65,3,0,105,0,19,0,1,93,65,3,0,90,0,19,0,1,93,65,3,0,105,0,25,0,1,93,65,3,0,90,0,25,0,1,93,65,3,0,85,0,30,0,1,93,65,3,0,102,0,30,0,1,93,65,3,0,104,0,34,0,1,93,65,3,0,121,0,34,0,1,93,65,3,0,118,0,39,0,1,93,65,3,0,135,0,39,0,1,93,65,3,0,118,0,40,0,1,93,65,3,0,135,0,40,0,1,93,65,3,0,105,0,45,0,1,93,0,65,5,0,55,0,3,0,71,0,3,0,2,93,65,9,0,91,0,9,0,107,0,9,0,123,0,9,0,139,0,9,0,4,93,65,5,0,104,0,13,0,120,0,13,0,2,93,65,3,0,89,0,13,0,1,93,65,5,0,90,0,14,0,106,0,14,0,2,93,65,3,0,104,0,15,0,1,93,65,3,0,89,0,15,0,1,93,65,5,0,89,0,19,0,105,0,19,0,2,93,65,3,0,85,0,25,0,1,93,65,3,0,102,0,25,0,1,93,65,3,0,85,0,30,0,1,93,65,3,0,102,0,30,0,1,93,65,3,0,101,0,32,0,1,93,65,5,0,118,0,32,0,134,0,32,0,2,93,65,3,0,100,0,34,0,1,93,65,3,0,118,0,34,0,1,93,65,5,0,118,0,39,0,134,0,39,0,2,93,65,3,0,118,0,40,0,1,93,65,3,0,135,0,40,0,1,93,65,3,0,102,0,45,0,1,93,37,33,20,30,2,51,50,55,23,6,35,34,38,39,14,1,35,34,46,2,53,52,62,2,51,50,30,2,23,62,3,51,50,30,2,21,20,39,34,7,51,46,1,33,34,6,21,20,22,51,50,54,53,52,38,3,100,254,169,32,48,55,23,84,71,10,72,81,93,102,23,22,110,67,57,91,64,34,35,65,93,57,28,59,53,40,11,13,42,49,55,27,48,79,55,31,214,107,24,253,4,64,254,82,78,80,79,78,75,77,79,245,57,71,41,14,37,77,32,53,54,51,56,40,70,95,55,54,92,66,38,13,26,38,25,24,38,26,14,28,53,75,48,31,155,113,54,59,91,84,85,90,99,79,78,94,0,255,255,0,40,255,242,2,41,3,181,2,38,0,52,0,0,1,7,0,204,0,69,0,209,0,38,65,3,0,79,0,60,0,1,93,65,7,0,0,0,60,0,16,0,60,0,32,0,60,0,3,93,0,65,3,0,47,0,59,0,1,93,48,49,255,255,0,32,255,246,1,131,2,228,2,38,0,84,0,0,1,6,0,204,232,0,0,29,65,3,0,79,0,42,0,1,93,65,3,0,63,0,43,0,1,93,65,3,0,0,0,43,0,1,93,48,49,0,0,0,255,255,255,253,0,0,2,57,3,141,2,38,0,58,0,0,1,7,0,104,0,85,0,209,0,68,184,0,14,47,65,5,0,16,0,14,0,32,0,14,0,2,93,65,3,0,80,0,14,0,1,113,65,3,0,144,0,14,0,1,93,184,0,10,208,0,184,0,13,47,65,3,0,47,0,13,0,1,93,65,3,0,175,0,13,0,1,93,184,0,10,208,48,49,0,0,255,255,0,9,0,0,2,30,3,181,2,38,0,59,0,0,1,7,0,204,0,60,0,209,0,34,65,5,0,0,0,10,0,16,0,10,0,2,93,65,3,0,32,0,10,0,1,113,0,65,3,0,47,0,9,0,1,93,48,49,255,255,0,22,0,0,1,190,2,228,2,38,0,91,0,0,1,6,0,204,14,0,0,33,65,5,0,111,0,10,0,127,0,10,0,2,93,65,3,0,223,0,10,0,1,93,65,3,0,0,0,10,0,1,93,48,49,0,0,0,0,1,255,222,255,15,1,115,2,202,0,32,1,43,187,0,11,0,5,0,22,0,4,43,184,0,22,16,184,0,25,208,184,0,0,208,184,0,0,47,184,0,11,16,184,0,8,208,184,0,9,208,184,0,9,47,184,0,11,16,184,0,12,208,184,0,19,208,184,0,19,47,184,0,22,16,184,0,21,208,184,0,25,16,184,0,24,208,184,0,24,47,0,184,0,0,69,88,184,0,31,47,27,185,0,31,0,14,62,89,184,0,0,69,88,184,0,8,47,27,185,0,8,0,12,62,89,184,0,0,69,88,184,0,17,47,27,185,0,17,0,8,62,89,184,0,31,16,185,0,3,0,3,244,184,0,8,16,185,0,11,0,3,244,184,0,17,16,185,0,19,0,3,244,184,0,11,16,184,0,22,208,184,0,8,16,184,0,25,208,48,49,1,65,3,0,133,0,6,0,1,93,65,7,0,38,0,6,0,54,0,6,0,70,0,6,0,3,93,65,3,0,102,0,6,0,1,93,65,5,0,119,0,15,0,135,0,15,0,2,93,65,3,0,89,0,28,0,1,93,65,3,0,122,0,28,0,1,93,0,65,3,0,135,0,6,0,1,93,65,5,0,57,0,6,0,73,0,6,0,2,93,65,5,0,121,0,15,0,137,0,15,0,2,93,65,3,0,116,0,28,0,1,93,65,3,0,87,0,28,0,1,93,1,7,38,35,34,14,2,7,51,7,35,3,14,3,43,1,39,54,55,19,35,55,51,55,62,3,51,50,1,115,7,13,19,30,43,30,20,8,148,6,153,86,6,27,32,34,13,13,13,57,14,80,94,7,96,9,6,33,49,61,35,17,2,191,55,8,16,39,64,47,56,253,242,40,56,36,17,63,12,89,1,255,56,61,39,60,42,22,0,0,0,0,1,255,244,255,14,0,151,1,234,0,14,0,163,187,0,9,0,4,0,8,0,4,43,65,3,0,63,0,8,0,1,113,65,3,0,143,0,8,0,1,93,65,3,0,223,0,8,0,1,93,65,3,0,32,0,8,0,1,93,184,0,8,16,184,0,2,208,184,0,2,47,65,3,0,143,0,9,0,1,93,65,3,0,223,0,9,0,1,93,65,3,0,63,0,9,0,1,113,65,3,0,32,0,9,0,1,93,0,184,0,0,69,88,184,0,9,47,27,185,0,9,0,12,62,89,184,0,0,69,88,184,0,1,47,27,185,0,1,0,8,62,89,185,0,2,0,1,244,48,49,1,65,11,0,5,0,12,0,21,0,12,0,37,0,12,0,53,0,12,0,69,0,12,0,5,93,23,7,39,62,3,53,17,51,17,20,14,2,28,30,10,22,28,16,7,90,20,33,45,237,5,69,2,10,21,37,30,2,51,253,171,32,45,31,18,0,1,0,76,2,91,1,114,2,233,0,5,0,130,25,184,0,4,47,24,65,3,0,0,0,4,0,1,93,184,0,1,208,184,0,4,16,184,0,3,208,184,0,3,47,184,0,4,16,184,0,5,208,184,0,5,47,0,184,0,2,47,65,3,0,64,0,2,0,1,93,65,3,0,32,0,2,0,1,93,184,0,0,208,184,0,2,16,184,0,4,220,65,5,0,15,0,4,0,31,0,4,0,2,93,65,9,0,95,0,4,0,111,0,4,0,127,0,4,0,143,0,4,0,4,93,184,0,1,220,184,0,2,16,184,0,3,220,184,0,5,208,48,49,1,39,7,53,55,23,1,114,147,147,147,147,2,91,82,82,36,106,106,0,0,1,0,76,2,88,1,114,2,228,0,5,0,130,25,184,0,1,47,24,184,0,0,208,184,0,0,47,184,0,1,16,184,0,2,208,184,0,2,47,184,0,1,16,184,0,4,208,0,184,0,1,47,65,3,0,64,0,1,0,1,93,65,3,0,32,0,1,0,1,93,184,0,3,220,65,9,0,95,0,3,0,111,0,3,0,127,0,3,0,143,0,3,0,4,93,65,5,0,15,0,3,0,31,0,3,0,2,93,184,0,2,220,184,0,0,208,184,0,1,16,184,0,4,220,65,3,0,240,0,4,0,1,93,184,0,3,16,184,0,5,208,48,49,1,7,39,53,23,55,1,114,147,147,147,147,2,187,99,99,41,76,76,0,0,2,0,42,2,64,0,249,2,243,0,14,0,26,1,101,184,0,3,47,184,0,11,220,65,3,0,32,0,11,0,1,113,65,3,0,208,0,11,0,1,93,184,0,3,16,184,0,15,220,184,0,11,16,184,0,21,220,0,184,0,14,47,65,3,0,95,0,14,0,1,113,65,3,0,239,0,14,0,1,93,65,3,0,207,0,14,0,1,93,65,3,0,128,0,14,0,1,93,65,3,0,96,0,14,0,1,93,184,0,6,220,65,3,0,15,0,6,0,1,113,65,7,0,143,0,6,0,159,0,6,0,175,0,6,0,3,93,65,3,0,79,0,6,0,1,93,184,0,14,16,184,0,18,220,184,0,6,16,184,0,24,220,48,49,1,65,9,0,74,0,2,0,90,0,2,0,106,0,2,0,122,0,2,0,4,93,65,9,0,73,0,4,0,89,0,4,0,105,0,4,0,121,0,4,0,4,93,65,9,0,70,0,9,0,86,0,9,0,102,0,9,0,118,0,9,0,4,93,65,9,0,70,0,12,0,86,0,12,0,102,0,12,0,118,0,12,0,4,93,0,65,9,0,73,0,1,0,89,0,1,0,105,0,1,0,121,0,1,0,4,93,65,9,0,70,0,5,0,86,0,5,0,102,0,5,0,118,0,5,0,4,93,65,9,0,70,0,8,0,86,0,8,0,102,0,8,0,118,0,8,0,4,93,65,9,0,72,0,12,0,88,0,12,0,104,0,12,0,120,0,12,0,4,93,65,9,0,73,0,13,0,89,0,13,0,105,0,13,0,121,0,13,0,4,93,65,7,0,53,0,16,0,69,0,16,0,85,0,16,0,3,113,19,34,38,53,52,54,51,50,30,2,21,20,6,35,39,20,22,51,50,54,53,52,38,35,34,6,146,49,55,58,52,24,37,24,12,48,48,67,36,24,24,36,35,25,25,35,2,64,52,37,39,51,15,26,32,17,34,55,89,27,33,33,27,26,33,33,0,0,1,0,92,2,87,1,182,2,190,0,23,1,42,184,0,8,47,65,3,0,0,0,8,0,1,93,184,0,7,220,184,0,8,16,184,0,21,220,184,0,20,220,0,184,0,0,47,65,3,0,64,0,0,0,1,93,65,3,0,32,0,0,0,1,93,184,0,13,220,65,9,0,47,0,13,0,63,0,13,0,79,0,13,0,95,0,13,0,4,93,184,0,5,220,65,5,0,48,0,5,0,64,0,5,0,2,113,184,0,0,16,184,0,7,208,184,0,7,47,184,0,0,16,184,0,18,220,65,3,0,63,0,18,0,1,113,184,0,13,16,184,0,20,208,184,0,20,47,48,49,1,65,7,0,6,0,6,0,22,0,6,0,38,0,6,0,3,113,65,5,0,40,0,10,0,56,0,10,0,2,93,65,5,0,40,0,11,0,56,0,11,0,2,93,65,7,0,11,0,19,0,27,0,19,0,43,0,19,0,3,113,65,5,0,37,0,22,0,53,0,22,0,2,93,0,65,7,0,9,0,6,0,25,0,6,0,41,0,6,0,3,113,65,5,0,37,0,10,0,53,0,10,0,2,93,65,5,0,38,0,11,0,54,0,11,0,2,93,65,7,0,7,0,19,0,23,0,19,0,39,0,19,0,3,113,65,5,0,40,0,22,0,56,0,22,0,2,93,65,5,0,41,0,23,0,57,0,23,0,2,93,1,34,46,2,35,34,7,39,62,3,51,50,30,2,51,50,55,23,14,1,1,75,12,36,41,32,11,53,18,36,6,20,30,32,15,13,36,46,35,10,42,27,34,11,58,2,87,16,19,16,49,9,22,34,23,11,15,19,15,51,9,43,51,0,0,1,0,57,0,238,1,189,1,68,0,3,0,19,184,0,1,47,184,0,0,220,0,184,0,1,47,184,0,2,220,48,49,37,33,53,33,1,189,254,124,1,132,238,86,0,0,0,0,1,0,57,0,238,2,25,1,68,0,3,0,28,184,0,1,47,65,3,0,0,0,1,0,1,93,184,0,0,220,0,184,0,1,47,184,0,2,220,48,49,37,33,53,33,2,25,254,32,1,224,238,86,0,0,0,1,0,43,2,43,0,144,2,238,0,6,0,58,184,0,0,47,184,0,4,220,184,0,2,208,186,0,3,0,0,0,4,17,18,57,0,184,0,0,69,88,184,0,1,47,27,185,0,1,0,18,62,89,184,0,4,220,184,0,0,208,184,0,4,16,184,0,5,220,48,49,19,55,23,7,23,21,35,43,78,23,35,34,100,2,129,109,13,87,9,86,0,1,0,42,2,43,0,143,2,238,0,6,0,58,184,0,0,47,184,0,4,220,184,0,2,208,186,0,3,0,4,0,0,17,18,57,0,184,0,0,69,88,184,0,5,47,27,185,0,5,0,18,62,89,184,0,4,220,184,0,0,208,184,0,4,16,184,0,1,220,48,49,19,7,39,55,39,53,51,143,78,23,35,34,100,2,152,109,13,87,9,86,0,1,0,57,255,147,0,158,0,86,0,6,0,62,184,0,0,47,184,0,4,220,184,0,2,208,186,0,3,0,4,0,0,17,18,57,0,184,0,0,69,88,184,0,4,47,27,185,0,4,0,6,62,89,184,0,0,208,184,0,4,16,184,0,1,220,184,0,4,16,184,0,5,220,48,49,51,7,39,55,39,53,51,158,78,23,35,34,100,109,13,87,9,86,0,0,0,2,0,43,2,43,1,98,2,238,0,6,0,13,0,116,184,0,6,47,184,0,5,220,184,0,2,208,186,0,3,0,6,0,5,17,18,57,184,0,6,16,184,0,13,220,184,0,12,220,184,0,9,208,186,0,10,0,13,0,12,17,18,57,0,184,0,0,69,88,184,0,1,47,27,185,0,1,0,18,62,89,184,0,4,220,184,0,0,208,184,0,4,16,184,0,5,220,184,0,4,16,184,0,7,208,184,0,1,16,184,0,8,208,184,0,7,16,184,0,11,208,184,0,5,16,184,0,13,208,48,49,19,55,23,7,23,21,35,63,1,23,7,23,21,35,43,78,23,35,34,100,210,78,23,35,34,100,2,129,109,13,87,9,86,86,109,13,87,9,86,0,0,2,0,42,2,43,1,97,2,238,0,6,0,13,0,118,184,0,6,47,184,0,5,220,184,0,2,208,186,0,3,0,5,0,6,17,18,57,184,0,6,16,184,0,13,220,184,0,12,220,184,0,9,208,186,0,10,0,12,0,13,17,18,57,0,184,0,0,69,88,184,0,12,47,27,185,0,12,0,18,62,89,184,0,11,220,184,0,4,208,184,0,0,208,184,0,11,16,184,0,8,220,184,0,1,208,184,0,12,16,184,0,5,208,184,0,11,16,184,0,7,208,48,49,1,65,3,0,89,0,1,0,1,93,1,7,39,55,39,53,51,15,1,39,55,39,53,51,1,97,78,23,35,34,100,210,78,23,35,34,100,2,152,109,13,87,9,86,86,109,13,87,9,86,0,0,0,2,0,57,255,147,1,132,0,86,0,6,0,13,0,138,184,0,7,47,65,3,0,80,0,7,0,1,113,184,0,0,220,65,5,0,79,0,0,0,95,0,0,0,2,113,184,0,4,220,184,0,2,208,186,0,3,0,4,0,0,17,18,57,184,0,7,16,184,0,11,220,184,0,9,208,186,0,10,0,11,0,7,17,18,57,0,184,0,0,69,88,184,0,4,47,27,185,0,4,0,6,62,89,184,0,0,208,184,0,4,16,184,0,1,220,184,0,4,16,184,0,5,220,184,0,4,16,184,0,11,208,184,0,7,208,184,0,1,16,184,0,8,208,184,0,5,16,184,0,12,208,48,49,51,7,39,55,39,53,51,23,7,39,55,39,53,51,158,78,23,35,34,100,230,78,23,35,34,100,109,13,87,9,86,86,109,13,87,9,86,0,0,1,0,35,0,0,1,133,2,95,0,13,0,196,184,0,10,47,65,3,0,16,0,10,0,1,93,184,0,11,220,65,9,0,80,0,11,0,96,0,11,0,112,0,11,0,128,0,11,0,4,93,186,0,12,0,11,0,10,17,18,57,184,0,12,16,184,0,1,208,184,0,11,16,184,0,2,208,184,0,10,16,184,0,5,208,186,0,9,0,10,0,11,17,18,57,184,0,9,16,184,0,6,208,184,0,10,16,184,0,8,220,184,0,11,16,184,0,13,220,0,184,0,10,47,184,0,0,69,88,184,0,4,47,27,185,0,4,0,6,62,89,186,0,8,0,10,0,4,17,18,57,184,0,8,47,184,0,7,220,184,0,0,208,186,0,6,0,7,0,8,17,18,57,184,0,6,16,184,0,1,208,186,0,9,0,8,0,7,17,18,57,184,0,9,16,184,0,12,208,184,0,8,16,184,0,13,208,48,49,1,39,23,7,35,39,55,7,53,23,39,51,7,55,1,133,158,41,31,58,31,41,158,156,34,110,34,156,1,117,30,151,252,252,151,30,85,31,180,180,31,0,0,1,0,53,255,197,1,151,2,95,0,21,1,61,184,0,13,47,65,3,0,0,0,13,0,1,93,184,0,14,220,65,9,0,80,0,14,0,96,0,14,0,112,0,14,0,128,0,14,0,4,93,186,0,15,0,14,0,13,17,18,57,184,0,15,16,184,0,1,208,184,0,14,16,184,0,2,208,184,0,13,16,184,0,3,208,186,0,12,0,13,0,14,17,18,57,184,0,12,16,184,0,4,208,184,0,13,16,184,0,11,220,184,0,6,208,184,0,4,16,184,0,7,208,184,0,13,16,184,0,8,208,184,0,12,16,184,0,9,208,184,0,14,16,184,0,16,220,184,0,15,16,184,0,18,208,184,0,14,16,184,0,19,208,184,0,1,16,184,0,20,208,184,0,16,16,184,0,21,208,0,184,0,14,47,184,0,3,47,186,0,0,0,3,0,14,17,18,57,184,0,0,47,184,0,21,220,186,0,1,0,0,0,21,17,18,57,184,0,1,16,184,0,4,208,184,0,0,16,184,0,5,208,184,0,21,16,184,0,6,208,186,0,20,0,21,0,0,17,18,57,184,0,20,16,184,0,7,208,186,0,16,0,14,0,3,17,18,57,184,0,16,47,184,0,17,220,186,0,18,0,17,0,16,17,18,57,184,0,18,16,184,0,9,208,184,0,17,16,184,0,10,208,184,0,16,16,184,0,11,208,186,0,15,0,16,0,17,17,18,57,184,0,15,16,184,0,12,208,48,49,37,39,23,35,55,7,53,23,39,55,7,53,23,39,51,7,55,21,39,23,7,55,1,151,156,34,110,34,156,160,43,43,160,156,34,110,34,156,160,43,43,160,88,30,177,177,30,84,30,132,133,30,84,30,176,176,30,84,30,133,132,30,0,0,0,0,1,0,44,0,169,1,6,1,131,0,20,0,19,184,0,8,47,184,0,18,220,0,184,0,3,47,184,0,13,220,48,49,55,14,1,35,34,46,2,53,52,62,2,51,50,30,2,21,20,6,230,17,39,21,22,39,30,18,18,30,39,22,22,39,30,18,16,201,17,15,18,30,39,22,22,39,30,18,18,30,39,22,21,40,0,0,0,0,3,0,57,0,0,2,107,0,86,0,3,0,7,0,11,0,121,184,0,1,47,65,3,0,0,0,1,0,1,93,65,3,0,32,0,1,0,1,93,185,0,0,0,4,244,184,0,1,16,184,0,5,220,185,0,4,0,4,244,184,0,5,16,184,0,9,220,185,0,8,0,4,244,0,184,0,0,69,88,184,0,1,47,27,185,0,1,0,6,62,89,184,0,2,220,65,3,0,63,0,2,0,1,113,184,0,1,16,184,0,5,208,184,0,2,16,184,0,6,208,184,0,5,16,184,0,9,208,184,0,6,16,184,0,10,208,48,49,51,35,53,51,23,35,53,51,23,35,53,51,147,90,90,236,90,90,236,90,90,86,86,86,86,86,0,0,0,0,7,0,36,255,242,4,141,2,193,0,3,0,21,0,37,0,55,0,71,0,89,0,105,3,55,184,0,7,47,184,0,41,47,65,7,0,0,0,41,0,16,0,41,0,32,0,41,0,3,93,184,0,51,220,186,0,1,0,7,0,51,17,18,57,184,0,1,47,184,0,0,220,184,0,1,16,184,0,3,220,184,0,2,220,184,0,7,16,184,0,17,220,184,0,7,16,184,0,27,220,65,3,0,31,0,27,0,1,113,184,0,17,16,184,0,33,220,65,3,0,16,0,33,0,1,113,184,0,41,16,184,0,61,220,65,3,0,31,0,61,0,1,113,184,0,51,16,184,0,67,220,65,3,0,16,0,67,0,1,113,184,0,41,16,184,0,75,220,184,0,85,220,184,0,75,16,184,0,95,220,65,3,0,31,0,95,0,1,113,184,0,85,16,184,0,101,220,65,3,0,16,0,101,0,1,113,0,184,0,0,69,88,184,0,12,47,27,185,0,12,0,14,62,89,184,0,0,69,88,184,0,2,47,27,185,0,2,0,14,62,89,184,0,0,69,88,184,0,38,47,27,185,0,38,0,6,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,184,0,12,16,184,0,4,220,184,0,12,16,184,0,22,220,184,0,4,16,184,0,30,220,184,0,38,16,184,0,46,220,184,0,56,220,184,0,38,16,184,0,64,220,184,0,38,16,184,0,72,208,184,0,46,16,184,0,80,208,184,0,56,16,184,0,90,208,184,0,64,16,184,0,98,208,48,49,1,65,3,0,87,0,0,0,1,93,65,3,0,202,0,5,0,1,93,65,7,0,10,0,6,0,26,0,6,0,42,0,6,0,3,93,65,7,0,10,0,9,0,26,0,9,0,42,0,9,0,3,93,65,3,0,202,0,10,0,1,93,65,3,0,198,0,14,0,1,93,65,7,0,6,0,15,0,22,0,15,0,38,0,15,0,3,93,65,7,0,5,0,19,0,21,0,19,0,37,0,19,0,3,93,65,3,0,198,0,20,0,1,93,65,5,0,118,0,24,0,134,0,24,0,2,93,65,7,0,10,0,40,0,26,0,40,0,42,0,40,0,3,93,65,7,0,9,0,43,0,25,0,43,0,41,0,43,0,3,93,65,3,0,201,0,44,0,1,93,65,3,0,197,0,48,0,1,93,65,7,0,5,0,49,0,21,0,49,0,37,0,49,0,3,93,65,7,0,5,0,53,0,21,0,53,0,37,0,53,0,3,93,65,3,0,198,0,54,0,1,93,65,5,0,118,0,58,0,134,0,58,0,2,93,65,3,0,200,0,73,0,1,93,65,7,0,10,0,74,0,26,0,74,0,42,0,74,0,3,93,65,7,0,10,0,77,0,26,0,77,0,42,0,77,0,3,93,65,3,0,201,0,78,0,1,93,65,3,0,197,0,82,0,1,93,65,7,0,5,0,83,0,21,0,83,0,37,0,83,0,3,93,65,7,0,5,0,87,0,21,0,87,0,37,0,87,0,3,93,65,3,0,198,0,88,0,1,93,65,5,0,118,0,92,0,134,0,92,0,2,93,0,65,3,0,202,0,5,0,1,93,65,7,0,5,0,9,0,21,0,9,0,37,0,9,0,3,93,65,3,0,197,0,10,0,1,93,65,3,0,198,0,14,0,1,93,65,7,0,7,0,15,0,23,0,15,0,39,0,15,0,3,93,65,3,0,200,0,20,0,1,93,65,3,0,202,0,39,0,1,93,65,3,0,198,0,44,0,1,93,65,3,0,198,0,48,0,1,93,65,3,0,203,0,54,0,1,93,65,3,0,201,0,73,0,1,93,65,3,0,199,0,78,0,1,93,65,3,0,198,0,82,0,1,93,65,3,0,202,0,88,0,1,93,23,35,1,51,1,34,38,53,52,62,2,51,50,30,2,21,20,14,2,3,34,14,2,21,20,22,51,50,54,53,52,46,2,1,34,38,53,52,62,2,51,50,30,2,21,20,14,2,3,34,14,2,21,20,22,51,50,54,53,52,46,2,1,34,38,53,52,62,2,51,50,30,2,21,20,14,2,3,34,14,2,21,20,22,51,50,54,53,52,46,2,238,75,1,165,74,254,36,64,82,24,42,55,30,31,53,39,23,23,40,55,29,19,34,26,15,54,37,40,54,14,26,33,1,195,64,82,24,42,55,30,31,53,39,23,23,40,55,29,19,34,26,15,54,37,40,54,14,26,33,1,81,64,82,24,42,55,30,31,53,39,23,23,40,55,29,19,34,26,15,54,37,40,54,14,26,33,12,2,200,254,145,94,88,46,71,48,25,24,46,67,44,46,71,49,25,1,64,19,36,52,31,60,70,75,64,29,48,34,18,253,101,94,88,46,71,48,25,24,46,67,44,46,71,49,25,1,64,19,36,52,31,60,70,75,64,29,48,34,18,254,192,94,88,46,71,48,25,24,46,67,44,46,71,49,25,1,64,19,36,52,31,60,70,75,64,29,48,34,18,0,0,1,0,14,0,78,1,26,1,234,0,5,0,219,184,0,2,47,65,9,0,95,0,2,0,111,0,2,0,127,0,2,0,143,0,2,0,4,93,65,3,0,255,0,2,0,1,93,184,0,4,220,65,3,0,128,0,4,0,1,93,65,3,0,80,0,4,0,1,93,184,0,0,208,184,0,4,16,184,0,3,220,65,9,0,95,0,3,0,111,0,3,0,127,0,3,0,143,0,3,0,4,93,65,5,0,239,0,3,0,255,0,3,0,2,93,65,7,0,15,0,3,0,31,0,3,0,47,0,3,0,3,113,184,0,1,208,184,0,2,16,184,0,5,220,65,9,0,80,0,5,0,96,0,5,0,112,0,5,0,128,0,5,0,4,93,65,5,0,224,0,5,0,240,0,5,0,2,93,65,7,0,0,0,5,0,16,0,5,0,32,0,5,0,3,113,0,25,184,0,2,47,24,184,0,1,208,184,0,1,47,184,0,2,16,184,0,3,208,184,0,3,47,184,0,2,16,184,0,5,208,48,49,37,35,39,55,51,7,1,26,109,159,159,109,159,78,206,206,206,0,0,0,1,0,41,0,78,1,53,1,234,0,5,0,207,184,0,0,47,65,3,0,0,0,0,0,1,93,65,3,0,160,0,0,0,1,93,184,0,4,220,65,3,0,143,0,4,0,1,93,65,3,0,95,0,4,0,1,93,184,0,5,220,65,9,0,80,0,5,0,96,0,5,0,112,0,5,0,128,0,5,0,4,93,65,5,0,224,0,5,0,240,0,5,0,2,93,65,7,0,0,0,5,0,16,0,5,0,32,0,5,0,3,113,184,0,1,208,184,0,4,16,184,0,2,208,184,0,0,16,184,0,3,220,65,9,0,95,0,3,0,111,0,3,0,127,0,3,0,143,0,3,0,4,93,65,5,0,239,0,3,0,255,0,3,0,2,93,65,7,0,15,0,3,0,31,0,3,0,47,0,3,0,3,113,0,25,184,0,0,47,24,184,0,1,208,184,0,1,47,184,0,0,16,184,0,3,208,184,0,0,16,184,0,5,208,184,0,5,47,48,49,1,7,35,55,39,51,1,53,159,109,159,159,109,1,28,206,206,206,0,0,2,0,33,1,56,1,118,2,194,0,19,0,31,2,137,186,0,15,0,5,0,3,43,65,3,0,223,0,5,0,1,93,65,3,0,143,0,5,0,1,93,65,3,0,16,0,5,0,1,93,65,3,0,64,0,5,0,1,93,65,3,0,176,0,15,0,1,93,65,3,0,0,0,15,0,1,113,65,3,0,48,0,15,0,1,113,65,3,0,224,0,15,0,1,93,65,3,0,64,0,15,0,1,93,65,5,0,16,0,15,0,32,0,15,0,2,93,184,0,5,16,185,0,20,0,5,244,184,0,15,16,185,0,26,0,5,244,0,184,0,0,69,88,184,0,10,47,27,185,0,10,0,14,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,10,62,89,65,3,0,135,0,5,0,1,93,185,0,23,0,1,244,184,0,10,16,185,0,29,0,1,244,48,49,1,65,3,0,152,0,1,0,1,93,65,3,0,184,0,2,0,1,93,65,3,0,169,0,2,0,1,93,65,3,0,24,0,3,0,1,93,65,3,0,9,0,3,0,1,93,65,3,0,41,0,3,0,1,93,65,5,0,74,0,3,0,90,0,3,0,2,113,65,5,0,73,0,7,0,89,0,7,0,2,113,65,3,0,10,0,7,0,1,93,65,5,0,166,0,12,0,182,0,12,0,2,93,65,3,0,39,0,12,0,1,93,65,3,0,151,0,12,0,1,93,65,5,0,68,0,13,0,84,0,13,0,2,113,65,5,0,6,0,13,0,22,0,13,0,2,93,65,3,0,6,0,18,0,1,93,65,3,0,182,0,18,0,1,93,65,5,0,23,0,18,0,39,0,18,0,2,93,65,5,0,151,0,18,0,167,0,18,0,2,93,65,3,0,217,0,21,0,1,93,65,3,0,234,0,21,0,1,93,65,5,0,75,0,21,0,91,0,21,0,2,113,65,3,0,138,0,24,0,1,93,65,3,0,138,0,28,0,1,93,65,3,0,132,0,30,0,1,93,65,5,0,71,0,30,0,87,0,30,0,2,113,0,65,3,0,153,0,1,0,1,93,65,3,0,168,0,2,0,1,93,65,3,0,186,0,2,0,1,93,65,5,0,71,0,3,0,87,0,3,0,2,113,65,7,0,8,0,3,0,24,0,3,0,40,0,3,0,3,93,65,3,0,7,0,7,0,1,93,65,3,0,181,0,12,0,1,93,65,3,0,38,0,12,0,1,93,65,5,0,150,0,12,0,166,0,12,0,2,93,65,5,0,7,0,13,0,23,0,13,0,2,93,65,5,0,71,0,13,0,87,0,13,0,2,113,65,5,0,72,0,17,0,88,0,17,0,2,113,65,3,0,184,0,18,0,1,93,65,7,0,9,0,18,0,25,0,18,0,41,0,18,0,3,93,65,5,0,153,0,18,0,169,0,18,0,2,93,65,3,0,231,0,21,0,1,93,65,3,0,216,0,21,0,1,93,65,3,0,135,0,24,0,1,93,19,34,46,2,53,52,62,2,51,50,30,2,21,20,14,2,39,20,22,51,50,54,53,52,38,35,34,6,200,38,61,44,24,27,46,64,37,36,61,45,25,25,46,64,132,52,42,45,55,55,40,40,59,1,56,27,50,71,43,44,74,54,31,29,52,71,42,45,74,52,29,191,64,62,66,69,63,67,72,0,2,0,5,1,64,1,47,2,186,0,9,0,12,0,160,186,0,2,0,5,0,3,43,65,3,0,159,0,2,0,1,93,65,3,0,16,0,2,0,1,93,184,0,2,16,185,0,3,0,5,244,184,0,10,208,184,0,2,16,184,0,8,208,186,0,6,0,10,0,8,17,18,57,184,0,9,208,184,0,9,47,184,0,5,16,184,0,12,208,65,3,0,70,0,12,0,1,93,0,184,0,0,69,88,184,0,6,47,27,185,0,6,0,14,62,89,184,0,0,69,88,184,0,2,47,27,185,0,2,0,10,62,89,186,0,1,0,6,0,2,17,18,57,184,0,1,47,184,0,4,208,184,0,1,16,185,0,8,0,3,244,184,0,10,208,184,0,6,16,184,0,11,208,48,49,1,35,21,35,53,35,19,51,21,51,35,53,7,1,47,49,74,175,187,62,49,123,74,1,167,103,103,1,19,218,110,110,0,1,0,24,1,57,1,22,2,186,0,24,1,71,186,0,20,0,4,0,3,43,65,5,0,111,0,4,0,127,0,4,0,2,93,65,5,0,159,0,4,0,175,0,4,0,2,93,65,3,0,80,0,20,0,1,113,65,3,0,127,0,20,0,1,93,65,5,0,16,0,20,0,32,0,20,0,2,93,65,3,0,32,0,20,0,1,113,65,3,0,80,0,20,0,1,93,184,0,20,16,185,0,9,0,5,244,186,0,12,0,4,0,20,17,18,57,184,0,12,47,184,0,11,208,184,0,12,16,184,0,13,208,186,0,14,0,4,0,20,17,18,57,184,0,14,47,184,0,11,16,184,0,16,208,186,0,17,0,16,0,11,17,18,57,0,184,0,0,69,88,184,0,14,47,27,185,0,14,0,14,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,10,62,89,184,0,5,220,65,5,0,112,0,5,0,128,0,5,0,2,93,184,0,0,16,185,0,7,0,1,244,186,0,17,0,14,0,0,17,18,57,184,0,17,47,185,0,11,0,3,244,184,0,14,16,185,0,15,0,1,244,48,49,1,65,5,0,52,0,19,0,68,0,19,0,2,93,65,5,0,86,0,19,0,102,0,19,0,2,93,65,3,0,68,0,22,0,1,93,65,3,0,52,0,23,0,1,93,65,3,0,22,0,23,0,1,93,65,3,0,39,0,23,0,1,93,0,65,3,0,41,0,23,0,1,93,65,3,0,26,0,23,0,1,93,19,34,46,1,39,55,22,51,50,53,52,43,1,55,51,7,35,7,30,1,21,20,14,2,130,17,36,31,22,17,35,52,78,99,62,25,187,8,123,10,85,77,24,41,53,1,57,7,10,15,65,29,61,55,201,70,71,1,54,58,32,48,34,17,0,0,0,0,2,0,32,1,56,1,44,2,186,0,23,0,35,1,231,186,0,19,0,3,0,3,43,65,3,0,207,0,3,0,1,93,65,3,0,111,0,3,0,1,93,65,5,0,143,0,3,0,159,0,3,0,2,93,65,3,0,64,0,3,0,1,93,65,3,0,64,0,19,0,1,93,65,3,0,207,0,19,0,1,93,65,3,0,111,0,19,0,1,93,65,3,0,159,0,19,0,1,93,65,3,0,16,0,19,0,1,93,65,5,0,48,0,19,0,64,0,19,0,2,113,65,3,0,0,0,19,0,1,113,186,0,9,0,19,0,3,17,18,57,184,0,9,47,184,0,3,16,185,0,27,0,5,244,184,0,14,208,65,7,0,39,0,14,0,55,0,14,0,71,0,14,0,3,93,184,0,19,16,185,0,33,0,5,244,0,184,0,0,69,88,184,0,8,47,27,185,0,8,0,14,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,10,62,89,184,0,8,16,185,0,11,0,3,244,184,0,0,16,184,0,16,220,65,3,0,95,0,16,0,1,93,65,3,0,47,0,16,0,1,113,186,0,14,0,16,0,0,17,18,57,185,0,24,0,3,244,184,0,0,16,185,0,30,0,1,244,48,49,1,65,7,0,42,0,2,0,58,0,2,0,74,0,2,0,3,93,65,3,0,104,0,6,0,1,93,65,3,0,136,0,6,0,1,93,65,3,0,89,0,6,0,1,93,65,3,0,121,0,6,0,1,93,65,5,0,87,0,17,0,103,0,17,0,2,93,65,7,0,37,0,18,0,53,0,18,0,69,0,18,0,3,93,65,3,0,118,0,18,0,1,93,65,3,0,135,0,18,0,1,93,65,7,0,37,0,21,0,53,0,21,0,69,0,21,0,3,93,0,65,3,0,116,0,6,0,1,93,65,3,0,101,0,6,0,1,93,65,3,0,87,0,6,0,1,93,65,3,0,135,0,6,0,1,93,65,3,0,86,0,7,0,1,93,65,7,0,37,0,17,0,53,0,17,0,69,0,17,0,3,93,65,3,0,102,0,17,0,1,93,65,3,0,87,0,17,0,1,93,65,3,0,118,0,18,0,1,93,65,3,0,135,0,18,0,1,93,19,34,38,53,52,62,2,51,23,34,14,2,7,54,51,50,22,21,20,14,2,39,34,6,21,20,22,51,50,54,53,52,38,158,57,69,36,53,61,24,49,16,49,45,32,3,18,50,54,68,21,37,53,16,31,38,39,23,29,36,30,1,56,71,75,48,87,66,39,28,29,43,49,21,19,55,54,26,45,35,20,177,30,29,24,29,37,26,19,30,0,0,0,0,1,0,23,1,64,1,34,2,186,0,5,0,150,186,0,0,0,5,0,3,43,65,3,0,175,0,0,0,1,93,65,5,0,10,0,0,0,26,0,0,0,2,93,65,3,0,118,0,0,0,1,93,184,0,0,16,184,0,1,208,184,0,0,16,184,0,3,208,65,3,0,138,0,3,0,1,93,65,5,0,105,0,3,0,121,0,3,0,2,93,65,5,0,73,0,3,0,89,0,3,0,2,113,184,0,2,208,65,3,0,175,0,5,0,1,93,0,184,0,0,69,88,184,0,5,47,27,185,0,5,0,14,62,89,184,0,0,69,88,184,0,2,47,27,185,0,2,0,10,62,89,184,0,5,16,185,0,4,0,1,244,48,49,1,3,35,19,35,53,1,34,170,77,139,159,2,186,254,134,1,52,70,0,0,3,0,31,1,56,1,59,2,194,0,22,0,30,0,42,2,97,186,0,18,0,3,0,3,43,65,5,0,127,0,3,0,143,0,3,0,2,93,65,3,0,191,0,3,0,1,93,65,3,0,48,0,3,0,1,93,65,3,0,80,0,18,0,1,113,65,5,0,0,0,18,0,16,0,18,0,2,93,65,3,0,192,0,18,0,1,93,65,3,0,48,0,18,0,1,93,186,0,7,0,3,0,18,17,18,57,184,0,7,47,186,0,13,0,18,0,3,17,18,57,184,0,13,47,186,0,5,0,7,0,13,17,18,57,65,3,0,25,0,5,0,1,113,65,7,0,40,0,5,0,56,0,5,0,72,0,5,0,3,93,186,0,15,0,13,0,7,17,18,57,184,0,7,16,185,0,25,0,5,244,184,0,13,16,185,0,29,0,5,244,184,0,3,16,185,0,34,0,5,244,184,0,18,16,185,0,40,0,5,244,0,184,0,0,69,88,184,0,10,47,27,185,0,10,0,14,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,10,62,89,186,0,27,0,10,0,0,17,18,57,184,0,27,47,65,5,0,223,0,27,0,239,0,27,0,2,93,65,3,0,31,0,27,0,1,93,185,0,31,0,3,244,186,0,5,0,27,0,31,17,18,57,186,0,15,0,27,0,31,17,18,57,184,0,10,16,185,0,23,0,3,244,184,0,0,16,185,0,37,0,3,244,48,49,1,65,3,0,104,0,1,0,1,93,65,3,0,89,0,2,0,1,93,65,7,0,42,0,2,0,58,0,2,0,74,0,2,0,3,93,65,7,0,41,0,8,0,57,0,8,0,73,0,8,0,3,93,65,5,0,105,0,8,0,121,0,8,0,2,93,65,3,0,90,0,8,0,1,93,65,3,0,103,0,9,0,1,93,65,7,0,40,0,9,0,56,0,9,0,72,0,9,0,3,93,65,3,0,103,0,11,0,1,93,65,3,0,116,0,12,0,1,93,65,9,0,37,0,12,0,53,0,12,0,69,0,12,0,85,0,12,0,4,93,65,7,0,39,0,21,0,55,0,21,0,71,0,21,0,3,93,0,65,7,0,42,0,1,0,58,0,1,0,74,0,1,0,3,93,65,7,0,106,0,1,0,122,0,1,0,138,0,1,0,3,93,65,3,0,100,0,9,0,1,93,65,3,0,133,0,9,0,1,93,65,7,0,38,0,9,0,54,0,9,0,70,0,9,0,3,93,65,3,0,118,0,9,0,1,93,65,7,0,37,0,11,0,53,0,11,0,69,0,11,0,3,93,65,3,0,101,0,11,0,1,93,65,3,0,133,0,11,0,1,93,65,3,0,87,0,12,0,1,93,65,7,0,41,0,21,0,57,0,21,0,73,0,21,0,3,93,19,34,38,53,52,55,38,53,52,54,51,50,22,21,20,7,30,1,21,20,14,2,3,34,21,20,23,54,53,52,7,14,1,21,20,22,51,50,54,53,52,38,167,67,69,63,40,57,64,63,55,50,32,40,19,37,56,30,54,51,55,50,30,43,36,32,34,38,38,1,56,62,46,60,44,28,58,42,54,49,39,54,36,13,52,32,23,43,33,20,1,82,47,41,12,13,42,45,151,4,39,30,27,30,32,27,29,36,0,0,2,0,22,1,64,1,35,2,194,0,23,0,34,1,99,186,0,3,0,19,0,3,43,65,3,0,16,0,3,0,1,93,65,3,0,111,0,3,0,1,93,65,3,0,159,0,3,0,1,93,65,3,0,64,0,3,0,1,113,65,3,0,64,0,3,0,1,93,65,3,0,15,0,19,0,1,113,65,3,0,63,0,19,0,1,113,65,5,0,143,0,19,0,159,0,19,0,2,93,65,3,0,111,0,19,0,1,93,186,0,9,0,19,0,3,17,18,57,184,0,9,47,184,0,3,16,185,0,27,0,5,244,184,0,14,208,184,0,19,16,185,0,32,0,5,244,0,184,0,0,69,88,184,0,0,47,27,185,0,0,0,14,62,89,184,0,0,69,88,184,0,8,47,27,185,0,8,0,10,62,89,185,0,11,0,3,244,184,0,0,16,184,0,16,220,65,3,0,80,0,16,0,1,93,65,3,0,32,0,16,0,1,113,186,0,14,0,0,0,16,17,18,57,185,0,24,0,3,244,184,0,0,16,185,0,29,0,1,244,48,49,1,65,7,0,41,0,18,0,57,0,18,0,73,0,18,0,3,93,65,9,0,90,0,18,0,106,0,18,0,122,0,18,0,138,0,18,0,4,93,65,7,0,41,0,22,0,57,0,22,0,73,0,22,0,3,93,0,65,7,0,36,0,1,0,52,0,1,0,68,0,1,0,3,93,65,9,0,90,0,7,0,106,0,7,0,122,0,7,0,138,0,7,0,4,93,65,7,0,42,0,17,0,58,0,17,0,74,0,17,0,3,93,65,7,0,37,0,22,0,53,0,22,0,69,0,22,0,3,93,19,50,22,21,20,14,2,35,39,50,62,2,55,6,35,34,38,53,52,62,2,23,50,54,53,52,35,34,6,21,20,22,164,57,70,31,53,62,29,47,16,49,46,33,2,19,52,55,67,21,38,52,18,31,38,61,30,34,27,2,194,72,73,47,87,67,40,28,25,40,51,26,19,55,52,27,46,35,20,177,29,29,54,36,24,22,30,0,0,255,255,0,45,255,249,1,130,1,131,1,7,0,222,0,12,254,193,0,24,0,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,184,0,23,208,48,49,255,255,0,38,0,1,0,170,1,123,1,7,0,120,0,15,254,193,0,20,0,184,0,0,69,88,184,0,1,47,27,185,0,1,0,6,62,89,48,49,255,255,0,38,0,1,1,30,1,131,1,7,0,113,0,13,254,193,0,20,0,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,48,49,255,255,0,32,255,249,1,34,1,131,1,7,0,114,0,13,254,193,0,20,0,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,48,49,255,255,0,18,0,1,1,60,1,123,1,7,0,223,0,13,254,193,0,24,0,184,0,0,69,88,184,0,2,47,27,185,0,2,0,6,62,89,184,0,10,208,48,49,255,255,0,35,255,250,1,33,1,123,1,7,0,224,0,11,254,193,0,20,0,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,48,49,255,255,0,45,255,249,1,57,1,123,1,7,0,225,0,13,254,193,0,24,0,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,184,0,30,208,48,49,255,255,0,42,0,1,1,53,1,123,1,7,0,226,0,19,254,193,0,20,0,184,0,0,69,88,184,0,1,47,27,185,0,1,0,6,62,89,48,49,255,255,0,44,255,249,1,72,1,131,1,7,0,227,0,13,254,193,0,32,0,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,184,0,27,208,184,0,0,16,184,0,37,208,48,49,255,255,0,32,0,1,1,45,1,131,1,7,0,228,0,10,254,193,0,24,0,184,0,0,69,88,184,0,8,47,27,185,0,8,0,6,62,89,184,0,24,208,48,49,0,1,0,33,0,17,2,134,2,171,0,41,2,76,186,0,17,0,6,0,3,43,65,5,0,127,0,6,0,143,0,6,0,2,93,65,3,0,95,0,6,0,1,113,65,3,0,0,0,6,0,1,93,184,0,6,16,184,0,0,208,184,0,6,16,184,0,1,208,184,0,1,47,184,0,6,16,184,0,8,208,184,0,8,47,65,3,0,112,0,8,0,1,93,184,0,6,16,184,0,10,208,65,3,0,0,0,17,0,1,93,184,0,6,16,184,0,26,220,65,3,0,208,0,26,0,1,93,65,11,0,64,0,26,0,80,0,26,0,96,0,26,0,112,0,26,0,128,0,26,0,5,93,184,0,22,208,186,0,23,0,26,0,17,17,18,57,184,0,23,47,186,0,30,0,17,0,26,17,18,57,184,0,30,47,184,0,26,16,184,0,32,208,65,3,0,7,0,32,0,1,93,65,5,0,22,0,32,0,38,0,32,0,2,93,65,7,0,69,0,32,0,85,0,32,0,101,0,32,0,3,93,65,3,0,56,0,34,0,1,113,184,0,17,16,184,0,37,208,0,184,0,15,47,184,0,39,47,186,0,23,0,15,0,39,17,18,57,184,0,23,47,65,3,0,175,0,23,0,1,93,65,3,0,31,0,23,0,1,93,65,7,0,223,0,23,0,239,0,23,0,255,0,23,0,3,93,65,3,0,47,0,23,0,1,113,184,0,30,220,65,3,0,95,0,30,0,1,113,185,0,31,0,1,244,184,0,0,208,184,0,30,16,184,0,3,208,184,0,23,16,185,0,24,0,1,244,184,0,7,208,184,0,23,16,184,0,10,208,184,0,15,16,184,0,18,220,65,5,0,47,0,18,0,63,0,18,0,2,113,184,0,15,16,184,0,20,220,65,5,0,127,0,20,0,143,0,20,0,2,93,65,5,0,47,0,20,0,63,0,20,0,2,113,184,0,39,16,184,0,34,220,65,5,0,32,0,34,0,48,0,34,0,2,113,65,5,0,112,0,34,0,128,0,34,0,2,93,184,0,39,16,184,0,36,220,65,5,0,32,0,36,0,48,0,36,0,2,113,48,49,1,65,3,0,105,0,12,0,1,93,65,3,0,90,0,12,0,1,93,0,65,5,0,117,0,12,0,133,0,12,0,2,93,65,5,0,86,0,12,0,102,0,12,0,2,93,65,11,0,53,0,16,0,69,0,16,0,85,0,16,0,101,0,16,0,117,0,16,0,5,93,65,11,0,53,0,17,0,69,0,17,0,85,0,17,0,101,0,17,0,117,0,17,0,5,93,65,11,0,59,0,37,0,75,0,37,0,91,0,37,0,107,0,37,0,123,0,37,0,5,93,55,35,55,51,46,1,61,1,35,55,51,62,3,51,50,23,7,38,35,34,7,33,7,35,21,20,22,23,51,7,35,22,51,50,55,23,6,35,34,38,174,141,24,99,2,2,89,22,76,14,57,80,101,57,104,72,12,91,73,146,46,1,2,24,244,3,2,243,24,198,59,117,73,91,12,72,104,102,156,215,69,19,33,14,19,69,57,91,63,34,34,98,38,151,69,19,17,33,16,69,104,38,98,34,104,0,0,2,0,31,1,81,2,156,2,188,0,12,0,20,1,63,184,0,17,47,184,0,4,220,184,0,10,220,65,3,0,16,0,10,0,1,93,65,3,0,32,0,10,0,1,113,186,0,7,0,4,0,10,17,18,57,184,0,7,16,184,0,1,208,184,0,4,16,184,0,3,220,65,3,0,63,0,3,0,1,113,184,0,2,208,184,0,4,16,184,0,5,208,186,0,6,0,2,0,5,17,18,57,184,0,10,16,184,0,11,220,184,0,12,208,184,0,10,16,184,0,9,208,65,3,0,56,0,9,0,1,93,186,0,8,0,12,0,9,17,18,57,184,0,17,16,184,0,16,220,65,5,0,63,0,16,0,79,0,16,0,2,113,184,0,14,220,184,0,17,16,184,0,19,220,0,184,0,0,69,88,184,0,20,47,27,185,0,20,0,14,62,89,184,0,5,208,184,0,20,16,184,0,17,220,184,0,4,208,186,0,1,0,5,0,4,17,18,57,184,0,1,47,184,0,5,16,184,0,2,208,65,3,0,85,0,2,0,1,93,65,3,0,67,0,2,0,1,93,184,0,1,16,184,0,7,208,65,3,0,77,0,7,0,1,93,65,3,0,92,0,7,0,1,93,184,0,5,16,184,0,8,208,184,0,4,16,184,0,11,208,184,0,2,16,184,0,12,208,184,0,20,16,184,0,19,220,65,5,0,48,0,19,0,64,0,19,0,2,113,184,0,15,208,48,49,65,3,0,107,0,7,0,1,93,1,35,39,3,35,19,51,23,55,51,19,35,3,37,7,35,17,35,17,35,53,1,233,6,92,33,52,47,29,105,104,29,48,54,31,254,219,6,100,51,102,1,187,163,254,243,1,107,179,179,254,149,1,12,95,50,254,199,1,57,50,0,3,0,74,0,0,1,242,2,48,0,17,0,25,0,33,1,115,186,0,13,0,1,0,3,43,65,3,0,16,0,1,0,1,93,65,3,0,176,0,1,0,1,93,65,3,0,64,0,13,0,1,93,65,5,0,0,0,13,0,16,0,13,0,2,93,65,3,0,0,0,13,0,1,113,65,3,0,224,0,13,0,1,93,186,0,8,0,13,0,1,17,18,57,184,0,8,47,184,0,1,16,185,0,28,0,4,244,184,0,20,208,186,0,10,0,20,0,8,17,18,57,65,5,0,4,0,10,0,20,0,10,0,2,93,184,0,8,16,185,0,23,0,4,244,184,0,13,16,185,0,32,0,4,244,65,3,0,79,0,35,0,1,113,0,184,0,0,69,88,184,0,3,47,27,185,0,3,0,16,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,186,0,20,0,3,0,0,17,18,57,184,0,20,47,185,0,27,0,2,244,186,0,10,0,20,0,27,17,18,57,184,0,3,16,185,0,18,0,2,244,184,0,0,16,185,0,29,0,2,244,48,49,1,65,3,0,4,0,6,0,1,93,65,7,0,22,0,6,0,38,0,6,0,54,0,6,0,3,93,65,3,0,71,0,6,0,1,93,65,7,0,89,0,10,0,105,0,10,0,121,0,10,0,3,93,65,3,0,135,0,11,0,1,93,65,3,0,5,0,15,0,1,93,65,3,0,133,0,15,0,1,93,0,65,3,0,70,0,6,0,1,93,65,9,0,7,0,6,0,23,0,6,0,39,0,6,0,55,0,6,0,4,93,65,3,0,133,0,11,0,1,93,65,3,0,8,0,15,0,1,93,65,3,0,138,0,15,0,1,93,33,35,17,51,50,30,2,21,20,7,30,1,21,20,14,2,3,35,21,51,50,53,52,38,7,35,21,51,50,54,53,52,1,34,216,146,57,85,56,28,49,54,47,36,59,75,75,86,103,85,52,16,120,95,70,69,2,48,12,32,55,43,80,39,19,63,52,49,64,37,15,1,224,148,74,44,30,224,175,36,49,90,0,0,1,0,39,255,245,1,245,2,59,0,29,1,180,186,0,12,0,5,0,3,43,65,3,0,15,0,5,0,1,93,65,3,0,47,0,5,0,1,93,65,3,0,128,0,5,0,1,93,65,3,0,128,0,12,0,1,93,65,3,0,192,0,12,0,1,93,65,3,0,0,0,12,0,1,113,65,3,0,224,0,12,0,1,93,65,3,0,160,0,12,0,1,93,65,3,0,48,0,12,0,1,93,65,3,0,16,0,12,0,1,93,184,0,5,16,185,0,20,0,4,244,184,0,12,16,184,0,28,208,0,184,0,0,69,88,184,0,10,47,27,185,0,10,0,16,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,184,0,10,16,184,0,13,220,65,3,0,95,0,13,0,1,113,184,0,10,16,185,0,15,0,2,244,184,0,0,16,185,0,25,0,2,244,184,0,0,16,184,0,27,220,65,3,0,80,0,27,0,1,113,48,49,1,65,3,0,137,0,2,0,1,93,65,3,0,56,0,8,0,1,93,65,3,0,136,0,8,0,1,93,65,11,0,71,0,11,0,87,0,11,0,103,0,11,0,119,0,11,0,135,0,11,0,5,93,65,5,0,23,0,11,0,39,0,11,0,2,113,0,65,3,0,56,0,2,0,1,93,65,3,0,138,0,2,0,1,93,65,3,0,131,0,8,0,1,93,65,3,0,54,0,8,0,1,93,65,5,0,17,0,11,0,33,0,11,0,2,113,65,11,0,70,0,11,0,86,0,11,0,102,0,11,0,118,0,11,0,134,0,11,0,5,93,65,11,0,70,0,12,0,86,0,12,0,102,0,12,0,118,0,12,0,134,0,12,0,5,93,65,11,0,73,0,28,0,89,0,28,0,105,0,28,0,121,0,28,0,137,0,28,0,5,93,65,11,0,74,0,29,0,90,0,29,0,106,0,29,0,122,0,29,0,138,0,29,0,5,93,65,5,0,27,0,29,0,43,0,29,0,2,113,5,34,46,2,53,52,62,2,51,50,23,7,38,35,34,14,2,21,20,30,2,51,50,55,23,6,1,79,65,109,78,44,44,78,109,65,97,69,10,91,65,47,72,49,26,26,49,73,47,64,91,10,73,11,42,76,108,65,65,107,77,42,33,87,32,30,53,75,45,45,75,53,30,32,88,32,0,0,0,2,0,74,0,0,2,78,2,48,0,12,0,21,0,235,186,0,8,0,1,0,3,43,65,3,0,207,0,1,0,1,93,65,3,0,15,0,1,0,1,93,65,3,0,175,0,1,0,1,93,65,3,0,16,0,1,0,1,93,65,3,0,96,0,8,0,1,93,65,3,0,224,0,8,0,1,93,65,3,0,32,0,8,0,1,113,65,3,0,0,0,8,0,1,113,65,3,0,176,0,8,0,1,93,65,3,0,64,0,8,0,1,93,65,5,0,16,0,8,0,32,0,8,0,2,93,184,0,1,16,185,0,15,0,4,244,184,0,8,16,185,0,19,0,4,244,0,184,0,0,69,88,184,0,3,47,27,185,0,3,0,16,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,184,0,3,16,185,0,13,0,2,244,184,0,0,16,185,0,16,0,2,244,48,49,1,65,3,0,135,0,5,0,1,93,65,3,0,133,0,10,0,1,93,0,65,3,0,133,0,5,0,1,93,65,3,0,136,0,10,0,1,93,65,3,0,138,0,11,0,1,93,33,35,17,51,50,30,2,21,20,14,2,3,35,17,51,50,54,53,52,38,1,39,221,221,64,110,78,43,44,78,109,64,128,128,94,99,99,2,48,39,72,104,65,66,104,72,38,1,216,254,128,102,90,90,102,0,0,0,1,0,74,0,0,1,197,2,48,0,11,0,152,186,0,0,0,1,0,3,43,65,3,0,16,0,0,0,1,93,65,3,0,224,0,0,0,1,93,65,3,0,16,0,1,0,1,93,184,0,0,16,184,0,4,208,184,0,4,47,184,0,1,16,185,0,10,0,4,244,184,0,6,208,186,0,8,0,0,0,1,17,18,57,184,0,8,47,0,184,0,0,69,88,184,0,2,47,27,185,0,2,0,16,62,89,184,0,0,69,88,184,0,1,47,27,185,0,1,0,6,62,89,184,0,2,16,185,0,5,0,2,244,186,0,6,0,2,0,1,17,18,57,184,0,6,47,185,0,9,0,2,244,184,0,1,16,185,0,10,0,2,244,48,49,41,1,17,33,21,33,21,51,21,35,21,33,1,197,254,133,1,115,254,236,217,217,1,28,2,48,88,136,88,160,0,1,0,74,0,0,1,182,2,48,0,9,0,166,186,0,0,0,7,0,3,43,65,3,0,175,0,0,0,1,93,65,3,0,16,0,0,0,1,93,65,3,0,176,0,0,0,1,93,65,3,0,175,0,7,0,1,93,65,3,0,16,0,7,0,1,93,65,3,0,176,0,7,0,1,93,184,0,7,16,185,0,6,0,4,244,184,0,2,208,186,0,3,0,0,0,7,17,18,57,184,0,3,47,0,184,0,0,69,88,184,0,8,47,27,185,0,8,0,16,62,89,184,0,0,69,88,184,0,6,47,27,185,0,6,0,6,62,89,184,0,8,16,185,0,1,0,2,244,186,0,2,0,8,0,6,17,18,57,184,0,2,47,185,0,5,0,2,244,65,3,0,165,0,7,0,1,93,48,49,1,33,21,51,21,35,21,35,17,33,1,182,254,241,210,210,93,1,108,1,216,136,88,248,2,48,0,0,0,1,0,39,255,245,2,22,2,59,0,32,1,48,186,0,27,0,5,0,3,43,65,3,0,80,0,27,0,1,93,65,3,0,112,0,27,0,1,93,186,0,12,0,27,0,5,17,18,57,184,0,12,47,184,0,5,16,185,0,18,0,4,244,184,0,27,16,185,0,24,0,4,244,184,0,27,16,184,0,26,208,184,0,26,47,0,184,0,0,69,88,184,0,10,47,27,185,0,10,0,16,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,184,0,10,16,184,0,13,220,184,0,10,16,185,0,15,0,2,244,184,0,0,16,185,0,21,0,2,244,186,0,26,0,10,0,0,17,18,57,184,0,26,47,185,0,25,0,2,244,48,49,1,65,3,0,137,0,2,0,1,93,65,3,0,136,0,7,0,1,93,65,3,0,136,0,8,0,1,93,65,5,0,21,0,16,0,37,0,16,0,2,93,65,3,0,21,0,20,0,1,93,65,3,0,38,0,20,0,1,93,0,65,3,0,138,0,2,0,1,93,65,3,0,135,0,7,0,1,93,65,3,0,134,0,8,0,1,93,65,9,0,85,0,11,0,101,0,11,0,117,0,11,0,133,0,11,0,4,93,65,3,0,69,0,12,0,1,93,65,9,0,86,0,12,0,102,0,12,0,118,0,12,0,134,0,12,0,4,93,65,3,0,23,0,16,0,1,93,5,34,46,2,53,52,62,2,51,50,23,7,38,35,34,6,21,20,22,51,50,55,53,35,53,51,21,14,3,1,74,63,107,77,44,43,79,110,66,102,75,9,87,79,98,100,105,103,49,42,81,175,17,49,56,57,11,42,76,108,66,65,107,76,42,32,87,31,111,90,94,111,11,114,79,250,8,15,12,7,0,0,0,1,0,74,0,0,2,60,2,48,0,11,0,127,186,0,0,0,5,0,3,43,65,3,0,16,0,0,0,1,93,184,0,0,16,185,0,1,0,4,244,65,3,0,16,0,5,0,1,93,184,0,5,16,185,0,4,0,4,244,184,0,8,208,184,0,1,16,184,0,9,208,0,184,0,0,69,88,184,0,7,47,27,185,0,7,0,16,62,89,184,0,0,69,88,184,0,4,47,27,185,0,4,0,6,62,89,184,0,1,208,186,0,8,0,7,0,4,17,18,57,184,0,8,47,185,0,3,0,2,244,184,0,7,16,184,0,10,208,48,49,33,35,53,33,21,35,17,51,21,33,53,51,2,60,93,254,200,93,93,1,56,93,248,248,2,48,223,223,0,0,0,0,1,0,74,0,0,0,167,2,48,0,3,0,109,187,0,0,0,4,0,1,0,4,43,65,3,0,175,0,0,0,1,93,65,5,0,0,0,0,0,16,0,0,0,2,93,65,3,0,128,0,0,0,1,93,65,3,0,175,0,1,0,1,93,65,3,0,128,0,1,0,1,93,65,5,0,0,0,1,0,16,0,1,0,2,93,0,184,0,0,69,88,184,0,2,47,27,185,0,2,0,16,62,89,184,0,0,69,88,184,0,1,47,27,185,0,1,0,6,62,89,48,49,51,35,17,51,167,93,93,2,48,0,1,255,254,255,118,0,167,2,48,0,10,0,119,187,0,8,0,4,0,7,0,4,43,65,3,0,175,0,7,0,1,93,65,3,0,16,0,7,0,1,93,65,3,0,128,0,7,0,1,93,184,0,7,16,184,0,2,208,184,0,2,47,65,3,0,175,0,8,0,1,93,65,3,0,16,0,8,0,1,93,65,3,0,128,0,8,0,1,93,65,3,0,15,0,12,0,1,93,0,184,0,1,47,184,0,0,69,88,184,0,8,47,27,185,0,8,0,16,62,89,184,0,1,16,185,0,2,0,1,244,48,49,23,35,39,51,50,54,53,17,51,17,20,28,21,9,12,37,27,93,138,66,34,39,2,47,253,186,116,0,2,0,74,0,0,2,0,2,48,0,5,0,9,1,0,186,0,0,0,7,0,3,43,65,5,0,96,0,0,0,112,0,0,0,2,93,65,3,0,32,0,0,0,1,113,65,3,0,217,0,0,0,1,93,65,3,0,240,0,0,0,1,93,65,3,0,0,0,0,0,1,113,65,3,0,64,0,0,0,1,93,65,5,0,16,0,0,0,32,0,0,0,2,93,184,0,0,16,185,0,1,0,4,244,65,11,0,182,0,1,0,198,0,1,0,214,0,1,0,230,0,1,0,246,0,1,0,5,93,65,7,0,6,0,1,0,22,0,1,0,38,0,1,0,3,113,184,0,2,208,184,0,1,16,184,0,3,208,184,0,0,16,184,0,4,208,184,0,0,16,184,0,5,208,65,3,0,223,0,7,0,1,93,65,3,0,16,0,7,0,1,93,184,0,7,16,185,0,6,0,4,244,0,184,0,0,69,88,184,0,9,47,27,185,0,9,0,16,62,89,184,0,0,69,88,184,0,6,47,27,185,0,6,0,6,62,89,184,0,1,208,184,0,9,16,184,0,3,208,186,0,2,0,3,0,1,17,18,57,25,184,0,2,47,24,184,0,5,208,48,49,33,35,3,19,51,11,1,35,17,51,2,0,102,215,215,102,215,130,93,93,1,40,1,8,254,248,254,216,2,48,0,0,0,2,0,8,0,0,2,14,2,48,0,7,0,10,2,64,187,0,7,0,4,0,6,0,4,43,65,3,0,255,0,7,0,1,93,65,3,0,0,0,7,0,1,113,65,3,0,96,0,7,0,1,93,184,0,7,16,184,0,0,208,65,3,0,136,0,0,0,1,93,65,3,0,23,0,0,0,1,113,65,3,0,55,0,0,0,1,93,185,0,1,0,4,244,65,3,0,255,0,6,0,1,93,65,3,0,0,0,6,0,1,113,65,3,0,96,0,6,0,1,93,186,0,9,0,6,0,7,17,18,57,186,0,2,0,1,0,9,17,18,57,184,0,6,16,184,0,5,208,65,3,0,56,0,5,0,1,93,65,3,0,24,0,5,0,1,113,65,3,0,135,0,5,0,1,93,185,0,4,0,4,244,186,0,3,0,4,0,9,17,18,57,186,0,8,0,9,0,1,17,18,57,186,0,10,0,9,0,4,17,18,57,65,3,0,63,0,12,0,1,93,65,3,0,31,0,12,0,1,93,0,184,0,0,69,88,184,0,6,47,27,185,0,6,0,16,62,89,184,0,0,69,88,184,0,4,47,27,185,0,4,0,6,62,89,184,0,1,208,186,0,10,0,6,0,4,17,18,57,184,0,10,47,185,0,3,0,2,244,184,0,6,16,184,0,9,208,65,3,0,42,0,9,0,1,113,48,49,1,65,3,0,167,0,1,0,1,93,65,3,0,120,0,3,0,1,93,65,3,0,168,0,4,0,1,93,65,3,0,136,0,6,0,1,93,65,7,0,216,0,6,0,232,0,6,0,248,0,6,0,3,93,65,13,0,8,0,6,0,24,0,6,0,40,0,6,0,56,0,6,0,72,0,6,0,88,0,6,0,6,113,65,7,0,89,0,6,0,105,0,6,0,121,0,6,0,3,93,65,5,0,86,0,7,0,102,0,7,0,2,93,65,5,0,119,0,7,0,135,0,7,0,2,93,65,7,0,215,0,7,0,231,0,7,0,247,0,7,0,3,93,65,13,0,7,0,7,0,23,0,7,0,39,0,7,0,55,0,7,0,71,0,7,0,87,0,7,0,6,113,65,3,0,136,0,8,0,1,93,65,3,0,89,0,8,0,1,93,65,3,0,86,0,10,0,1,93,65,3,0,135,0,10,0,1,93,0,65,3,0,41,0,9,0,1,93,65,3,0,74,0,9,0,1,93,65,7,0,218,0,9,0,234,0,9,0,250,0,9,0,3,93,65,5,0,10,0,9,0,26,0,9,0,2,113,65,3,0,59,0,9,0,1,93,65,3,0,43,0,9,0,1,113,65,3,0,140,0,9,0,1,93,33,35,39,35,7,35,19,51,19,39,7,2,14,97,55,214,54,98,213,93,29,76,76,141,141,2,48,254,181,189,189,0,0,1,0,46,0,0,2,154,2,48,0,11,2,50,186,0,0,0,6,0,3,43,65,3,0,0,0,0,0,1,113,65,3,0,47,0,0,0,1,93,65,3,0,16,0,0,0,1,93,65,5,0,112,0,0,0,128,0,0,0,2,93,65,3,0,64,0,0,0,1,93,184,0,0,16,185,0,1,0,4,244,184,0,2,208,65,3,0,87,0,2,0,1,93,65,5,0,31,0,6,0,47,0,6,0,2,113,65,3,0,47,0,6,0,1,93,65,3,0,16,0,6,0,1,93,186,0,3,0,6,0,0,17,18,57,184,0,6,16,185,0,5,0,4,244,184,0,4,208,65,3,0,88,0,4,0,1,93,184,0,6,16,184,0,7,208,186,0,8,0,7,0,4,17,18,57,65,3,0,39,0,8,0,1,93,65,3,0,102,0,8,0,1,93,184,0,3,16,184,0,9,208,65,3,0,232,0,9,0,1,93,184,0,0,16,184,0,11,208,186,0,10,0,2,0,11,17,18,57,65,3,0,40,0,10,0,1,93,0,184,0,0,69,88,184,0,7,47,27,185,0,7,0,16,62,89,184,0,0,69,88,184,0,5,47,27,185,0,5,0,6,62,89,184,0,1,208,184,0,7,16,184,0,4,208,65,5,0,27,0,4,0,43,0,4,0,2,113,65,3,0,139,0,4,0,1,93,65,3,0,12,0,4,0,1,113,65,5,0,108,0,4,0,124,0,4,0,2,93,65,5,0,76,0,4,0,92,0,4,0,2,113,65,3,0,251,0,4,0,1,93,65,3,0,91,0,4,0,1,93,65,3,0,234,0,4,0,1,93,65,3,0,73,0,4,0,1,93,184,0,2,208,186,0,3,0,7,0,5,17,18,57,184,0,3,47,184,0,9,208,65,5,0,66,0,9,0,82,0,9,0,2,113,65,7,0,83,0,9,0,99,0,9,0,115,0,9,0,3,93,65,3,0,52,0,9,0,1,113,65,5,0,53,0,9,0,69,0,9,0,2,93,65,3,0,230,0,9,0,1,93,65,5,0,197,0,9,0,213,0,9,0,2,93,65,3,0,132,0,9,0,1,93,65,3,0,4,0,9,0,1,113,65,3,0,243,0,9,0,1,93,65,3,0,18,0,9,0,1,113,65,3,0,33,0,9,0,1,113,184,0,7,16,184,0,10,208,48,49,1,65,3,0,200,0,7,0,1,93,65,3,0,54,0,8,0,1,93,65,3,0,57,0,10,0,1,93,65,3,0,199,0,11,0,1,93,0,65,3,0,38,0,9,0,1,113,33,35,11,3,35,19,51,27,1,51,2,154,98,54,157,159,54,98,81,78,152,150,78,1,136,254,243,1,13,254,120,2,48,254,249,1,7,0,0,0,0,1,0,74,0,0,2,28,2,48,0,9,2,14,186,0,9,0,4,0,3,43,65,3,0,16,0,9,0,1,93,65,5,0,80,0,9,0,96,0,9,0,2,93,65,3,0,176,0,9,0,1,93,65,3,0,175,0,9,0,1,93,65,3,0,224,0,9,0,1,93,65,5,0,128,0,9,0,144,0,9,0,2,93,65,3,0,48,0,9,0,1,93,65,3,0,32,0,9,0,1,113,65,3,0,0,0,9,0,1,113,184,0,9,16,185,0,8,0,4,244,184,0,1,208,65,3,0,176,0,4,0,1,93,65,3,0,207,0,4,0,1,93,65,3,0,175,0,4,0,1,93,65,3,0,16,0,4,0,1,93,65,3,0,144,0,4,0,1,93,184,0,4,16,185,0,3,0,4,244,184,0,6,208,0,184,0,0,69,88,184,0,6,47,27,185,0,6,0,16,62,89,184,0,0,69,88,184,0,3,47,27,185,0,3,0,6,62,89,184,0,1,208,184,0,6,16,184,0,2,208,65,3,0,74,0,2,0,1,113,65,3,0,27,0,2,0,1,113,65,3,0,44,0,2,0,1,113,65,3,0,142,0,2,0,1,93,65,5,0,108,0,2,0,124,0,2,0,2,93,65,3,0,91,0,2,0,1,113,65,5,0,74,0,2,0,90,0,2,0,2,93,65,3,0,250,0,2,0,1,93,65,3,0,10,0,2,0,1,113,65,5,0,41,0,2,0,57,0,2,0,2,93,65,3,0,167,0,4,0,1,93,184,0,1,16,184,0,7,208,65,3,0,83,0,7,0,1,113,65,3,0,68,0,7,0,1,93,65,3,0,85,0,7,0,1,93,65,3,0,53,0,7,0,1,93,65,3,0,38,0,7,0,1,93,65,3,0,245,0,7,0,1,93,65,7,0,4,0,7,0,20,0,7,0,36,0,7,0,3,113,65,3,0,68,0,7,0,1,113,65,3,0,131,0,7,0,1,93,65,5,0,98,0,7,0,114,0,7,0,2,93,184,0,6,16,184,0,8,208,48,49,1,65,3,0,85,0,6,0,1,93,65,3,0,71,0,6,0,1,93,0,65,5,0,122,0,2,0,138,0,2,0,2,93,65,3,0,43,0,2,0,1,113,65,3,0,69,0,7,0,1,93,65,3,0,117,0,7,0,1,93,65,3,0,37,0,7,0,1,113,65,3,0,87,0,7,0,1,93,33,35,1,17,35,17,51,1,17,51,2,28,78,254,217,93,96,1,20,94,1,149,254,107,2,48,254,130,1,126,0,0,0,2,0,39,255,245,2,114,2,59,0,18,0,37,2,43,186,0,17,0,7,0,3,43,65,3,0,79,0,7,0,1,93,65,3,0,159,0,7,0,1,93,65,3,0,111,0,7,0,1,93,65,3,0,15,0,7,0,1,93,65,3,0,128,0,7,0,1,93,65,3,0,0,0,17,0,1,113,65,3,0,128,0,17,0,1,93,65,3,0,32,0,17,0,1,113,65,3,0,224,0,17,0,1,93,65,3,0,176,0,17,0,1,93,184,0,7,16,185,0,26,0,4,244,184,0,17,16,185,0,36,0,4,244,65,3,0,47,0,39,0,1,93,65,3,0,95,0,39,0,1,93,0,184,0,0,69,88,184,0,12,47,27,185,0,12,0,16,62,89,184,0,0,69,88,184,0,2,47,27,185,0,2,0,6,62,89,184,0,12,16,185,0,21,0,2,244,184,0,2,16,185,0,31,0,2,244,48,49,1,65,3,0,134,0,0,0,1,93,65,3,0,138,0,5,0,1,93,65,3,0,137,0,9,0,1,93,65,3,0,135,0,14,0,1,93,65,3,0,135,0,15,0,1,93,65,3,0,181,0,19,0,1,93,65,3,0,166,0,19,0,1,93,65,5,0,24,0,19,0,40,0,19,0,2,93,65,3,0,121,0,19,0,1,93,65,5,0,23,0,23,0,39,0,23,0,2,93,65,3,0,168,0,24,0,1,93,65,3,0,185,0,24,0,1,93,65,5,0,22,0,29,0,38,0,29,0,2,93,65,3,0,168,0,29,0,1,93,65,3,0,185,0,29,0,1,93,65,3,0,120,0,33,0,1,93,65,5,0,25,0,33,0,41,0,33,0,2,93,65,3,0,165,0,34,0,1,93,65,3,0,182,0,34,0,1,93,0,65,3,0,137,0,0,0,1,93,65,3,0,136,0,5,0,1,93,65,3,0,134,0,9,0,1,93,65,3,0,135,0,14,0,1,93,65,3,0,134,0,15,0,1,93,65,3,0,166,0,19,0,1,93,65,3,0,183,0,19,0,1,93,65,5,0,24,0,19,0,40,0,19,0,2,93,65,3,0,182,0,24,0,1,93,65,3,0,167,0,24,0,1,93,65,5,0,24,0,24,0,40,0,24,0,2,93,65,5,0,23,0,29,0,39,0,29,0,2,93,65,3,0,169,0,29,0,1,93,65,3,0,186,0,29,0,1,93,65,5,0,22,0,33,0,38,0,33,0,2,93,65,3,0,118,0,33,0,1,93,65,5,0,168,0,34,0,184,0,34,0,2,93,37,6,35,34,46,2,53,52,62,2,51,50,30,2,21,20,3,38,35,34,14,2,21,20,30,2,51,50,62,2,53,52,2,31,83,128,64,108,78,43,43,78,108,64,64,108,78,44,153,50,91,46,71,49,25,25,49,71,46,46,71,49,25,69,80,42,76,108,65,65,107,77,42,42,77,107,65,131,1,22,56,29,54,75,45,45,75,54,29,30,53,75,45,91,0,0,0,0,2,255,248,0,0,2,193,2,48,0,15,0,18,1,118,186,0,0,0,1,0,3,43,65,3,0,16,0,0,0,1,93,65,3,0,15,0,0,0,1,113,65,3,0,144,0,0,0,1,93,65,3,0,96,0,0,0,1,93,65,3,0,15,0,1,0,1,113,65,3,0,127,0,1,0,1,93,184,0,1,16,184,0,5,208,65,3,0,170,0,5,0,1,93,65,3,0,26,0,5,0,1,93,65,3,0,38,0,5,0,1,93,185,0,4,0,4,244,184,0,1,16,184,0,16,208,186,0,3,0,4,0,16,17,18,57,65,3,0,250,0,3,0,1,93,184,0,6,208,65,5,0,234,0,6,0,250,0,6,0,2,93,65,7,0,106,0,6,0,122,0,6,0,138,0,6,0,3,93,65,5,0,25,0,6,0,41,0,6,0,2,113,65,3,0,89,0,6,0,1,93,184,0,0,16,184,0,8,208,184,0,8,47,184,0,1,16,185,0,14,0,4,244,184,0,10,208,184,0,0,16,184,0,12,208,184,0,12,47,186,0,18,0,16,0,4,17,18,57,65,3,0,86,0,18,0,1,93,65,3,0,38,0,18,0,1,93,0,184,0,0,69,88,184,0,6,47,27,185,0,6,0,16,62,89,184,0,0,69,88,184,0,1,47,27,185,0,1,0,6,62,89,186,0,16,0,1,0,6,17,18,57,184,0,16,47,185,0,2,0,2,244,184,0,1,16,184,0,4,208,184,0,6,16,185,0,9,0,2,244,186,0,10,0,6,0,1,17,18,57,184,0,10,47,185,0,13,0,2,244,184,0,1,16,185,0,14,0,2,244,184,0,9,16,184,0,17,208,65,3,0,42,0,17,0,1,113,48,49,41,1,53,35,7,35,1,33,21,33,21,51,21,35,21,33,37,53,7,2,193,254,142,175,74,94,1,34,1,159,254,253,200,200,1,11,254,142,132,138,138,2,48,89,135,88,160,140,241,241,0,2,0,74,0,0,1,227,2,48,0,14,0,23,1,63,186,0,10,0,3,0,3,43,65,3,0,16,0,3,0,1,93,65,3,0,207,0,3,0,1,93,65,3,0,176,0,3,0,1,93,65,3,0,48,0,3,0,1,93,184,0,3,16,185,0,2,0,4,244,65,3,0,48,0,10,0,1,93,65,3,0,176,0,10,0,1,93,65,3,0,112,0,10,0,1,93,65,3,0,16,0,10,0,1,93,65,5,0,16,0,10,0,32,0,10,0,2,113,184,0,17,208,184,0,10,16,185,0,21,0,4,244,0,184,0,0,69,88,184,0,4,47,27,185,0,4,0,16,62,89,184,0,0,69,88,184,0,2,47,27,185,0,2,0,6,62,89,186,0,1,0,4,0,2,17,18,57,184,0,1,47,184,0,4,16,185,0,16,0,2,244,184,0,1,16,185,0,17,0,2,244,48,49,1,65,3,0,135,0,7,0,1,93,65,5,0,165,0,8,0,181,0,8,0,2,93,65,3,0,6,0,8,0,1,93,65,3,0,134,0,8,0,1,93,65,3,0,198,0,8,0,1,93,65,3,0,23,0,8,0,1,93,65,3,0,6,0,12,0,1,93,0,65,3,0,134,0,7,0,1,93,65,3,0,134,0,8,0,1,93,65,3,0,198,0,8,0,1,93,65,5,0,7,0,8,0,23,0,8,0,2,93,65,5,0,167,0,8,0,183,0,8,0,2,93,65,3,0,9,0,12,0,1,93,37,35,21,35,17,51,50,30,2,21,20,14,2,3,35,21,51,50,54,53,52,38,1,33,119,96,180,54,86,60,29,36,56,69,62,90,104,60,53,55,188,188,2,48,15,39,68,54,56,75,45,20,1,37,207,51,57,54,45,0,0,0,2,0,39,255,245,2,114,2,59,0,21,0,43,2,248,186,0,19,0,9,0,3,43,65,3,0,224,0,19,0,1,93,65,3,0,32,0,19,0,1,113,65,3,0,0,0,19,0,1,113,65,3,0,176,0,19,0,1,93,65,3,0,128,0,19,0,1,93,65,3,0,111,0,9,0,1,93,65,3,0,15,0,9,0,1,93,65,3,0,159,0,9,0,1,93,65,3,0,79,0,9,0,1,93,65,3,0,128,0,9,0,1,93,186,0,21,0,19,0,9,17,18,57,184,0,21,16,184,0,0,208,184,0,0,47,186,0,2,0,9,0,19,17,18,57,184,0,9,16,185,0,27,0,4,244,184,0,19,16,185,0,39,0,4,244,186,0,34,0,27,0,39,17,18,57,65,3,0,106,0,34,0,1,93,65,3,0,121,0,34,0,1,93,184,0,34,16,184,0,35,208,184,0,35,47,65,3,0,47,0,35,0,1,113,65,3,0,127,0,35,0,1,93,65,5,0,31,0,35,0,47,0,35,0,2,93,186,0,37,0,39,0,27,17,18,57,65,3,0,47,0,45,0,1,93,65,3,0,95,0,45,0,1,93,0,184,0,0,69,88,184,0,14,47,27,185,0,14,0,16,62,89,184,0,0,69,88,184,0,4,47,27,185,0,4,0,6,62,89,186,0,2,0,4,0,14,17,18,57,184,0,2,16,184,0,1,208,184,0,1,47,186,0,21,0,14,0,4,17,18,57,65,3,0,135,0,21,0,1,93,184,0,14,16,185,0,22,0,2,244,184,0,4,16,185,0,32,0,2,244,186,0,34,0,32,0,22,17,18,57,186,0,37,0,22,0,32,17,18,57,184,0,37,16,184,0,36,208,184,0,36,47,48,49,1,65,5,0,23,0,2,0,39,0,2,0,2,113,65,3,0,137,0,2,0,1,93,65,3,0,136,0,3,0,1,93,65,3,0,137,0,6,0,1,93,65,3,0,137,0,7,0,1,93,65,3,0,138,0,11,0,1,93,65,3,0,133,0,17,0,1,93,65,3,0,19,0,21,0,1,113,65,3,0,36,0,21,0,1,113,65,5,0,20,0,24,0,36,0,24,0,2,93,65,5,0,22,0,29,0,38,0,29,0,2,93,65,3,0,117,0,30,0,1,93,65,3,0,184,0,30,0,1,93,65,3,0,169,0,30,0,1,93,65,3,0,24,0,34,0,1,113,65,3,0,43,0,34,0,1,113,65,3,0,138,0,35,0,1,93,65,3,0,23,0,37,0,1,113,65,3,0,40,0,37,0,1,113,65,3,0,121,0,42,0,1,93,65,5,0,26,0,42,0,42,0,42,0,2,93,0,65,3,0,25,0,2,0,1,113,65,3,0,42,0,2,0,1,113,65,3,0,138,0,3,0,1,93,65,3,0,136,0,7,0,1,93,65,3,0,134,0,11,0,1,93,65,3,0,134,0,16,0,1,93,65,3,0,39,0,21,0,1,113,65,3,0,182,0,24,0,1,93,65,3,0,167,0,24,0,1,93,65,5,0,24,0,24,0,40,0,24,0,2,93,65,3,0,118,0,30,0,1,93,65,5,0,168,0,30,0,184,0,30,0,2,93,65,5,0,24,0,34,0,40,0,34,0,2,113,65,3,0,37,0,36,0,1,113,65,3,0,20,0,37,0,1,113,65,3,0,117,0,37,0,1,93,65,3,0,37,0,37,0,1,113,65,3,0,121,0,42,0,1,93,37,7,39,6,35,34,46,2,53,52,62,2,51,50,30,2,21,20,7,3,34,14,2,21,20,30,2,51,50,55,39,55,23,54,53,52,46,2,2,107,52,57,78,100,64,108,78,43,43,78,108,64,64,108,78,44,59,235,46,71,49,25,25,49,71,46,65,44,80,51,83,33,26,51,73,58,62,44,51,42,76,108,65,65,107,77,42,42,77,107,65,101,80,1,128,29,54,75,45,45,75,54,29,23,60,64,65,46,75,45,75,54,29,0,0,0,0,2,0,74,0,0,2,3,2,48,0,11,0,19,1,143,186,0,9,0,5,0,3,43,65,7,0,16,0,9,0,32,0,9,0,48,0,9,0,3,93,65,3,0,144,0,9,0,1,93,65,3,0,176,0,9,0,1,93,65,3,0,112,0,9,0,1,93,65,3,0,240,0,9,0,1,93,65,5,0,16,0,9,0,32,0,9,0,2,113,65,3,0,16,0,5,0,1,93,65,3,0,175,0,5,0,1,93,65,3,0,48,0,5,0,1,93,65,3,0,176,0,5,0,1,93,65,3,0,144,0,5,0,1,93,186,0,11,0,9,0,5,17,18,57,65,3,0,54,0,11,0,1,93,65,9,0,86,0,11,0,102,0,11,0,118,0,11,0,134,0,11,0,4,93,184,0,11,16,184,0,0,208,65,3,0,70,0,0,0,1,93,184,0,11,16,185,0,2,0,4,244,184,0,1,208,184,0,5,16,185,0,4,0,4,244,184,0,14,208,184,0,9,16,185,0,18,0,4,244,0,184,0,0,69,88,184,0,7,47,27,185,0,7,0,16,62,89,184,0,0,69,88,184,0,4,47,27,185,0,4,0,6,62,89,184,0,1,208,186,0,3,0,7,0,4,17,18,57,184,0,3,47,186,0,11,0,3,0,7,17,18,57,184,0,7,16,185,0,12,0,2,244,184,0,3,16,185,0,14,0,2,244,48,49,1,65,3,0,132,0,8,0,1,93,65,7,0,7,0,8,0,23,0,8,0,39,0,8,0,3,93,65,3,0,133,0,10,0,1,93,65,3,0,118,0,10,0,1,93,65,3,0,122,0,19,0,1,93,0,65,3,0,5,0,8,0,1,93,65,3,0,134,0,8,0,1,93,65,3,0,23,0,8,0,1,93,65,3,0,138,0,10,0,1,93,65,3,0,120,0,19,0,1,93,33,35,39,35,21,35,17,51,50,21,20,7,39,35,21,51,50,54,53,52,2,3,99,128,118,96,204,205,105,112,96,106,52,58,212,212,2,48,162,110,52,247,183,48,45,90,0,0,0,0,1,0,41,255,245,1,221,2,59,0,48,2,215,186,0,44,0,16,0,3,43,65,3,0,47,0,16,0,1,93,65,3,0,111,0,16,0,1,93,65,3,0,15,0,16,0,1,93,65,3,0,79,0,16,0,1,93,65,3,0,16,0,16,0,1,93,65,3,0,48,0,16,0,1,93,65,3,0,80,0,44,0,1,93,65,3,0,176,0,44,0,1,93,65,3,0,208,0,44,0,1,93,65,7,0,112,0,44,0,128,0,44,0,144,0,44,0,3,93,65,3,0,48,0,44,0,1,93,65,3,0,16,0,44,0,1,93,186,0,2,0,16,0,44,17,18,57,184,0,2,47,184,0,44,16,185,0,7,0,4,244,186,0,26,0,44,0,16,17,18,57,184,0,26,47,184,0,16,16,185,0,34,0,4,244,0,184,0,0,69,88,184,0,21,47,27,185,0,21,0,16,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,184,0,3,220,65,3,0,32,0,3,0,1,93,184,0,0,16,185,0,5,0,2,244,186,0,11,0,0,0,21,17,18,57,65,3,0,138,0,11,0,1,93,65,7,0,89,0,11,0,105,0,11,0,121,0,11,0,3,93,184,0,21,16,184,0,27,220,65,3,0,47,0,27,0,1,93,65,3,0,144,0,27,0,1,93,184,0,21,16,185,0,29,0,2,244,186,0,37,0,21,0,0,17,18,57,48,49,1,65,3,0,121,0,9,0,1,93,65,3,0,25,0,14,0,1,93,65,3,0,121,0,14,0,1,93,65,3,0,43,0,14,0,1,93,65,3,0,9,0,19,0,1,93,65,13,0,55,0,25,0,71,0,25,0,87,0,25,0,103,0,25,0,119,0,25,0,135,0,25,0,6,93,65,3,0,133,0,36,0,1,93,65,3,0,135,0,39,0,1,93,65,3,0,6,0,41,0,1,93,65,3,0,38,0,41,0,1,93,65,3,0,23,0,41,0,1,93,65,3,0,87,0,41,0,1,93,65,3,0,37,0,42,0,1,93,65,3,0,101,0,42,0,1,93,65,3,0,22,0,42,0,1,93,65,5,0,6,0,47,0,22,0,47,0,2,93,0,65,15,0,58,0,1,0,74,0,1,0,90,0,1,0,106,0,1,0,122,0,1,0,138,0,1,0,154,0,1,0,7,93,65,3,0,43,0,1,0,1,113,65,3,0,28,0,1,0,1,113,65,13,0,58,0,2,0,74,0,2,0,90,0,2,0,106,0,2,0,122,0,2,0,138,0,2,0,6,93,65,3,0,121,0,9,0,1,93,65,3,0,41,0,14,0,1,93,65,3,0,121,0,14,0,1,93,65,3,0,26,0,14,0,1,93,65,3,0,5,0,19,0,1,93,65,13,0,53,0,25,0,69,0,25,0,85,0,25,0,101,0,25,0,117,0,25,0,133,0,25,0,6,93,65,3,0,134,0,39,0,1,93,65,3,0,84,0,41,0,1,93,65,3,0,6,0,41,0,1,93,65,5,0,23,0,41,0,39,0,41,0,2,93,65,3,0,22,0,42,0,1,93,65,3,0,102,0,42,0,1,93,65,3,0,39,0,42,0,1,93,65,3,0,40,0,47,0,1,93,65,5,0,10,0,47,0,26,0,47,0,2,93,23,34,39,55,22,51,50,53,52,46,2,47,1,46,1,53,52,62,2,51,50,30,2,23,7,38,35,34,14,2,21,20,30,2,23,30,3,21,20,14,2,246,129,67,12,71,115,126,29,53,75,46,48,35,47,26,52,81,56,27,55,49,42,15,10,102,70,24,45,34,20,26,53,78,53,23,46,36,23,15,49,91,11,39,107,58,70,24,34,26,23,14,21,15,54,48,31,60,46,28,7,11,15,8,96,50,8,16,26,18,24,26,20,22,20,9,24,35,51,36,24,56,48,32,0,0,0,0,1,0,17,0,0,1,197,2,48,0,7,0,113,187,0,1,0,4,0,4,0,4,43,65,3,0,176,0,1,0,1,93,184,0,1,16,184,0,0,220,65,3,0,176,0,4,0,1,93,184,0,4,16,184,0,5,220,65,3,0,15,0,9,0,1,93,65,3,0,112,0,9,0,1,93,0,184,0,0,69,88,184,0,6,47,27,185,0,6,0,16,62,89,184,0,0,69,88,184,0,3,47,27,185,0,3,0,6,62,89,184,0,6,16,185,0,5,0,2,244,184,0,1,208,48,49,1,35,17,35,17,35,53,33,1,197,171,94,171,1,180,1,216,254,40,1,216,88,0,0,0,0,1,0,67,255,245,2,48,2,48,0,21,1,39,186,0,18,0,4,0,3,43,65,3,0,175,0,4,0,1,93,65,3,0,223,0,4,0,1,93,65,3,0,16,0,4,0,1,93,184,0,4,16,185,0,5,0,4,244,65,3,0,240,0,18,0,1,93,65,3,0,223,0,18,0,1,93,65,3,0,175,0,18,0,1,93,65,3,0,16,0,18,0,1,93,65,3,0,16,0,18,0,1,113,184,0,18,16,185,0,17,0,4,244,0,184,0,0,69,88,184,0,5,47,27,185,0,5,0,16,62,89,184,0,0,69,88,184,0,0,47,27,185,0,0,0,6,62,89,185,0,11,0,2,244,184,0,5,16,184,0,17,208,48,49,1,65,3,0,88,0,1,0,1,93,65,5,0,55,0,9,0,71,0,9,0,2,93,65,5,0,57,0,13,0,73,0,13,0,2,93,65,3,0,85,0,20,0,1,93,65,3,0,103,0,20,0,1,93,65,5,0,88,0,21,0,104,0,21,0,2,93,0,65,3,0,105,0,1,0,1,93,65,3,0,90,0,1,0,1,93,65,3,0,54,0,9,0,1,93,65,3,0,71,0,9,0,1,93,65,3,0,70,0,13,0,1,93,65,3,0,55,0,13,0,1,93,65,3,0,104,0,20,0,1,93,65,5,0,89,0,21,0,105,0,21,0,2,93,5,34,38,53,17,51,17,20,30,2,51,50,62,2,53,17,51,17,20,6,1,58,123,124,93,14,36,59,45,47,60,34,12,93,123,11,133,117,1,65,254,226,46,73,51,27,30,53,72,42,1,30,254,191,118,132,0,0,0,0,1,0,6,0,0,2,42,2,48,0,6,1,51,187,0,1,0,4,0,2,0,4,43,65,3,0,176,0,1,0,1,93,65,3,0,96,0,1,0,1,93,184,0,1,16,184,0,0,208,65,3,0,56,0,0,0,1,93,65,3,0,118,0,0,0,1,93,65,3,0,96,0,2,0,1,93,65,3,0,176,0,2,0,1,93,184,0,2,16,184,0,3,208,65,3,0,121,0,3,0,1,93,65,3,0,55,0,3,0,1,93,185,0,4,0,4,244,186,0,5,0,2,0,1,17,18,57,184,0,0,16,185,0,6,0,4,244,0,184,0,0,69,88,184,0,4,47,27,185,0,4,0,16,62,89,184,0,0,69,88,184,0,2,47,27,185,0,2,0,6,62,89,184,0,5,208,65,3,0,70,0,5,0,1,93,65,5,0,85,0,5,0,101,0,5,0,2,93,184,0,4,16,184,0,6,208,48,49,1,65,13,0,167,0,1,0,183,0,1,0,199,0,1,0,215,0,1,0,231,0,1,0,247,0,1,0,6,93,65,7,0,7,0,1,0,23,0,1,0,39,0,1,0,3,113,65,13,0,168,0,2,0,184,0,2,0,200,0,2,0,216,0,2,0,232,0,2,0,248,0,2,0,6,93,65,7,0,8,0,2,0,24,0,2,0,40,0,2,0,3,113,0,65,3,0,130,0,5,0,1,93,65,3,0,116,0,5,0,1,93,1,3,35,3,51,27,1,2,42,220,106,222,98,177,175,2,48,253,208,2,48,254,70,1,186,0,0,0,1,0,17,0,0,3,54,2,48,0,12,2,97,186,0,10,0,9,0,3,43,65,3,0,175,0,10,0,1,93,65,3,0,39,0,10,0,1,93,65,3,0,16,0,10,0,1,93,184,0,10,16,184,0,1,220,184,0,0,208,65,3,0,103,0,0,0,1,93,65,3,0,6,0,0,0,1,93,184,0,1,16,185,0,2,0,4,244,65,3,0,41,0,2,0,1,93,65,3,0,175,0,9,0,1,93,65,3,0,16,0,9,0,1,93,186,0,3,0,9,0,10,17,18,57,184,0,9,16,184,0,5,220,185,0,4,0,4,244,184,0,5,16,184,0,6,208,65,3,0,9,0,6,0,1,93,65,3,0,104,0,6,0,1,93,185,0,7,0,4,244,186,0,8,0,5,0,4,17,18,57,186,0,11,0,2,0,1,17,18,57,184,0,0,16,185,0,12,0,4,244,0,184,0,0,69,88,184,0,7,47,27,185,0,7,0,16,62,89,184,0,0,69,88,184,0,4,47,27,185,0,4,0,6,62,89,184,0,2,208,184,0,7,16,184,0,9,208,184,0,9,47,184,0,3,208,65,9,0,74,0,3,0,90,0,3,0,106,0,3,0,122,0,3,0,4,93,184,0,4,16,184,0,8,208,65,3,0,70,0,8,0,1,93,65,3,0,85,0,8,0,1,93,65,3,0,37,0,8,0,1,113,184,0,11,208,184,0,7,16,184,0,12,208,48,49,1,65,3,0,69,0,1,0,1,113,65,3,0,246,0,1,0,1,93,65,7,0,6,0,1,0,22,0,1,0,38,0,1,0,3,113,65,3,0,200,0,2,0,1,93,65,7,0,73,0,2,0,89,0,2,0,105,0,2,0,3,93,65,3,0,70,0,4,0,1,93,65,3,0,102,0,4,0,1,93,65,3,0,87,0,4,0,1,93,65,3,0,199,0,4,0,1,93,65,3,0,249,0,5,0,1,93,65,7,0,9,0,5,0,25,0,5,0,41,0,5,0,3,113,65,3,0,74,0,5,0,1,113,65,3,0,135,0,7,0,1,93,65,3,0,135,0,8,0,1,93,65,5,0,232,0,9,0,248,0,9,0,2,93,65,7,0,8,0,9,0,24,0,9,0,40,0,9,0,3,113,65,5,0,231,0,10,0,247,0,10,0,2,93,65,7,0,7,0,10,0,23,0,10,0,39,0,10,0,3,113,65,3,0,136,0,12,0,1,93,0,65,5,0,74,0,3,0,90,0,3,0,2,93,65,3,0,138,0,3,0,1,93,65,3,0,107,0,3,0,1,93,65,3,0,251,0,3,0,1,93,65,7,0,11,0,3,0,27,0,3,0,43,0,3,0,3,113,65,3,0,75,0,3,0,1,113,65,3,0,125,0,3,0,1,93,1,3,35,11,1,35,3,51,27,1,51,27,1,3,54,174,93,136,140,95,167,98,126,141,74,145,123,2,48,253,208,1,148,254,108,2,48,254,87,1,165,254,98,1,162,0,1,0,14,0,0,2,17,2,48,0,11,1,176,187,0,11,0,4,0,5,0,4,43,65,5,0,87,0,11,0,103,0,11,0,2,93,65,3,0,48,0,11,0,1,93,184,0,11,16,184,0,0,208,65,3,0,5,0,0,0,1,113,65,3,0,166,0,0,0,1,93,65,3,0,135,0,0,0,1,93,65,3,0,89,0,0,0,1,93,65,3,0,8,0,0,0,1,93,65,3,0,55,0,0,0,1,93,65,3,0,214,0,0,0,1,93,65,3,0,181,0,0,0,1,93,65,3,0,69,0,0,0,1,93,185,0,1,0,4,244,65,3,0,7,0,1,0,1,113,65,3,0,48,0,5,0,1,93,186,0,2,0,5,0,11,17,18,57,184,0,5,16,184,0,4,208,65,3,0,103,0,4,0,1,93,65,3,0,40,0,4,0,1,113,65,3,0,73,0,4,0,1,93,65,3,0,185,0,4,0,1,93,65,3,0,168,0,4,0,1,93,65,3,0,6,0,4,0,1,93,65,3,0,86,0,4,0,1,93,185,0,3,0,4,244,184,0,4,16,184,0,6,208,184,0,3,16,184,0,7,208,186,0,8,0,5,0,11,17,18,57,184,0,1,16,184,0,9,208,184,0,0,16,184,0,10,208,65,3,0,31,0,13,0,1,93,0,184,0,0,69,88,184,0,7,47,27,185,0,7,0,16,62,89,184,0,0,69,88,184,0,3,47,27,185,0,3,0,6,62,89,184,0,1,208,186,0,2,0,3,0,7,17,18,57,186,0,8,0,7,0,3,17,18,57,65,3,0,54,0,8,0,1,93,65,3,0,69,0,8,0,1,93,186,0,5,0,8,0,2,17,18,57,184,0,7,16,184,0,9,208,186,0,11,0,2,0,8,17,18,57,48,49,1,65,3,0,119,0,11,0,1,93,0,65,3,0,122,0,2,0,1,93,65,3,0,139,0,2,0,1,93,65,5,0,117,0,8,0,133,0,8,0,2,93,33,35,39,7,35,19,3,51,23,55,51,3,2,17,104,159,149,103,204,200,108,146,148,103,205,214,214,1,23,1,25,205,205,254,242,0,0,0,0,1,0,1,0,0,1,247,2,48,0,8,1,20,187,0,1,0,4,0,4,0,4,43,65,3,0,48,0,1,0,1,93,65,3,0,144,0,1,0,1,93,184,0,1,16,184,0,0,208,65,3,0,9,0,0,0,1,93,65,3,0,89,0,0,0,1,93,65,3,0,135,0,0,0,1,93,65,3,0,70,0,0,0,1,93,65,3,0,144,0,4,0,1,93,65,3,0,48,0,4,0,1,93,184,0,4,16,184,0,5,208,65,3,0,136,0,5,0,1,93,65,3,0,73,0,5,0,1,93,65,3,0,6,0,5,0,1,93,65,3,0,86,0,5,0,1,93,185,0,6,0,4,244,186,0,7,0,4,0,1,17,18,57,184,0,0,16,185,0,8,0,4,244,0,184,0,0,69,88,184,0,6,47,27,185,0,6,0,16,62,89,184,0,0,69,88,184,0,3,47,27,185,0,3,0,6,62,89,186,0,7,0,6,0,3,17,18,57,65,3,0,38,0,7,0,1,93,184,0,6,16,184,0,8,208,48,49,65,3,0,132,0,7,0,1,93,65,7,0,85,0,7,0,101,0,7,0,117,0,7,0,3,93,65,3,0,246,0,7,0,1,93,65,7,0,6,0,7,0,22,0,7,0,38,0,7,0,3,113,1,3,21,35,53,3,51,23,55,1,247,203,96,203,99,152,152,2,48,254,204,252,252,1,52,225,225,0,0,0,0,1,0,15,0,0,1,212,2,48,0,7,1,79,186,0,2,0,6,0,3,43,65,3,0,64,0,2,0,1,93,65,3,0,223,0,2,0,1,93,65,3,0,176,0,2,0,1,93,65,3,0,96,0,2,0,1,93,184,0,2,16,184,0,0,208,184,0,6,16,184,0,4,208,184,0,1,208,65,3,0,99,0,1,0,1,93,65,3,0,36,0,1,0,1,113,65,3,0,85,0,1,0,1,113,65,3,0,70,0,1,0,1,113,65,3,0,154,0,1,0,1,93,65,3,0,246,0,1,0,1,93,65,5,0,5,0,1,0,21,0,1,0,2,113,65,5,0,68,0,1,0,84,0,1,0,2,93,65,3,0,114,0,1,0,1,93,65,3,0,128,0,1,0,1,93,184,0,0,16,184,0,5,208,65,3,0,249,0,5,0,1,93,65,3,0,90,0,5,0,1,113,65,3,0,43,0,5,0,1,113,65,3,0,108,0,5,0,1,93,65,3,0,143,0,5,0,1,93,65,3,0,125,0,5,0,1,93,65,3,0,91,0,5,0,1,93,65,3,0,74,0,5,0,1,93,65,5,0,10,0,5,0,26,0,5,0,2,113,65,3,0,73,0,5,0,1,113,65,3,0,149,0,5,0,1,93,65,3,0,47,0,9,0,1,93,0,184,0,0,69,88,184,0,7,47,27,185,0,7,0,16,62,89,184,0,0,69,88,184,0,3,47,27,185,0,3,0,6,62,89,185,0,2,0,2,244,184,0,7,16,185,0,6,0,2,244,48,49,9,1,33,21,33,1,33,53,1,212,254,213,1,5,254,97,1,43,254,251,2,48,254,40,88,1,216,88,0,0,0,0,2,0,39,255,245,3,116,2,59,0,26,0,45,2,173,186,0,0,0,1,0,3,43,65,3,0,95,0,0,0,1,93,65,5,0,0,0,0,0,16,0,0,0,2,93,65,3,0,176,0,0,0,1,93,65,5,0,0,0,1,0,16,0,1,0,2,93,65,3,0,255,0,1,0,1,93,65,3,0,95,0,1,0,1,93,65,3,0,176,0,1,0,1,93,65,3,0,144,0,1,0,1,93,184,0,1,16,184,0,9,220,65,3,0,159,0,9,0,1,93,65,3,0,191,0,9,0,1,93,65,3,0,127,0,9,0,1,93,65,5,0,15,0,9,0,31,0,9,0,2,93,184,0,1,16,184,0,16,208,184,0,0,16,184,0,19,208,184,0,19,47,184,0,1,16,185,0,25,0,4,244,184,0,21,208,186,0,23,0,0,0,1,17,18,57,184,0,23,47,184,0,9,16,185,0,34,0,4,244,184,0,1,16,184,0,44,208,65,5,0,121,0,44,0,137,0,44,0,2,93,0,184,0,0,69,88,184,0,14,47,27,185,0,14,0,16,62,89,184,0,0,69,88,184,0,17,47,27,185,0,17,0,16,62,89,184,0,0,69,88,184,0,4,47,27,185,0,4,0,6,62,89,184,0,0,69,88,184,0,1,47,27,185,0,1,0,6,62,89,186,0,2,0,4,0,14,17,18,57,65,5,0,27,0,2,0,43,0,2,0,2,113,65,5,0,58,0,2,0,74,0,2,0,2,113,186,0,16,0,14,0,4,17,18,57,65,9,0,20,0,16,0,36,0,16,0,52,0,16,0,68,0,16,0,4,113,184,0,17,16,185,0,20,0,2,244,186,0,21,0,17,0,1,17,18,57,184,0,21,47,185,0,24,0,2,244,184,0,1,16,185,0,25,0,2,244,184,0,14,16,185,0,29,0,2,244,184,0,4,16,185,0,39,0,2,244,48,49,1,65,3,0,136,0,6,0,1,93,65,3,0,138,0,7,0,1,93,65,3,0,137,0,11,0,1,93,65,3,0,136,0,12,0,1,93,65,3,0,56,0,15,0,1,93,65,3,0,41,0,27,0,1,93,65,3,0,137,0,27,0,1,93,65,3,0,169,0,27,0,1,93,65,3,0,38,0,31,0,1,93,65,3,0,39,0,37,0,1,93,65,3,0,40,0,41,0,1,93,65,3,0,136,0,41,0,1,93,65,3,0,168,0,41,0,1,93,65,3,0,169,0,42,0,1,93,0,65,3,0,73,0,3,0,1,93,65,3,0,58,0,3,0,1,93,65,3,0,137,0,6,0,1,93,65,3,0,136,0,7,0,1,93,65,3,0,134,0,11,0,1,93,65,3,0,134,0,12,0,1,93,65,3,0,51,0,15,0,1,93,65,3,0,69,0,15,0,1,93,65,3,0,168,0,27,0,1,93,65,3,0,41,0,27,0,1,93,65,3,0,137,0,27,0,1,93,65,3,0,40,0,31,0,1,93,65,3,0,38,0,37,0,1,93,65,3,0,38,0,41,0,1,93,65,3,0,134,0,41,0,1,93,65,3,0,166,0,41,0,1,93,41,1,53,6,35,34,46,2,53,52,62,2,51,50,23,53,33,21,33,21,51,21,35,21,33,1,38,35,34,14,2,21,20,30,2,51,50,62,2,53,52,3,116,254,153,98,98,64,106,77,43,43,77,106,64,98,98,1,95,254,254,199,199,1,10,254,97,48,92,46,71,48,25,25,48,71,46,46,71,48,24,52,63,42,76,108,65,65,107,77,42,63,52,88,136,88,160,1,83,56,29,54,75,45,45,75,54,29,30,53,75,45,92,0,0,0,1,0,74,0,0,1,172,2,48,0,5,0,124,186,0,5,0,1,0,3,43,65,3,0,16,0,1,0,1,93,65,3,0,175,0,1,0,1,93,65,3,0,176,0,1,0,1,93,65,3,0,144,0,1,0,1,93,184,0,1,16,185,0,4,0,4,244,65,3,0,144,0,5,0,1,93,65,3,0,16,0,5,0,1,93,65,3,0,176,0,5,0,1,93,0,184,0,0,69,88,184,0,2,47,27,185,0,2,0,16,62,89,184,0,0,69,88,184,0,1,47,27,185,0,1,0,6,62,89,185,0,4,0,2,244,48,49,41,1,17,51,17,33,1,172,254,158,93,1,5,2,48,254,40,0,0,1,0,0,0,1,1,72,59,245,254,62,95,15,60,245,0,31,3,232,0,0,0,0,202,233,78,152,0,0,0,0,202,233,79,52,255,217,255,6,4,141,3,196,0,0,0,9,0,2,0,0,0,0,0,0,0,1,0,0,3,197,255,6,0,0,4,177,255,217,255,213,4,141,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,13,0,250,0,72,0,225,0,0,0,242,0,59,1,146,0,40,2,192,0,33,2,2,0,42,3,72,0,35,2,99,0,36,0,182,0,41,1,5,0,42,1,5,0,24,1,170,0,33,1,207,0,46,0,216,0,57,1,168,0,57,0,204,0,57,2,20,0,19,2,202,0,63,1,99,0,34,2,12,0,50,2,35,0,40,2,47,0,14,2,29,0,51,2,56,0,62,1,246,0,39,2,97,0,59,2,58,0,45,0,204,0,57,0,216,0,57,1,149,0,33,1,246,0,66,1,148,0,60,1,185,0,30,2,210,0,49,2,104,0,7,2,85,0,80,2,104,0,39,2,215,0,80,2,42,0,80,2,11,0,80,2,160,0,39,2,234,0,80,0,255,0,80,0,255,255,239,2,65,0,80,1,245,0,80,3,44,0,48,2,192,0,80,3,0,0,39,2,60,0,80,3,0,0,39,2,91,0,80,2,72,0,40,2,21,0,15,2,212,0,72,2,132,0,4,3,203,0,14,2,87,0,9,2,55,255,253,2,37,0,9,1,71,0,70,2,13,0,35,1,71,0,0,1,255,0,49,2,54,0,3,1,47,0,58,1,224,0,24,2,43,0,60,1,198,0,33,2,43,0,32,2,0,0,31,1,75,0,10,1,242,0,26,2,30,0,60,0,212,0,61,0,212,255,244,1,192,0,60,0,236,0,60,3,109,0,61,2,47,0,61,2,38,0,32,2,45,0,61,2,45,0,33,1,65,0,61,1,158,0,32,1,81,0,18,2,12,0,56,1,236,0,9,2,213,0,12,1,218,0,11,1,249,0,7,1,215,0,22,1,43,0,19,0,229,0,70,1,43,0,2,1,199,0,54,0,225,0,0,0,224,0,50,1,221,0,34,1,244,0,34,2,114,0,61,2,162,0,30,0,232,0,72,1,200,0,37,1,166,0,87,2,208,0,49,1,93,0,33,2,51,0,15,2,84,0,66,1,168,0,57,2,208,0,49,1,77,0,34,1,242,0,64,1,48,0,25,1,54,0,19,1,47,0,58,2,79,0,73,2,110,0,33,0,238,0,57,1,47,0,144,0,216,0,23,1,114,0,33,2,51,0,41,2,205,0,39,2,217,0,36,3,117,0,32,1,193,0,62,2,104,0,7,2,104,0,7,2,104,0,7,2,104,0,7,2,104,0,7,2,104,0,7,3,97,255,249,2,104,0,39,2,42,0,80,2,42,0,80,2,42,0,80,2,42,0,80,0,255,0,35,0,255,0,36,0,255,255,240,0,255,0,5,2,215,255,245,2,192,0,80,3,0,0,39,3,0,0,39,3,0,0,39,3,0,0,39,3,0,0,39,1,183,0,61,3,0,0,39,2,214,0,72,2,214,0,72,2,214,0,72,2,214,0,72,2,55,255,253,2,58,0,80,2,45,0,16,1,224,0,24,1,224,0,24,1,224,0,24,1,224,0,24,1,224,0,24,1,224,0,24,3,30,0,22,1,198,0,33,2,0,0,31,2,0,0,31,2,0,0,31,2,0,0,31,0,212,0,13,0,212,0,14,0,212,255,217,0,212,255,239,2,5,0,28,2,47,0,61,2,38,0,32,2,38,0,32,2,38,0,32,2,38,0,32,2,38,0,32,2,80,0,66,2,58,0,33,2,12,0,56,2,12,0,56,2,12,0,56,2,12,0,56,1,249,0,7,2,68,0,60,1,249,0,7,2,104,0,39,1,198,0,33,0,212,0,61,4,47,0,40,3,134,0,32,2,72,0,40,1,158,0,32,2,55,255,253,2,37,0,9,1,215,0,22,1,95,255,222,0,212,255,244,1,190,0,76,1,190,0,76,1,36,0,42,2,16,0,92,1,246,0,57,2,82,0,57,0,186,0,43,0,169,0,42,0,216,0,57,1,140,0,43,1,123,0,42,1,190,0,57,1,168,0,35,1,204,0,53,1,50,0,44,2,164,0,57,4,177,0,36,1,66,0,14,1,67,0,41,1,151,0,33,1,74,0,5,1,51,0,24,1,66,0,32,1,34,0,23,1,90,0,31,1,68,0,22,1,175,0,45,0,237,0,38,1,76,0,38,1,81,0,32,1,101,0,18,1,76,0,35,1,91,0,45,1,76,0,42,1,116,0,44,1,90,0,32,2,191,0,33,2,215,0,31,2,22,0,74,2,25,0,39,2,117,0,74,1,234,0,74,1,203,0,74,2,71,0,39,2,134,0,74,0,241,0,74,0,241,255,254,2,13,0,74,2,22,0,8,2,200,0,46,2,102,0,74,2,153,0,39,2,230,255,248,1,254,0,74,2,153,0,39,2,25,0,74,1,255,0,41,1,214,0,17,2,115,0,67,2,49,0,6,3,67,0,17,2,28,0,14,1,248,0,1,1,227,0,15,3,153,0,39,1,184,0,74,0,0,0,1,0,0,248,0,0,1,41,83,192,0,0,13,55,242,0,3,0,7,255,248,0,3,0,13,255,146,0,3,0,14,255,234,0,3,0,15,255,146,0,3,0,16,255,220,0,3,0,21,255,237,0,3,0,23,255,245,0,3,0,33,255,234,0,3,0,34,255,213,0,3,0,46,255,238,0,3,0,66,255,243,0,3,0,68,255,236,0,3,0,69,255,236,0,3,0,70,255,236,0,3,0,72,255,241,0,3,0,80,255,236,0,3,0,82,255,236,0,3,0,84,255,244,0,3,0,107,255,241,0,3,0,127,255,213,0,3,0,128,255,213,0,3,0,129,255,213,0,3,0,130,255,213,0,3,0,131,255,213,0,3,0,132,255,213,0,3,0,133,255,203,0,3,0,159,255,243,0,3,0,160,255,243,0,3,0,161,255,243,0,3,0,162,255,243,0,3,0,163,255,243,0,3,0,164,255,243,0,3,0,165,255,243,0,3,0,166,255,236,0,3,0,167,255,236,0,3,0,168,255,236,0,3,0,169,255,236,0,3,0,170,255,236,0,3,0,173,0,29,0,3,0,175,255,237,0,3,0,177,255,236,0,3,0,178,255,236,0,3,0,179,255,236,0,3,0,180,255,236,0,3,0,181,255,236,0,3,0,183,255,236,0,3,0,195,255,236,0,3,0,197,255,244,0,3,0,207,255,234,0,3,0,208,255,234,0,3,0,211,255,146,0,3,0,214,255,146,0,3,0,218,255,146,0,3,0,220,255,241,0,7,0,3,255,210,0,7,0,8,255,210,0,7,0,53,255,202,0,7,0,55,255,217,0,7,0,56,255,233,0,7,0,58,255,203,0,7,0,71,255,242,0,7,0,77,255,251,0,7,0,85,255,235,0,7,0,86,255,250,0,7,0,87,255,243,0,7,0,88,255,247,0,7,0,90,255,240,0,7,0,156,255,203,0,7,0,158,255,243,0,7,0,184,255,250,0,7,0,185,255,250,0,7,0,186,255,250,0,7,0,187,255,250,0,7,0,188,255,240,0,7,0,190,255,240,0,7,0,198,255,203,0,7,0,210,255,210,0,7,0,213,255,210,0,8,0,173,0,29,0,9,0,17,255,230,0,9,0,21,255,234,0,9,0,23,255,229,0,9,0,25,255,237,0,9,0,26,255,245,0,9,0,35,255,243,0,9,0,36,255,229,0,9,0,37,255,243,0,9,0,38,255,243,0,9,0,39,255,243,0,9,0,40,255,229,0,9,0,41,255,243,0,9,0,42,255,243,0,9,0,43,0,22,0,9,0,44,255,243,0,9,0,45,255,243,0,9,0,46,255,239,0,9,0,47,255,243,0,9,0,48,255,229,0,9,0,49,255,243,0,9,0,50,255,229,0,9,0,51,255,243,0,9,0,52,255,245,0,9,0,54,255,243,0,9,0,66,255,231,0,9,0,68,255,224,0,9,0,69,255,224,0,9,0,70,255,224,0,9,0,71,255,239,0,9,0,72,255,232,0,9,0,78,255,233,0,9,0,79,255,233,0,9,0,80,255,224,0,9,0,81,255,233,0,9,0,82,255,224,0,9,0,83,255,233,0,9,0,84,255,233,0,9,0,85,255,231,0,9,0,86,255,227,0,9,0,87,255,231,0,9,0,88,255,232,0,9,0,90,255,231,0,9,0,91,255,247,0,9,0,134,255,229,0,9,0,135,255,243,0,9,0,136,255,243,0,9,0,137,255,243,0,9,0,138,255,243,0,9,0,139,255,243,0,9,0,140,255,243,0,9,0,141,255,243,0,9,0,142,255,243,0,9,0,143,255,243,0,9,0,144,255,243,0,9,0,145,255,229,0,9,0,146,255,229,0,9,0,147,255,229,0,9,0,148,255,229,0,9,0,149,255,229,0,9,0,151,255,229,0,9,0,152,255,243,0,9,0,153,255,243,0,9,0,154,255,243,0,9,0,155,255,243,0,9,0,157,255,243,0,9,0,158,255,236,0,9,0,159,255,231,0,9,0,160,255,231,0,9,0,161,255,231,0,9,0,162,255,231,0,9,0,163,255,231,0,9,0,164,255,231,0,9,0,165,255,231,0,9,0,166,255,224,0,9,0,167,255,224,0,9,0,168,255,224,0,9,0,169,255,224,0,9,0,170,255,224,0,9,0,175,255,232,0,9,0,176,255,233,0,9,0,177,255,224,0,9,0,178,255,224,0,9,0,179,255,224,0,9,0,180,255,224,0,9,0,181,255,224,0,9,0,183,255,224,0,9,0,184,255,227,0,9,0,185,255,227,0,9,0,186,255,227,0,9,0,187,255,227,0,9,0,188,255,231,0,9,0,189,255,233,0,9,0,190,255,231,0,9,0,194,255,229,0,9,0,195,255,224,0,9,0,196,255,245,0,9,0,197,255,244,0,9,0,200,255,247,0,11,0,46,255,238,0,11,0,53,0,11,0,11,0,55,0,16,0,11,0,56,0,9,0,11,0,72,255,238,0,11,0,133,255,203,0,11,0,171,0,16,0,11,0,172,0,12,0,11,0,173,0,65,0,11,0,174,0,43,0,11,0,175,255,232,0,12,0,18,255,229,0,12,0,19,255,218,0,12,0,20,255,238,0,12,0,24,255,216,0,13,0,3,255,146,0,13,0,8,255,146,0,13,0,17,255,239,0,13,0,18,255,242,0,13,0,209,255,124,0,13,0,210,255,121,0,13,0,212,255,124,0,13,0,213,255,121,0,14,0,3,255,234,0,14,0,8,255,234,0,14,0,52,255,243,0,14,0,53,255,216,0,14,0,55,255,238,0,14,0,56,255,248,0,14,0,57,255,242,0,14,0,58,255,222,0,14,0,59,255,237,0,14,0,71,255,247,0,14,0,85,255,248,0,14,0,89,255,247,0,14,0,91,255,231,0,14,0,156,255,222,0,14,0,158,255,248,0,14,0,196,255,243,0,14,0,198,255,222,0,14,0,199,255,237,0,14,0,200,255,231,0,14,0,210,255,193,0,14,0,213,255,193,0,15,0,3,255,146,0,15,0,8,255,146,0,15,0,17,255,239,0,15,0,18,255,242,0,15,0,36,255,242,0,15,0,40,255,242,0,15,0,48,255,242,0,15,0,50,255,242,0,15,0,53,255,214,0,15,0,54,255,243,0,15,0,55,255,213,0,15,0,56,255,226,0,15,0,58,255,215,0,15,0,71,255,241,0,15,0,85,255,239,0,15,0,87,255,227,0,15,0,88,255,236,0,15,0,90,255,222,0,15,0,134,255,242,0,15,0,145,255,242,0,15,0,146,255,242,0,15,0,147,255,242,0,15,0,148,255,242,0,15,0,149,255,242,0,15,0,151,255,242,0,15,0,152,255,243,0,15,0,153,255,243,0,15,0,154,255,243,0,15,0,155,255,243,0,15,0,156,255,215,0,15,0,158,255,243,0,15,0,188,255,222,0,15,0,190,255,222,0,15,0,194,255,242,0,15,0,198,255,215,0,15,0,209,255,124,0,15,0,210,255,121,0,15,0,212,255,124,0,15,0,213,255,121,0,16,0,16,255,197,0,16,0,17,255,246,0,16,0,21,255,217,0,16,0,23,255,228,0,16,0,34,255,208,0,16,0,36,255,243,0,16,0,40,255,243,0,16,0,46,255,237,0,16,0,48,255,243,0,16,0,50,255,243,0,16,0,58,0,7,0,16,0,66,255,218,0,16,0,68,255,214,0,16,0,69,255,214,0,16,0,70,255,214,0,16,0,72,255,218,0,16,0,78,255,228,0,16,0,79,255,228,0,16,0,80,255,214,0,16,0,81,255,228,0,16,0,82,255,214,0,16,0,83,255,228,0,16,0,84,255,221,0,16,0,86,255,230,0,16,0,91,255,241,0,16,0,127,255,208,0,16,0,128,255,208,0,16,0,129,255,208,0,16,0,130,255,208,0,16,0,131,255,208,0,16,0,132,255,208,0,16,0,133,255,202,0,16,0,134,255,243,0,16,0,145,255,243,0,16,0,146,255,243,0,16,0,147,255,243,0,16,0,148,255,243,0,16,0,149,255,243,0,16,0,151,255,243,0,16,0,156,0,7,0,16,0,159,255,218,0,16,0,160,255,218,0,16,0,161,255,218,0,16,0,162,255,218,0,16,0,163,255,218,0,16,0,164,255,218,0,16,0,165,255,218,0,16,0,166,255,214,0,16,0,167,255,214,0,16,0,168,255,214,0,16,0,169,255,214,0,16,0,170,255,214,0,16,0,173,0,13,0,16,0,174,0,14,0,16,0,175,255,234,0,16,0,176,255,228,0,16,0,177,255,214,0,16,0,178,255,214,0,16,0,179,255,214,0,16,0,180,255,214,0,16,0,181,255,214,0,16,0,183,255,214,0,16,0,184,255,230,0,16,0,185,255,230,0,16,0,186,255,230,0,16,0,187,255,230,0,16,0,189,255,228,0,16,0,194,255,243,0,16,0,195,255,214,0,16,0,197,255,231,0,16,0,198,0,7,0,16,0,200,255,241,0,17,0,10,255,230,0,17,0,13,255,238,0,17,0,15,255,238,0,17,0,16,255,243,0,17,0,24,255,245,0,17,0,34,255,246,0,17,0,53,255,236,0,17,0,55,255,246,0,17,0,57,255,246,0,17,0,58,255,233,0,17,0,59,255,241,0,17,0,61,255,248,0,17,0,62,255,237,0,17,0,94,255,240,0,17,0,127,255,246,0,17,0,128,255,246,0,17,0,129,255,246,0,17,0,130,255,246,0,17,0,131,255,246,0,17,0,132,255,246,0,17,0,156,255,233,0,17,0,198,255,233,0,17,0,199,255,241,0,17,0,218,255,238,0,18,0,10,255,245,0,18,0,12,255,248,0,19,0,12,255,239,0,20,0,10,255,239,0,21,0,3,255,244,0,21,0,8,255,244,0,21,0,10,255,235,0,21,0,13,255,240,0,21,0,15,255,241,0,21,0,53,255,238,0,21,0,55,255,244,0,21,0,56,255,245,0,21,0,58,255,242,0,21,0,59,255,248,0,21,0,61,255,247,0,21,0,91,255,247,0,21,0,111,255,245,0,21,0,156,255,242,0,21,0,198,255,242,0,21,0,199,255,248,0,21,0,200,255,247,0,21,0,218,255,241,0,23,0,10,255,239,0,23,0,18,255,248,0,23,0,24,255,248,0,23,0,53,255,231,0,23,0,55,255,240,0,23,0,56,255,244,0,23,0,58,255,235,0,23,0,61,255,244,0,23,0,90,255,247,0,23,0,111,255,245,0,23,0,156,255,235,0,23,0,188,255,247,0,23,0,190,255,247,0,23,0,198,255,235,0,24,0,4,255,228,0,24,0,12,255,220,0,24,0,13,255,217,0,24,0,15,255,217,0,24,0,16,255,200,0,24,0,17,255,247,0,24,0,21,255,221,0,24,0,23,255,232,0,24,0,34,255,210,0,24,0,36,255,246,0,24,0,40,255,246,0,24,0,46,255,236,0,24,0,48,255,246,0,24,0,50,255,246,0,24,0,53,0,17,0,24,0,55,0,30,0,24,0,56,0,19,0,24,0,57,0,22,0,24,0,58,0,33,0,24,0,62,0,25,0,24,0,66,255,223,0,24,0,68,255,218,0,24,0,69,255,218,0,24,0,70,255,218,0,24,0,72,255,222,0,24,0,78,255,232,0,24,0,79,255,232,0,24,0,80,255,218,0,24,0,81,255,232,0,24,0,82,255,218,0,24,0,83,255,232,0,24,0,84,255,224,0,24,0,86,255,233,0,24,0,91,255,245,0,24,0,94,0,28,0,24,0,127,255,210,0,24,0,128,255,210,0,24,0,129,255,210,0,24,0,130,255,210,0,24,0,131,255,210,0,24,0,132,255,210,0,24,0,134,255,246,0,24,0,145,255,246,0,24,0,146,255,246,0,24,0,147,255,246,0,24,0,148,255,246,0,24,0,149,255,246,0,24,0,151,255,246,0,24,0,156,0,33,0,24,0,159,255,223,0,24,0,160,255,223,0,24,0,161,255,223,0,24,0,162,255,223,0,24,0,163,255,223,0,24,0,164,255,223,0,24,0,165,255,223,0,24,0,166,255,218,0,24,0,167,255,218,0,24,0,168,255,218,0,24,0,169,255,218,0,24,0,170,255,218,0,24,0,176,255,232,0,24,0,177,255,218,0,24,0,178,255,218,0,24,0,179,255,218,0,24,0,180,255,218,0,24,0,181,255,218,0,24,0,183,255,218,0,24,0,184,255,233,0,24,0,185,255,233,0,24,0,186,255,233,0,24,0,187,255,233,0,24,0,189,255,232,0,24,0,194,255,246,0,24,0,195,255,218,0,24,0,197,255,224,0,24,0,198,0,33,0,24,0,200,255,245,0,24,0,218,255,217,0,25,0,10,255,238,0,25,0,53,255,248,0,25,0,58,255,246,0,25,0,156,255,246,0,25,0,198,255,246,0,26,0,10,255,236,0,26,0,13,255,234,0,26,0,15,255,234,0,26,0,16,255,225,0,26,0,34,255,232,0,26,0,46,255,246,0,26,0,59,255,246,0,26,0,127,255,232,0,26,0,128,255,232,0,26,0,129,255,232,0,26,0,130,255,232,0,26,0,131,255,232,0,26,0,132,255,232,0,26,0,199,255,246,0,26,0,218,255,234,0,30,0,19,255,246,0,30,0,24,255,238,0,33,0,3,255,247,0,33,0,8,255,247,0,33,0,53,255,203,0,33,0,55,255,227,0,33,0,56,255,236,0,33,0,57,255,240,0,33,0,58,255,211,0,33,0,59,255,236,0,33,0,156,255,211,0,33,0,198,255,211,0,33,0,199,255,236,0,33,0,210,255,236,0,33,0,213,255,236,0,34,0,3,255,213,0,34,0,8,255,213,0,34,0,11,255,212,0,34,0,18,255,239,0,34,0,26,255,242,0,34,0,32,255,239,0,34,0,36,255,245,0,34,0,40,255,245,0,34,0,48,255,245,0,34,0,50,255,245,0,34,0,53,255,202,0,34,0,54,255,240,0,34,0,55,255,207,0,34,0,56,255,219,0,34,0,58,255,192,0,34,0,61,255,208,0,34,0,68,255,245,0,34,0,69,255,245,0,34,0,70,255,245,0,34,0,71,255,241,0,34,0,72,255,248,0,34,0,77,255,249,0,34,0,80,255,245,0,34,0,82,255,245,0,34,0,85,255,229,0,34,0,86,255,244,0,34,0,87,255,221,0,34,0,88,255,228,0,34,0,90,255,217,0,34,0,94,255,246,0,34,0,107,255,247,0,34,0,110,255,241,0,34,0,134,255,245,0,34,0,145,255,245,0,34,0,146,255,245,0,34,0,147,255,245,0,34,0,148,255,245,0,34,0,149,255,245,0,34,0,151,255,245,0,34,0,152,255,240,0,34,0,153,255,240,0,34,0,154,255,240,0,34,0,155,255,240,0,34,0,156,255,192,0,34,0,158,255,242,0,34,0,166,255,245,0,34,0,167,255,245,0,34,0,168,255,245,0,34,0,169,255,245,0,34,0,170,255,245,0,34,0,175,255,250,0,34,0,177,255,245,0,34,0,178,255,245,0,34,0,179,255,245,0,34,0,180,255,245,0,34,0,181,255,245,0,34,0,183,255,245,0,34,0,184,255,244,0,34,0,185,255,244,0,34,0,186,255,244,0,34,0,187,255,244,0,34,0,188,255,217,0,34,0,190,255,217,0,34,0,194,255,245,0,34,0,195,255,245,0,34,0,198,255,192,0,34,0,209,255,205,0,34,0,210,255,204,0,34,0,212,255,205,0,34,0,213,255,204,0,34,0,220,255,247,0,34,0,240,255,212,0,35,0,10,255,231,0,35,0,11,255,247,0,35,0,19,255,247,0,35,0,24,255,243,0,35,0,32,255,240,0,35,0,52,255,251,0,35,0,53,255,228,0,35,0,55,255,240,0,35,0,56,255,245,0,35,0,57,255,241,0,35,0,58,255,229,0,35,0,59,255,248,0,35,0,61,255,241,0,35,0,62,255,227,0,35,0,67,255,250,0,35,0,71,255,242,0,35,0,72,255,249,0,35,0,73,255,250,0,35,0,74,255,250,0,35,0,75,255,250,0,35,0,76,255,250,0,35,0,77,255,250,0,35,0,78,255,250,0,35,0,79,255,250,0,35,0,81,255,250,0,35,0,83,255,250,0,35,0,84,255,251,0,35,0,85,255,239,0,35,0,86,255,251,0,35,0,87,255,239,0,35,0,88,255,243,0,35,0,89,255,234,0,35,0,90,255,236,0,35,0,91,255,242,0,35,0,94,255,231,0,35,0,133,255,248,0,35,0,156,255,229,0,35,0,158,255,242,0,35,0,171,255,250,0,35,0,172,255,250,0,35,0,173,255,250,0,35,0,174,255,250,0,35,0,176,255,250,0,35,0,184,255,251,0,35,0,185,255,251,0,35,0,186,255,251,0,35,0,187,255,251,0,35,0,188,255,236,0,35,0,189,255,250,0,35,0,190,255,236,0,35,0,193,255,250,0,35,0,196,255,251,0,35,0,197,255,251,0,35,0,198,255,229,0,35,0,199,255,248,0,35,0,200,255,242,0,35,0,240,255,244,0,36,0,14,255,195,0,36,0,21,255,207,0,36,0,36,255,242,0,36,0,40,255,242,0,36,0,48,255,242,0,36,0,50,255,242,0,36,0,68,255,242,0,36,0,69,255,242,0,36,0,70,255,242,0,36,0,71,255,249,0,36,0,72,255,241,0,36,0,78,255,249,0,36,0,79,255,249,0,36,0,80,255,242,0,36,0,81,255,249,0,36,0,82,255,242,0,36,0,83,255,249,0,36,0,85,255,249,0,36,0,86,255,241,0,36,0,87,255,249,0,36,0,88,255,250,0,36,0,90,255,249,0,36,0,107,255,226,0,36,0,134,255,242,0,36,0,145,255,242,0,36,0,146,255,242,0,36,0,147,255,242,0,36,0,148,255,242,0,36,0,149,255,242,0,36,0,151,255,242,0,36,0,158,255,250,0,36,0,166,255,242,0,36,0,167,255,242,0,36,0,168,255,242,0,36,0,169,255,242,0,36,0,170,255,242,0,36,0,173,0,31,0,36,0,174,0,12,0,36,0,175,255,249,0,36,0,176,255,249,0,36,0,177,255,242,0,36,0,178,255,242,0,36,0,179,255,242,0,36,0,180,255,242,0,36,0,181,255,242,0,36,0,183,255,242,0,36,0,184,255,241,0,36,0,185,255,241,0,36,0,186,255,241,0,36,0,187,255,241,0,36,0,188,255,249,0,36,0,189,255,249,0,36,0,190,255,249,0,36,0,194,255,242,0,36,0,195,255,242,0,36,0,207,255,195,0,36,0,208,255,195,0,36,0,220,255,226,0,37,0,10,255,228,0,37,0,13,255,241,0,37,0,15,255,242,0,37,0,16,255,237,0,37,0,20,255,248,0,37,0,24,255,240,0,37,0,32,255,237,0,37,0,34,255,244,0,37,0,46,255,250,0,37,0,53,255,228,0,37,0,55,255,243,0,37,0,56,255,248,0,37,0,57,255,225,0,37,0,58,255,227,0,37,0,59,255,235,0,37,0,61,255,244,0,37,0,62,255,224,0,37,0,66,255,248,0,37,0,67,255,249,0,37,0,68,255,250,0,37,0,69,255,250,0,37,0,70,255,250,0,37,0,72,255,250,0,37,0,73,255,249,0,37,0,74,255,249,0,37,0,75,255,249,0,37,0,76,255,249,0,37,0,77,255,249,0,37,0,78,255,249,0,37,0,79,255,249,0,37,0,80,255,250,0,37,0,81,255,249,0,37,0,82,255,250,0,37,0,83,255,249,0,37,0,84,255,250,0,37,0,86,255,250,0,37,0,89,255,244,0,37,0,91,255,250,0,37,0,94,255,229,0,37,0,127,255,244,0,37,0,128,255,244,0,37,0,129,255,244,0,37,0,130,255,244,0,37,0,131,255,244,0,37,0,132,255,244,0,37,0,133,255,226,0,37,0,156,255,227,0,37,0,158,255,250,0,37,0,159,255,248,0,37,0,160,255,248,0,37,0,161,255,248,0,37,0,162,255,248,0,37,0,163,255,248,0,37,0,164,255,248,0,37,0,165,255,248,0,37,0,166,255,250,0,37,0,167,255,250,0,37,0,168,255,250,0,37,0,169,255,250,0,37,0,170,255,250,0,37,0,171,255,249,0,37,0,172,255,249,0,37,0,173,255,249,0,37,0,174,255,249,0,37,0,175,255,249,0,37,0,176,255,249,0,37,0,177,255,250,0,37,0,178,255,250,0,37,0,179,255,250,0,37,0,180,255,250,0,37,0,181,255,250,0,37,0,183,255,250,0,37,0,184,255,250,0,37,0,185,255,250,0,37,0,186,255,250,0,37,0,187,255,250,0,37,0,189,255,249,0,37,0,193,255,249,0,37,0,195,255,250,0,37,0,197,255,250,0,37,0,198,255,227,0,37,0,199,255,235,0,37,0,200,255,250,0,37,0,210,255,247,0,37,0,211,255,241,0,37,0,213,255,247,0,37,0,214,255,241,0,37,0,218,255,242,0,37,0,240,255,246,0,38,0,14,255,244,0,38,0,21,255,220,0,38,0,36,255,245,0,38,0,40,255,245,0,38,0,48,255,245,0,38,0,50,255,245,0,38,0,68,255,240,0,38,0,69,255,240,0,38,0,70,255,240,0,38,0,71,255,243,0,38,0,72,255,241,0,38,0,78,255,247,0,38,0,79,255,247,0,38,0,80,255,240,0,38,0,81,255,247,0,38,0,82,255,240,0,38,0,83,255,247,0,38,0,84,255,251,0,38,0,85,255,242,0,38,0,86,255,238,0,38,0,87,255,241,0,38,0,88,255,243,0,38,0,90,255,240,0,38,0,107,255,235,0,38,0,110,255,248,0,38,0,134,255,245,0,38,0,145,255,245,0,38,0,146,255,245,0,38,0,147,255,245,0,38,0,148,255,245,0,38,0,149,255,245,0,38,0,151,255,245,0,38,0,158,255,243,0,38,0,166,255,240,0,38,0,167,255,240,0,38,0,168,255,240,0,38,0,169,255,240,0,38,0,170,255,240,0,38,0,173,0,21,0,38,0,175,255,246,0,38,0,176,255,247,0,38,0,177,255,240,0,38,0,178,255,240,0,38,0,179,255,240,0,38,0,180,255,240,0,38,0,181,255,240,0,38,0,183,255,240,0,38,0,184,255,238,0,38,0,185,255,238,0,38,0,186,255,238,0,38,0,187,255,238,0,38,0,188,255,240,0,38,0,189,255,247,0,38,0,190,255,240,0,38,0,194,255,245,0,38,0,195,255,240,0,38,0,197,255,251,0,38,0,207,255,244,0,38,0,208,255,244,0,38,0,220,255,235,0,39,0,7,255,245,0,39,0,11,0,11,0,39,0,13,255,186,0,39,0,15,255,186,0,39,0,16,255,199,0,39,0,21,255,223,0,39,0,23,255,243,0,39,0,27,255,243,0,39,0,28,255,243,0,39,0,33,255,222,0,39,0,34,255,203,0,39,0,36,255,248,0,39,0,40,255,248,0,39,0,46,255,239,0,39,0,48,255,248,0,39,0,50,255,248,0,39,0,53,0,5,0,39,0,62,0,16,0,39,0,66,255,199,0,39,0,67,255,251,0,39,0,68,255,212,0,39,0,69,255,212,0,39,0,70,255,212,0,39,0,71,255,244,0,39,0,72,255,216,0,39,0,73,255,251,0,39,0,74,255,249,0,39,0,75,255,249,0,39,0,76,255,251,0,39,0,78,255,211,0,39,0,79,255,211,0,39,0,80,255,212,0,39,0,81,255,211,0,39,0,82,255,212,0,39,0,83,255,211,0,39,0,84,255,217,0,39,0,85,255,247,0,39,0,86,255,217,0,39,0,87,255,247,0,39,0,88,255,248,0,39,0,89,255,239,0,39,0,90,255,248,0,39,0,91,255,236,0,39,0,94,0,19,0,39,0,107,255,236,0,39,0,122,255,217,0,39,0,127,255,203,0,39,0,128,255,203,0,39,0,129,255,203,0,39,0,130,255,203,0,39,0,131,255,203,0,39,0,132,255,203,0,39,0,133,255,155,0,39,0,134,255,248,0,39,0,145,255,248,0,39,0,146,255,248,0,39,0,147,255,248,0,39,0,148,255,248,0,39,0,149,255,248,0,39,0,151,255,248,0,39,0,158,255,241,0,39,0,159,255,199,0,39,0,160,255,199,0,39,0,161,255,199,0,39,0,162,255,206,0,39,0,163,255,199,0,39,0,164,255,199,0,39,0,165,255,199,0,39,0,166,255,212,0,39,0,167,255,212,0,39,0,168,255,212,0,39,0,169,255,212,0,39,0,170,255,212,0,39,0,171,255,249,0,39,0,172,255,249,0,39,0,173,0,52,0,39,0,174,0,28,0,39,0,175,255,222,0,39,0,176,255,211,0,39,0,177,255,212,0,39,0,178,255,212,0,39,0,179,255,212,0,39,0,180,255,212,0,39,0,181,255,212,0,39,0,183,255,212,0,39,0,184,255,217,0,39,0,185,255,217,0,39,0,186,255,217,0,39,0,187,255,217,0,39,0,188,255,248,0,39,0,189,255,211,0,39,0,190,255,248,0,39,0,193,255,249,0,39,0,194,255,248,0,39,0,195,255,212,0,39,0,197,255,217,0,39,0,200,255,236,0,39,0,211,255,186,0,39,0,214,255,186,0,39,0,218,255,186,0,39,0,220,255,236,0,39,0,221,255,217,0,39,0,240,0,16,0,40,0,10,255,248,0,40,0,53,255,251,0,40,0,67,255,250,0,40,0,68,255,251,0,40,0,69,255,251,0,40,0,70,255,251,0,40,0,71,255,246,0,40,0,72,255,250,0,40,0,73,255,250,0,40,0,74,255,250,0,40,0,75,255,250,0,40,0,76,255,250,0,40,0,77,255,250,0,40,0,78,255,250,0,40,0,79,255,250,0,40,0,80,255,251,0,40,0,81,255,250,0,40,0,82,255,251,0,40,0,83,255,250,0,40,0,85,255,244,0,40,0,86,255,249,0,40,0,87,255,244,0,40,0,88,255,247,0,40,0,90,255,242,0,40,0,91,255,249,0,40,0,158,255,244,0,40,0,166,255,251,0,40,0,167,255,251,0,40,0,168,255,251,0,40,0,169,255,251,0,40,0,170,255,251,0,40,0,171,255,250,0,40,0,172,255,250,0,40,0,173,255,250,0,40,0,174,255,250,0,40,0,176,255,250,0,40,0,177,255,251,0,40,0,178,255,251,0,40,0,179,255,251,0,40,0,180,255,251,0,40,0,181,255,251,0,40,0,183,255,251,0,40,0,184,255,249,0,40,0,185,255,249,0,40,0,186,255,249,0,40,0,187,255,249,0,40,0,188,255,242,0,40,0,189,255,250,0,40,0,190,255,242,0,40,0,193,255,250,0,40,0,195,255,251,0,40,0,200,255,249,0,41,0,10,255,246,0,41,0,46,255,251,0,41,0,66,255,246,0,41,0,67,255,247,0,41,0,68,255,242,0,41,0,69,255,242,0,41,0,70,255,242,0,41,0,71,255,247,0,41,0,72,255,241,0,41,0,73,255,247,0,41,0,74,255,247,0,41,0,75,255,247,0,41,0,76,255,247,0,41,0,77,255,246,0,41,0,78,255,247,0,41,0,79,255,247,0,41,0,80,255,242,0,41,0,81,255,247,0,41,0,82,255,242,0,41,0,83,255,247,0,41,0,84,255,246,0,41,0,85,255,247,0,41,0,86,255,245,0,41,0,87,255,247,0,41,0,88,255,248,0,41,0,90,255,247,0,41,0,91,255,246,0,41,0,158,255,244,0,41,0,159,255,246,0,41,0,160,255,246,0,41,0,161,255,246,0,41,0,162,255,246,0,41,0,163,255,246,0,41,0,164,255,246,0,41,0,165,255,246,0,41,0,166,255,242,0,41,0,167,255,242,0,41,0,168,255,242,0,41,0,169,255,242,0,41,0,170,255,242,0,41,0,171,255,247,0,41,0,172,255,247,0,41,0,173,255,247,0,41,0,174,255,247,0,41,0,175,255,243,0,41,0,176,255,247,0,41,0,177,255,242,0,41,0,178,255,242,0,41,0,179,255,242,0,41,0,180,255,242,0,41,0,181,255,242,0,41,0,183,255,242,0,41,0,184,255,245,0,41,0,185,255,245,0,41,0,186,255,245,0,41,0,187,255,245,0,41,0,188,255,247,0,41,0,189,255,247,0,41,0,190,255,247,0,41,0,193,255,247,0,41,0,195,255,242,0,41,0,197,255,246,0,41,0,200,255,246,0,42,0,10,255,246,0,42,0,46,255,251,0,42,0,66,255,246,0,42,0,67,255,247,0,42,0,68,255,242,0,42,0,69,255,242,0,42,0,70,255,242,0,42,0,71,255,247,0,42,0,72,255,241,0,42,0,73,255,247,0,42,0,74,255,247,0,42,0,75,255,247,0,42,0,76,255,247,0,42,0,77,255,246,0,42,0,78,255,247,0,42,0,79,255,247,0,42,0,80,255,242,0,42,0,81,255,247,0,42,0,82,255,242,0,42,0,83,255,247,0,42,0,84,255,246,0,42,0,85,255,247,0,42,0,86,255,245,0,42,0,87,255,247,0,42,0,88,255,248,0,42,0,90,255,247,0,42,0,91,255,246,0,42,0,158,255,244,0,42,0,159,255,246,0,42,0,160,255,246,0,42,0,161,255,246,0,42,0,162,255,246,0,42,0,163,255,246,0,42,0,164,255,246,0,42,0,165,255,246,0,42,0,166,255,242,0,42,0,167,255,242,0,42,0,168,255,242,0,42,0,169,255,242,0,42,0,170,255,242,0,42,0,171,255,247,0,42,0,172,255,247,0,42,0,173,255,247,0,42,0,174,255,247,0,42,0,175,255,243,0,42,0,176,255,247,0,42,0,177,255,242,0,42,0,178,255,242,0,42,0,179,255,242,0,42,0,180,255,242,0,42,0,181,255,242,0,42,0,183,255,242,0,42,0,184,255,245,0,42,0,185,255,245,0,42,0,186,255,245,0,42,0,187,255,245,0,42,0,188,255,247,0,42,0,189,255,247,0,42,0,190,255,247,0,42,0,193,255,247,0,42,0,195,255,242,0,42,0,197,255,246,0,42,0,200,255,246,0,43,0,10,255,246,0,43,0,46,255,251,0,43,0,66,255,246,0,43,0,67,255,247,0,43,0,68,255,242,0,43,0,69,255,242,0,43,0,70,255,242,0,43,0,71,255,247,0,43,0,72,255,241,0,43,0,73,255,247,0,43,0,74,255,247,0,43,0,75,255,247,0,43,0,76,255,247,0,43,0,77,255,246,0,43,0,78,255,247,0,43,0,79,255,247,0,43,0,80,255,242,0,43,0,81,255,247,0,43,0,82,255,242,0,43,0,83,255,247,0,43,0,84,255,246,0,43,0,85,255,247,0,43,0,86,255,245,0,43,0,87,255,247,0,43,0,88,255,248,0,43,0,90,255,247,0,43,0,91,255,246,0,43,0,158,255,244,0,43,0,159,255,246,0,43,0,160,255,246,0,43,0,161,255,246,0,43,0,162,255,246,0,43,0,163,255,246,0,43,0,164,255,246,0,43,0,165,255,246,0,43,0,166,255,242,0,43,0,167,255,242,0,43,0,168,255,242,0,43,0,169,255,242,0,43,0,170,255,242,0,43,0,171,255,247,0,43,0,172,255,247,0,43,0,173,255,247,0,43,0,174,255,247,0,43,0,175,255,243,0,43,0,176,255,247,0,43,0,177,255,242,0,43,0,178,255,242,0,43,0,179,255,242,0,43,0,180,255,242,0,43,0,181,255,242,0,43,0,183,255,242,0,43,0,184,255,245,0,43,0,185,255,245,0,43,0,186,255,245,0,43,0,187,255,245,0,43,0,188,255,247,0,43,0,189,255,247,0,43,0,190,255,247,0,43,0,193,255,247,0,43,0,195,255,242,0,43,0,197,255,246,0,43,0,200,255,246,0,44,0,7,255,247,0,44,0,11,0,9,0,44,0,14,255,244,0,44,0,36,255,228,0,44,0,40,255,228,0,44,0,48,255,228,0,44,0,50,255,228,0,44,0,52,255,250,0,44,0,62,0,33,0,44,0,68,255,222,0,44,0,69,255,222,0,44,0,70,255,222,0,44,0,71,255,246,0,44,0,72,255,238,0,44,0,80,255,222,0,44,0,82,255,222,0,44,0,85,255,229,0,44,0,86,255,232,0,44,0,87,255,201,0,44,0,88,255,211,0,44,0,90,255,199,0,44,0,94,0,33,0,44,0,107,255,227,0,44,0,110,255,238,0,44,0,134,255,228,0,44,0,145,255,228,0,44,0,146,255,228,0,44,0,147,255,228,0,44,0,148,255,228,0,44,0,149,255,228,0,44,0,151,255,228,0,44,0,158,255,245,0,44,0,166,255,222,0,44,0,167,255,222,0,44,0,168,255,222,0,44,0,169,255,222,0,44,0,170,255,222,0,44,0,171,0,10,0,44,0,173,0,24,0,44,0,174,0,41,0,44,0,175,255,239,0,44,0,177,255,222,0,44,0,178,255,222,0,44,0,179,255,222,0,44,0,180,255,222,0,44,0,181,255,222,0,44,0,183,255,222,0,44,0,184,255,232,0,44,0,185,255,232,0,44,0,186,255,232,0,44,0,187,255,232,0,44,0,188,255,199,0,44,0,190,255,199,0,44,0,194,255,228,0,44,0,195,255,222,0,44,0,196,255,250,0,44,0,207,255,244,0,44,0,208,255,244,0,44,0,220,255,227,0,44,0,240,0,27,0,45,0,3,255,166,0,45,0,8,255,166,0,45,0,11,255,166,0,45,0,14,255,196,0,45,0,17,255,243,0,45,0,18,255,236,0,45,0,21,255,194,0,45,0,26,255,227,0,45,0,32,255,231,0,45,0,36,255,232,0,45,0,40,255,232,0,45,0,48,255,232,0,45,0,50,255,232,0,45,0,53,255,189,0,45,0,54,255,238,0,45,0,55,255,154,0,45,0,56,255,203,0,45,0,58,255,158,0,45,0,61,255,187,0,45,0,62,255,240,0,45,0,68,255,246,0,45,0,69,255,246,0,45,0,70,255,246,0,45,0,71,255,241,0,45,0,72,255,249,0,45,0,80,255,246,0,45,0,82,255,246,0,45,0,85,255,232,0,45,0,86,255,249,0,45,0,87,255,199,0,45,0,88,255,212,0,45,0,90,255,181,0,45,0,94,255,241,0,45,0,107,255,222,0,45,0,110,255,220,0,45,0,134,255,232,0,45,0,145,255,232,0,45,0,146,255,232,0,45,0,147,255,232,0,45,0,148,255,232,0,45,0,149,255,232,0,45,0,151,255,232,0,45,0,152,255,238,0,45,0,153,255,238,0,45,0,154,255,238,0,45,0,155,255,238,0,45,0,156,255,158,0,45,0,158,255,243,0,45,0,166,255,246,0,45,0,167,255,246,0,45,0,168,255,246,0,45,0,169,255,246,0,45,0,170,255,246,0,45,0,177,255,246,0,45,0,178,255,246,0,45,0,179,255,246,0,45,0,180,255,246,0,45,0,181,255,246,0,45,0,183,255,246,0,45,0,184,255,249,0,45,0,185,255,249,0,45,0,186,255,249,0,45,0,187,255,249,0,45,0,188,255,181,0,45,0,190,255,181,0,45,0,194,255,232,0,45,0,195,255,246,0,45,0,198,255,158,0,45,0,207,255,196,0,45,0,208,255,196,0,45,0,209,255,167,0,45,0,210,255,167,0,45,0,212,255,167,0,45,0,213,255,167,0,45,0,220,255,222,0,45,0,240,255,166,0,46,0,3,255,238,0,46,0,8,255,238,0,46,0,10,255,242,0,46,0,11,255,238,0,46,0,18,255,247,0,46,0,32,255,242,0,46,0,35,255,251,0,46,0,36,255,251,0,46,0,37,255,251,0,46,0,38,255,251,0,46,0,39,255,251,0,46,0,40,255,251,0,46,0,41,255,251,0,46,0,42,255,251,0,46,0,43,255,251,0,46,0,44,255,251,0,46,0,45,255,251,0,46,0,47,255,251,0,46,0,48,255,251,0,46,0,49,255,251,0,46,0,50,255,251,0,46,0,51,255,251,0,46,0,53,255,231,0,46,0,54,255,248,0,46,0,55,255,236,0,46,0,56,255,238,0,46,0,58,255,233,0,46,0,61,255,239,0,46,0,66,255,250,0,46,0,67,255,245,0,46,0,68,255,244,0,46,0,69,255,244,0,46,0,70,255,244,0,46,0,71,255,240,0,46,0,72,255,243,0,46,0,73,255,245,0,46,0,74,255,246,0,46,0,75,255,246,0,46,0,76,255,245,0,46,0,77,255,245,0,46,0,78,255,246,0,46,0,79,255,246,0,46,0,80,255,244,0,46,0,81,255,246,0,46,0,82,255,244,0,46,0,83,255,246,0,46,0,84,255,250,0,46,0,85,255,236,0,46,0,86,255,244,0,46,0,87,255,234,0,46,0,88,255,236,0,46,0,90,255,233,0,46,0,91,255,249,0,46,0,134,255,251,0,46,0,135,255,251,0,46,0,136,255,251,0,46,0,137,255,251,0,46,0,138,255,251,0,46,0,139,255,251,0,46,0,140,255,251,0,46,0,141,255,251,0,46,0,142,255,251,0,46,0,143,255,251,0,46,0,144,255,251,0,46,0,145,255,251,0,46,0,146,255,251,0,46,0,147,255,251,0,46,0,148,255,251,0,46,0,149,255,251,0,46,0,151,255,251,0,46,0,152,255,248,0,46,0,153,255,248,0,46,0,154,255,248,0,46,0,155,255,248,0,46,0,156,255,233,0,46,0,157,255,251,0,46,0,158,255,238,0,46,0,159,255,250,0,46,0,160,255,250,0,46,0,161,255,250,0,46,0,162,255,250,0,46,0,163,255,250,0,46,0,164,255,250,0,46,0,165,255,250,0,46,0,166,255,244,0,46,0,167,255,244,0,46,0,168,255,244,0,46,0,169,255,244,0,46,0,170,255,244,0,46,0,171,255,246,0,46,0,172,255,246,0,46,0,173,255,246,0,46,0,174,255,246,0,46,0,175,255,247,0,46,0,176,255,246,0,46,0,177,255,244,0,46,0,178,255,244,0,46,0,179,255,244,0,46,0,180,255,244,0,46,0,181,255,244,0,46,0,183,255,244,0,46,0,184,255,244,0,46,0,185,255,244,0,46,0,186,255,244,0,46,0,187,255,244,0,46,0,188,255,233,0,46,0,189,255,246,0,46,0,190,255,233,0,46,0,193,255,246,0,46,0,194,255,251,0,46,0,195,255,244,0,46,0,197,255,250,0,46,0,198,255,233,0,46,0,200,255,249,0,46,0,209,255,236,0,46,0,210,255,236,0,46,0,212,255,236,0,46,0,213,255,236,0,46,0,240,255,237,0,47,0,10,255,246,0,47,0,46,255,251,0,47,0,66,255,246,0,47,0,67,255,247,0,47,0,68,255,242,0,47,0,69,255,242,0,47,0,70,255,242,0,47,0,71,255,247,0,47,0,72,255,241,0,47,0,73,255,247,0,47,0,74,255,247,0,47,0,75,255,247,0,47,0,76,255,247,0,47,0,77,255,246,0,47,0,78,255,247,0,47,0,79,255,247,0,47,0,80,255,242,0,47,0,81,255,247,0,47,0,82,255,242,0,47,0,83,255,247,0,47,0,84,255,246,0,47,0,85,255,247,0,47,0,86,255,245,0,47,0,87,255,247,0,47,0,88,255,248,0,47,0,90,255,247,0,47,0,91,255,246,0,47,0,158,255,244,0,47,0,159,255,246,0,47,0,160,255,246,0,47,0,161,255,246,0,47,0,162,255,246,0,47,0,163,255,246,0,47,0,164,255,246,0,47,0,165,255,246,0,47,0,166,255,242,0,47,0,167,255,242,0,47,0,168,255,242,0,47,0,169,255,242,0,47,0,170,255,242,0,47,0,171,255,247,0,47,0,172,255,247,0,47,0,173,255,247,0,47,0,174,255,247,0,47,0,175,255,243,0,47,0,176,255,247,0,47,0,177,255,242,0,47,0,178,255,242,0,47,0,179,255,242,0,47,0,180,255,242,0,47,0,181,255,242,0,47,0,183,255,242,0,47,0,184,255,245,0,47,0,185,255,245,0,47,0,186,255,245,0,47,0,187,255,245,0,47,0,188,255,247,0,47,0,189,255,247,0,47,0,190,255,247,0,47,0,193,255,247,0,47,0,195,255,242,0,47,0,197,255,246,0,47,0,200,255,246,0,48,0,10,255,229,0,48,0,13,255,242,0,48,0,15,255,242,0,48,0,16,255,239,0,48,0,24,255,243,0,48,0,32,255,240,0,48,0,34,255,245,0,48,0,46,255,251,0,48,0,53,255,232,0,48,0,55,255,244,0,48,0,56,255,248,0,48,0,57,255,229,0,48,0,58,255,230,0,48,0,59,255,238,0,48,0,61,255,245,0,48,0,62,255,227,0,48,0,66,255,247,0,48,0,67,255,250,0,48,0,68,255,250,0,48,0,69,255,250,0,48,0,70,255,250,0,48,0,72,255,250,0,48,0,73,255,250,0,48,0,74,255,249,0,48,0,75,255,249,0,48,0,76,255,250,0,48,0,77,255,250,0,48,0,78,255,249,0,48,0,79,255,249,0,48,0,80,255,250,0,48,0,81,255,249,0,48,0,82,255,250,0,48,0,83,255,249,0,48,0,84,255,250,0,48,0,86,255,251,0,48,0,89,255,245,0,48,0,91,255,250,0,48,0,94,255,231,0,48,0,127,255,245,0,48,0,128,255,245,0,48,0,129,255,245,0,48,0,130,255,245,0,48,0,131,255,245,0,48,0,132,255,245,0,48,0,133,255,229,0,48,0,156,255,230,0,48,0,158,255,251,0,48,0,159,255,247,0,48,0,160,255,247,0,48,0,161,255,247,0,48,0,162,255,247,0,48,0,163,255,247,0,48,0,164,255,247,0,48,0,165,255,247,0,48,0,166,255,250,0,48,0,167,255,250,0,48,0,168,255,250,0,48,0,169,255,250,0,48,0,170,255,250,0,48,0,171,255,249,0,48,0,172,255,249,0,48,0,173,255,249,0,48,0,174,255,249,0,48,0,175,255,250,0,48,0,176,255,249,0,48,0,177,255,250,0,48,0,178,255,250,0,48,0,179,255,250,0,48,0,180,255,250,0,48,0,181,255,250,0,48,0,183,255,250,0,48,0,184,255,251,0,48,0,185,255,251,0,48,0,186,255,251,0,48,0,187,255,251,0,48,0,189,255,249,0,48,0,193,255,249,0,48,0,195,255,250,0,48,0,197,255,250,0,48,0,198,255,230,0,48,0,199,255,238,0,48,0,200,255,250,0,48,0,210,255,247,0,48,0,211,255,242,0,48,0,213,255,247,0,48,0,214,255,242,0,48,0,218,255,242,0,48,0,240,255,246,0,49,0,7,255,250,0,49,0,10,255,241,0,49,0,13,255,175,0,49,0,15,255,175,0,49,0,16,255,210,0,49,0,20,255,248,0,49,0,21,255,242,0,49,0,33,255,241,0,49,0,34,255,216,0,49,0,46,255,246,0,49,0,57,255,242,0,49,0,59,255,248,0,49,0,66,255,242,0,49,0,67,255,251,0,49,0,68,255,243,0,49,0,69,255,243,0,49,0,70,255,243,0,49,0,72,255,246,0,49,0,73,255,251,0,49,0,74,255,250,0,49,0,75,255,250,0,49,0,76,255,251,0,49,0,77,255,251,0,49,0,78,255,248,0,49,0,79,255,248,0,49,0,80,255,243,0,49,0,81,255,248,0,49,0,82,255,243,0,49,0,83,255,248,0,49,0,84,255,248,0,49,0,86,255,250,0,49,0,127,255,216,0,49,0,128,255,216,0,49,0,129,255,216,0,49,0,130,255,216,0,49,0,131,255,216,0,49,0,132,255,216,0,49,0,133,255,187,0,49,0,159,255,242,0,49,0,160,255,242,0,49,0,161,255,242,0,49,0,162,255,242,0,49,0,163,255,242,0,49,0,164,255,242,0,49,0,165,255,242,0,49,0,166,255,243,0,49,0,167,255,243,0,49,0,168,255,243,0,49,0,169,255,243,0,49,0,170,255,243,0,49,0,171,255,250,0,49,0,172,255,250,0,49,0,173,0,25,0,49,0,174,0,4,0,49,0,175,255,234,0,49,0,176,255,248,0,49,0,177,255,243,0,49,0,178,255,243,0,49,0,179,255,243,0,49,0,180,255,243,0,49,0,181,255,243,0,49,0,183,255,243,0,49,0,184,255,250,0,49,0,185,255,250,0,49,0,186,255,250,0,49,0,187,255,250,0,49,0,189,255,248,0,49,0,193,255,250,0,49,0,195,255,243,0,49,0,197,255,248,0,49,0,199,255,248,0,49,0,211,255,175,0,49,0,214,255,175,0,49,0,218,255,175,0,50,0,10,255,229,0,50,0,13,255,242,0,50,0,15,255,242,0,50,0,16,255,239,0,50,0,24,255,243,0,50,0,32,255,240,0,50,0,34,255,245,0,50,0,46,255,251,0,50,0,53,255,232,0,50,0,55,255,244,0,50,0,56,255,248,0,50,0,57,255,229,0,50,0,58,255,230,0,50,0,59,255,238,0,50,0,61,255,245,0,50,0,62,255,227,0,50,0,66,255,247,0,50,0,67,255,250,0,50,0,68,255,250,0,50,0,69,255,250,0,50,0,70,255,250,0,50,0,72,255,250,0,50,0,73,255,250,0,50,0,74,255,249,0,50,0,75,255,249,0,50,0,76,255,250,0,50,0,77,255,250,0,50,0,78,255,249,0,50,0,79,255,249,0,50,0,80,255,250,0,50,0,81,255,249,0,50,0,82,255,250,0,50,0,83,255,249,0,50,0,84,255,250,0,50,0,86,255,251,0,50,0,89,255,245,0,50,0,91,255,250,0,50,0,94,255,231,0,50,0,127,255,245,0,50,0,128,255,245,0,50,0,129,255,245,0,50,0,130,255,245,0,50,0,131,255,245,0,50,0,132,255,245,0,50,0,133,255,229,0,50,0,156,255,230,0,50,0,158,255,251,0,50,0,159,255,247,0,50,0,160,255,247,0,50,0,161,255,247,0,50,0,162,255,247,0,50,0,163,255,247,0,50,0,164,255,247,0,50,0,165,255,247,0,50,0,166,255,250,0,50,0,167,255,250,0,50,0,168,255,250,0,50,0,169,255,250,0,50,0,170,255,250,0,50,0,171,255,249,0,50,0,172,255,249,0,50,0,173,255,249,0,50,0,174,255,249,0,50,0,175,255,250,0,50,0,176,255,249,0,50,0,177,255,250,0,50,0,178,255,250,0,50,0,179,255,250,0,50,0,180,255,250,0,50,0,181,255,250,0,50,0,183,255,250,0,50,0,184,255,251,0,50,0,185,255,251,0,50,0,186,255,251,0,50,0,187,255,251,0,50,0,189,255,249,0,50,0,193,255,249,0,50,0,195,255,250,0,50,0,197,255,250,0,50,0,198,255,230,0,50,0,199,255,238,0,50,0,200,255,250,0,50,0,210,255,247,0,50,0,211,255,242,0,50,0,213,255,247,0,50,0,214,255,242,0,50,0,218,255,242,0,50,0,240,255,246,0,51,0,21,255,234,0,51,0,53,255,243,0,51,0,55,255,251,0,51,0,58,255,245,0,51,0,62,255,240,0,51,0,66,255,251,0,51,0,67,255,250,0,51,0,68,255,237,0,51,0,69,255,237,0,51,0,70,255,237,0,51,0,71,255,249,0,51,0,72,255,243,0,51,0,73,255,250,0,51,0,74,255,249,0,51,0,75,255,249,0,51,0,76,255,250,0,51,0,77,255,248,0,51,0,78,255,248,0,51,0,79,255,248,0,51,0,80,255,237,0,51,0,81,255,248,0,51,0,82,255,237,0,51,0,83,255,248,0,51,0,85,255,248,0,51,0,86,255,244,0,51,0,87,255,248,0,51,0,88,255,250,0,51,0,90,255,248,0,51,0,94,255,247,0,51,0,107,255,242,0,51,0,156,255,245,0,51,0,158,255,247,0,51,0,159,255,251,0,51,0,160,255,251,0,51,0,161,255,251,0,51,0,162,255,251,0,51,0,163,255,251,0,51,0,164,255,251,0,51,0,165,255,251,0,51,0,166,255,237,0,51,0,167,255,237,0,51,0,168,255,237,0,51,0,169,255,237,0,51,0,170,255,237,0,51,0,171,255,249,0,51,0,172,255,249,0,51,0,173,255,249,0,51,0,174,255,249,0,51,0,175,255,242,0,51,0,176,255,248,0,51,0,177,255,237,0,51,0,178,255,237,0,51,0,179,255,237,0,51,0,180,255,237,0,51,0,181,255,237,0,51,0,183,255,237,0,51,0,184,255,244,0,51,0,185,255,244,0,51,0,186,255,244,0,51,0,187,255,244,0,51,0,188,255,248,0,51,0,189,255,248,0,51,0,190,255,248,0,51,0,193,255,249,0,51,0,195,255,237,0,51,0,198,255,245,0,51,0,220,255,242,0,52,0,10,255,246,0,52,0,57,255,251,0,52,0,67,255,250,0,52,0,71,255,243,0,52,0,72,255,250,0,52,0,73,255,250,0,52,0,74,255,250,0,52,0,75,255,250,0,52,0,76,255,250,0,52,0,77,255,250,0,52,0,78,255,250,0,52,0,79,255,250,0,52,0,81,255,250,0,52,0,83,255,250,0,52,0,84,255,251,0,52,0,85,255,241,0,52,0,86,255,250,0,52,0,87,255,241,0,52,0,88,255,244,0,52,0,89,255,242,0,52,0,90,255,240,0,52,0,91,255,244,0,52,0,158,255,244,0,52,0,171,255,250,0,52,0,172,255,250,0,52,0,173,255,250,0,52,0,174,255,250,0,52,0,176,255,250,0,52,0,184,255,250,0,52,0,185,255,250,0,52,0,186,255,250,0,52,0,187,255,250,0,52,0,188,255,240,0,52,0,189,255,250,0,52,0,190,255,240,0,52,0,193,255,250,0,52,0,197,255,251,0,52,0,200,255,244,0,53,0,7,255,241,0,53,0,11,0,12,0,53,0,13,255,213,0,53,0,14,255,216,0,53,0,15,255,214,0,53,0,16,255,205,0,53,0,17,255,235,0,53,0,21,255,211,0,53,0,23,255,218,0,53,0,25,255,248,0,53,0,27,255,222,0,53,0,28,255,222,0,53,0,33,255,197,0,53,0,34,255,202,0,53,0,36,255,232,0,53,0,40,255,232,0,53,0,46,255,230,0,53,0,48,255,232,0,53,0,50,255,232,0,53,0,62,0,18,0,53,0,66,255,195,0,53,0,67,255,250,0,53,0,68,255,177,0,53,0,69,255,177,0,53,0,70,255,177,0,53,0,71,255,231,0,53,0,72,255,175,0,53,0,73,255,250,0,53,0,74,255,247,0,53,0,75,255,247,0,53,0,76,255,250,0,53,0,77,255,250,0,53,0,78,255,168,0,53,0,79,255,168,0,53,0,80,255,177,0,53,0,81,255,168,0,53,0,82,255,177,0,53,0,83,255,168,0,53,0,84,255,197,0,53,0,85,255,230,0,53,0,86,255,169,0,53,0,87,255,173,0,53,0,88,255,182,0,53,0,89,255,170,0,53,0,90,255,171,0,53,0,91,255,208,0,53,0,94,0,21,0,53,0,107,255,195,0,53,0,110,255,232,0,53,0,122,255,197,0,53,0,127,255,202,0,53,0,128,255,202,0,53,0,129,255,202,0,53,0,130,255,202,0,53,0,131,255,202,0,53,0,132,255,202,0,53,0,133,255,183,0,53,0,134,255,232,0,53,0,145,255,232,0,53,0,146,255,232,0,53,0,147,255,232,0,53,0,148,255,232,0,53,0,149,255,232,0,53,0,151,255,232,0,53,0,158,255,227,0,53,0,159,255,195,0,53,0,160,255,195,0,53,0,161,255,195,0,53,0,162,255,203,0,53,0,163,255,195,0,53,0,164,255,195,0,53,0,165,255,195,0,53,0,166,255,177,0,53,0,167,255,177,0,53,0,168,255,177,0,53,0,169,255,177,0,53,0,170,255,177,0,53,0,171,255,254,0,53,0,172,255,254,0,53,0,173,0,52,0,53,0,174,0,30,0,53,0,175,255,215,0,53,0,176,255,168,0,53,0,177,255,177,0,53,0,178,255,177,0,53,0,179,255,177,0,53,0,180,255,177,0,53,0,181,255,177,0,53,0,183,255,177,0,53,0,184,255,169,0,53,0,185,255,169,0,53,0,186,255,169,0,53,0,187,255,169,0,53,0,188,255,171,0,53,0,189,255,208,0,53,0,190,255,171,0,53,0,193,255,247,0,53,0,194,255,232,0,53,0,195,255,177,0,53,0,197,255,216,0,53,0,200,255,208,0,53,0,207,255,216,0,53,0,208,255,216,0,53,0,211,255,213,0,53,0,214,255,213,0,53,0,218,255,214,0,53,0,220,255,195,0,53,0,221,255,197,0,53,0,240,0,16,0,54,0,10,255,245,0,54,0,13,255,243,0,54,0,15,255,243,0,54,0,16,255,234,0,54,0,34,255,240,0,54,0,46,255,248,0,54,0,59,255,251,0,54,0,66,255,242,0,54,0,67,255,245,0,54,0,68,255,243,0,54,0,69,255,243,0,54,0,70,255,243,0,54,0,71,255,250,0,54,0,72,255,242,0,54,0,73,255,245,0,54,0,74,255,243,0,54,0,75,255,243,0,54,0,76,255,245,0,54,0,77,255,244,0,54,0,78,255,240,0,54,0,79,255,240,0,54,0,80,255,243,0,54,0,81,255,240,0,54,0,82,255,243,0,54,0,83,255,240,0,54,0,84,255,243,0,54,0,85,255,249,0,54,0,86,255,242,0,54,0,87,255,250,0,54,0,88,255,250,0,54,0,89,255,250,0,54,0,90,255,250,0,54,0,91,255,244,0,54,0,127,255,240,0,54,0,128,255,240,0,54,0,129,255,240,0,54,0,130,255,240,0,54,0,131,255,240,0,54,0,132,255,240,0,54,0,133,255,240,0,54,0,158,255,248,0,54,0,159,255,242,0,54,0,160,255,242,0,54,0,161,255,242,0,54,0,162,255,242,0,54,0,163,255,242,0,54,0,164,255,242,0,54,0,165,255,242,0,54,0,166,255,243,0,54,0,167,255,243,0,54,0,168,255,243,0,54,0,169,255,243,0,54,0,170,255,243,0,54,0,171,255,243,0,54,0,172,255,243,0,54,0,173,255,251,0,54,0,174,255,243,0,54,0,175,255,242,0,54,0,176,255,240,0,54,0,177,255,243,0,54,0,178,255,243,0,54,0,179,255,243,0,54,0,180,255,243,0,54,0,181,255,243,0,54,0,183,255,243,0,54,0,184,255,242,0,54,0,185,255,242,0,54,0,186,255,242,0,54,0,187,255,242,0,54,0,188,255,250,0,54,0,189,255,240,0,54,0,190,255,250,0,54,0,193,255,243,0,54,0,195,255,243,0,54,0,197,255,243,0,54,0,199,255,251,0,54,0,200,255,244,0,54,0,211,255,243,0,54,0,214,255,243,0,54,0,218,255,243,0,55,0,7,255,243,0,55,0,11,0,16,0,55,0,13,255,213,0,55,0,14,255,238,0,55,0,15,255,213,0,55,0,16,255,201,0,55,0,17,255,246,0,55,0,21,255,220,0,55,0,23,255,230,0,55,0,28,255,248,0,55,0,33,255,213,0,55,0,34,255,207,0,55,0,36,255,244,0,55,0,40,255,244,0,55,0,46,255,235,0,55,0,48,255,244,0,55,0,50,255,244,0,55,0,62,0,29,0,55,0,66,255,216,0,55,0,68,255,196,0,55,0,69,255,196,0,55,0,70,255,196,0,55,0,71,255,244,0,55,0,72,255,203,0,55,0,78,255,220,0,55,0,79,255,220,0,55,0,80,255,196,0,55,0,81,255,220,0,55,0,82,255,196,0,55,0,83,255,220,0,55,0,84,255,217,0,55,0,85,255,239,0,55,0,86,255,220,0,55,0,87,255,242,0,55,0,88,255,241,0,55,0,89,255,243,0,55,0,90,255,243,0,55,0,91,255,243,0,55,0,94,0,29,0,55,0,107,255,220,0,55,0,110,255,245,0,55,0,122,255,244,0,55,0,127,255,207,0,55,0,128,255,207,0,55,0,129,255,207,0,55,0,130,255,207,0,55,0,131,255,207,0,55,0,132,255,207,0,55,0,133,255,196,0,55,0,134,255,244,0,55,0,145,255,244,0,55,0,146,255,244,0,55,0,147,255,244,0,55,0,148,255,244,0,55,0,149,255,244,0,55,0,151,255,244,0,55,0,158,255,242,0,55,0,159,255,216,0,55,0,160,255,216,0,55,0,161,255,216,0,55,0,162,255,216,0,55,0,163,255,216,0,55,0,164,255,216,0,55,0,165,255,216,0,55,0,166,255,196,0,55,0,167,255,196,0,55,0,168,255,196,0,55,0,169,255,196,0,55,0,170,255,196,0,55,0,171,0,9,0,55,0,173,0,44,0,55,0,174,0,40,0,55,0,175,255,216,0,55,0,176,255,220,0,55,0,177,255,196,0,55,0,178,255,196,0,55,0,179,255,196,0,55,0,180,255,196,0,55,0,181,255,196,0,55,0,183,255,196,0,55,0,184,255,220,0,55,0,185,255,220,0,55,0,186,255,220,0,55,0,187,255,220,0,55,0,188,255,243,0,55,0,189,255,220,0,55,0,190,255,243,0,55,0,194,255,244,0,55,0,195,255,196,0,55,0,197,255,227,0,55,0,200,255,243,0,55,0,207,255,238,0,55,0,208,255,238,0,55,0,211,255,213,0,55,0,214,255,213,0,55,0,218,255,213,0,55,0,220,255,220,0,55,0,221,255,244,0,55,0,240,0,26,0,56,0,7,255,247,0,56,0,11,0,17,0,56,0,13,255,225,0,56,0,14,255,248,0,56,0,15,255,226,0,56,0,16,255,215,0,56,0,21,255,233,0,56,0,23,255,241,0,56,0,33,255,223,0,56,0,34,255,219,0,56,0,36,255,249,0,56,0,40,255,249,0,56,0,46,255,239,0,56,0,48,255,249,0,56,0,50,255,249,0,56,0,62,0,26,0,56,0,66,255,216,0,56,0,68,255,217,0,56,0,69,255,217,0,56,0,70,255,217,0,56,0,71,255,247,0,56,0,72,255,216,0,56,0,74,255,251,0,56,0,75,255,251,0,56,0,78,255,224,0,56,0,79,255,224,0,56,0,80,255,217,0,56,0,81,255,224,0,56,0,82,255,217,0,56,0,83,255,224,0,56,0,84,255,219,0,56,0,85,255,243,0,56,0,86,255,227,0,56,0,87,255,247,0,56,0,88,255,247,0,56,0,89,255,249,0,56,0,90,255,248,0,56,0,91,255,247,0,56,0,94,0,28,0,56,0,107,255,230,0,56,0,127,255,219,0,56,0,128,255,219,0,56,0,129,255,219,0,56,0,130,255,219,0,56,0,131,255,219,0,56,0,132,255,219,0,56,0,133,255,209,0,56,0,134,255,249,0,56,0,145,255,249,0,56,0,146,255,249,0,56,0,147,255,249,0,56,0,148,255,249,0,56,0,149,255,249,0,56,0,151,255,249,0,56,0,158,255,245,0,56,0,159,255,216,0,56,0,160,255,216,0,56,0,161,255,216,0,56,0,162,255,216,0,56,0,163,255,216,0,56,0,164,255,216,0,56,0,165,255,216,0,56,0,166,255,217,0,56,0,167,255,217,0,56,0,168,255,217,0,56,0,169,255,217,0,56,0,170,255,217,0,56,0,171,0,4,0,56,0,172,255,251,0,56,0,173,0,44,0,56,0,174,0,36,0,56,0,175,255,222,0,56,0,176,255,224,0,56,0,177,255,217,0,56,0,178,255,217,0,56,0,179,255,217,0,56,0,180,255,217,0,56,0,181,255,217,0,56,0,183,255,217,0,56,0,184,255,227,0,56,0,185,255,227,0,56,0,186,255,227,0,56,0,187,255,227,0,56,0,188,255,248,0,56,0,189,255,224,0,56,0,190,255,248,0,56,0,193,255,251,0,56,0,194,255,249,0,56,0,195,255,217,0,56,0,197,255,219,0,56,0,200,255,247,0,56,0,207,255,248,0,56,0,208,255,248,0,56,0,211,255,225,0,56,0,214,255,225,0,56,0,218,255,226,0,56,0,220,255,230,0,56,0,240,0,23,0,57,0,7,255,246,0,57,0,14,255,243,0,57,0,36,255,229,0,57,0,40,255,229,0,57,0,48,255,229,0,57,0,50,255,229,0,57,0,52,255,251,0,57,0,62,0,31,0,57,0,68,255,223,0,57,0,69,255,223,0,57,0,70,255,223,0,57,0,71,255,245,0,57,0,72,255,238,0,57,0,80,255,223,0,57,0,82,255,223,0,57,0,85,255,228,0,57,0,86,255,232,0,57,0,87,255,207,0,57,0,88,255,213,0,57,0,90,255,206,0,57,0,94,0,31,0,57,0,107,255,226,0,57,0,110,255,238,0,57,0,134,255,229,0,57,0,145,255,229,0,57,0,146,255,229,0,57,0,147,255,229,0,57,0,148,255,229,0,57,0,149,255,229,0,57,0,151,255,229,0,57,0,158,255,243,0,57,0,166,255,223,0,57,0,167,255,223,0,57,0,168,255,223,0,57,0,169,255,223,0,57,0,170,255,223,0,57,0,171,0,7,0,57,0,173,0,23,0,57,0,174,0,38,0,57,0,175,255,239,0,57,0,177,255,223,0,57,0,178,255,223,0,57,0,179,255,223,0,57,0,180,255,223,0,57,0,181,255,223,0,57,0,183,255,223,0,57,0,184,255,232,0,57,0,185,255,232,0,57,0,186,255,232,0,57,0,187,255,232,0,57,0,188,255,206,0,57,0,190,255,206,0,57,0,194,255,229,0,57,0,195,255,223,0,57,0,196,255,251,0,57,0,207,255,243,0,57,0,208,255,243,0,57,0,220,255,226,0,57,0,240,0,24,0,58,0,7,255,237,0,58,0,11,0,13,0,58,0,13,255,215,0,58,0,14,255,222,0,58,0,15,255,215,0,58,0,16,255,201,0,58,0,17,255,233,0,58,0,21,255,206,0,58,0,23,255,218,0,58,0,25,255,246,0,58,0,27,255,235,0,58,0,28,255,235,0,58,0,32,0,13,0,58,0,33,255,198,0,58,0,34,255,192,0,58,0,36,255,230,0,58,0,40,255,230,0,58,0,46,255,232,0,58,0,48,255,230,0,58,0,50,255,230,0,58,0,61,0,7,0,58,0,62,0,31,0,58,0,66,255,189,0,58,0,68,255,171,0,58,0,69,255,171,0,58,0,70,255,171,0,58,0,71,255,237,0,58,0,72,255,180,0,58,0,78,255,187,0,58,0,79,255,187,0,58,0,80,255,171,0,58,0,81,255,187,0,58,0,82,255,171,0,58,0,83,255,187,0,58,0,84,255,186,0,58,0,85,255,221,0,58,0,86,255,190,0,58,0,87,255,215,0,58,0,88,255,216,0,58,0,89,255,214,0,58,0,90,255,217,0,58,0,91,255,229,0,58,0,94,0,33,0,58,0,107,255,198,0,58,0,110,255,230,0,58,0,122,255,225,0,58,0,127,255,192,0,58,0,128,255,192,0,58,0,129,255,192,0,58,0,130,255,192,0,58,0,131,255,192,0,58,0,132,255,192,0,58,0,133,255,180,0,58,0,134,255,230,0,58,0,145,255,230,0,58,0,146,255,230,0,58,0,147,255,230,0,58,0,148,255,230,0,58,0,149,255,230,0,58,0,151,255,230,0,58,0,158,255,230,0,58,0,159,255,189,0,58,0,160,255,189,0,58,0,161,255,189,0,58,0,162,255,189,0,58,0,163,255,189,0,58,0,164,255,189,0,58,0,165,255,189,0,58,0,166,255,171,0,58,0,167,255,171,0,58,0,168,255,171,0,58,0,169,255,171,0,58,0,170,255,171,0,58,0,171,0,16,0,58,0,173,0,38,0,58,0,174,0,47,0,58,0,175,255,216,0,58,0,176,255,187,0,58,0,177,255,171,0,58,0,178,255,171,0,58,0,179,255,171,0,58,0,180,255,171,0,58,0,181,255,171,0,58,0,183,255,171,0,58,0,184,255,190,0,58,0,185,255,190,0,58,0,186,255,190,0,58,0,187,255,190,0,58,0,188,255,217,0,58,0,189,255,225,0,58,0,190,255,217,0,58,0,194,255,230,0,58,0,195,255,171,0,58,0,197,255,234,0,58,0,200,255,229,0,58,0,207,255,222,0,58,0,208,255,222,0,58,0,211,255,215,0,58,0,214,255,215,0,58,0,218,255,215,0,58,0,220,255,198,0,58,0,221,255,225,0,58,0,240,0,33,0,59,0,14,255,217,0,59,0,17,255,243,0,59,0,21,255,199,0,59,0,23,255,247,0,59,0,36,255,238,0,59,0,40,255,238,0,59,0,48,255,238,0,59,0,50,255,238,0,59,0,62,0,23,0,59,0,66,255,246,0,59,0,68,255,227,0,59,0,69,255,227,0,59,0,70,255,227,0,59,0,71,255,241,0,59,0,72,255,229,0,59,0,74,255,250,0,59,0,75,255,250,0,59,0,78,255,235,0,59,0,79,255,235,0,59,0,80,255,227,0,59,0,81,255,235,0,59,0,82,255,227,0,59,0,83,255,235,0,59,0,84,255,245,0,59,0,85,255,241,0,59,0,86,255,224,0,59,0,87,255,241,0,59,0,88,255,241,0,59,0,90,255,242,0,59,0,91,255,248,0,59,0,94,0,23,0,59,0,107,255,214,0,59,0,110,255,233,0,59,0,134,255,238,0,59,0,145,255,238,0,59,0,146,255,238,0,59,0,147,255,238,0,59,0,148,255,238,0,59,0,149,255,238,0,59,0,151,255,238,0,59,0,158,255,239,0,59,0,159,255,246,0,59,0,160,255,246,0,59,0,161,255,246,0,59,0,162,255,246,0,59,0,163,255,246,0,59,0,164,255,246,0,59,0,165,255,246,0,59,0,166,255,227,0,59,0,167,255,227,0,59,0,168,255,227,0,59,0,169,255,227,0,59,0,170,255,227,0,59,0,171,0,6,0,59,0,172,255,250,0,59,0,173,0,29,0,59,0,174,0,37,0,59,0,175,255,235,0,59,0,176,255,235,0,59,0,177,255,227,0,59,0,178,255,227,0,59,0,179,255,227,0,59,0,180,255,227,0,59,0,181,255,227,0,59,0,183,255,227,0,59,0,184,255,224,0,59,0,185,255,224,0,59,0,186,255,224,0,59,0,187,255,224,0,59,0,188,255,242,0,59,0,189,255,235,0,59,0,190,255,242,0,59,0,193,255,250,0,59,0,194,255,238,0,59,0,195,255,227,0,59,0,197,255,245,0,59,0,200,255,248,0,59,0,207,255,217,0,59,0,208,255,217,0,59,0,220,255,214,0,59,0,240,0,24,0,60,0,17,255,232,0,60,0,21,255,228,0,60,0,23,255,229,0,60,0,25,255,248,0,60,0,34,255,227,0,60,0,36,255,226,0,60,0,40,255,226,0,60,0,43,0,49,0,60,0,46,255,244,0,60,0,48,255,226,0,60,0,50,255,226,0,60,0,53,0,22,0,60,0,55,0,31,0,60,0,56,0,27,0,60,0,57,0,28,0,60,0,58,0,36,0,60,0,66,255,218,0,60,0,68,255,213,0,60,0,69,255,213,0,60,0,70,255,213,0,60,0,75,0,7,0,60,0,78,255,214,0,60,0,79,255,214,0,60,0,80,255,213,0,60,0,81,255,223,0,60,0,82,255,213,0,60,0,83,255,214,0,60,0,84,255,218,0,60,0,85,255,224,0,60,0,86,255,215,0,60,0,87,255,216,0,60,0,88,255,218,0,60,0,89,255,226,0,60,0,90,255,216,0,60,0,91,255,219,0,60,0,127,255,227,0,60,0,128,255,227,0,60,0,129,255,227,0,60,0,130,255,227,0,60,0,131,255,227,0,60,0,132,255,227,0,60,0,133,255,243,0,60,0,134,255,226,0,60,0,145,255,226,0,60,0,146,255,226,0,60,0,147,255,226,0,60,0,148,255,226,0,60,0,149,255,226,0,60,0,151,255,226,0,60,0,156,0,36,0,60,0,158,255,244,0,60,0,159,255,218,0,60,0,160,255,218,0,60,0,161,255,218,0,60,0,162,255,228,0,60,0,163,255,218,0,60,0,164,255,218,0,60,0,165,255,218,0,60,0,166,255,213,0,60,0,167,255,213,0,60,0,168,255,213,0,60,0,169,255,213,0,60,0,170,255,213,0,60,0,171,0,15,0,60,0,173,0,34,0,60,0,174,0,45,0,60,0,175,255,231,0,60,0,176,255,214,0,60,0,177,255,213,0,60,0,178,255,213,0,60,0,179,255,213,0,60,0,180,255,213,0,60,0,181,255,213,0,60,0,183,255,213,0,60,0,184,255,215,0,60,0,185,255,215,0,60,0,186,255,215,0,60,0,187,255,215,0,60,0,188,255,216,0,60,0,189,255,252,0,60,0,190,255,216,0,60,0,194,255,226,0,60,0,195,255,213,0,60,0,197,255,232,0,60,0,198,0,36,0,60,0,200,255,246,0,61,0,3,255,220,0,61,0,8,255,220,0,61,0,17,255,244,0,61,0,18,255,241,0,61,0,26,255,242,0,61,0,36,255,236,0,61,0,40,255,236,0,61,0,43,0,16,0,61,0,48,255,236,0,61,0,50,255,236,0,61,0,53,255,205,0,61,0,54,255,234,0,61,0,55,255,201,0,61,0,56,255,216,0,61,0,58,255,201,0,61,0,85,255,240,0,61,0,87,255,222,0,61,0,88,255,231,0,61,0,90,255,219,0,61,0,134,255,236,0,61,0,145,255,236,0,61,0,146,255,236,0,61,0,147,255,236,0,61,0,148,255,236,0,61,0,149,255,236,0,61,0,151,255,236,0,61,0,152,255,234,0,61,0,153,255,234,0,61,0,154,255,234,0,61,0,155,255,234,0,61,0,156,255,201,0,61,0,188,255,219,0,61,0,190,255,219,0,61,0,194,255,236,0,61,0,198,255,201,0,61,0,210,255,214,0,61,0,213,255,214,0,66,0,3,255,234,0,66,0,7,255,245,0,66,0,8,255,234,0,66,0,10,255,246,0,66,0,11,255,231,0,66,0,18,255,234,0,66,0,26,255,247,0,66,0,32,255,229,0,66,0,35,255,240,0,66,0,36,255,237,0,66,0,37,255,240,0,66,0,38,255,240,0,66,0,39,255,240,0,66,0,40,255,237,0,66,0,41,255,240,0,66,0,42,255,240,0,66,0,43,255,240,0,66,0,44,255,240,0,66,0,45,255,240,0,66,0,46,255,248,0,66,0,47,255,240,0,66,0,48,255,237,0,66,0,49,255,240,0,66,0,50,255,237,0,66,0,51,255,240,0,66,0,52,255,250,0,66,0,53,255,173,0,66,0,54,255,227,0,66,0,55,255,193,0,66,0,56,255,210,0,66,0,58,255,165,0,66,0,61,255,210,0,66,0,62,255,227,0,66,0,71,255,251,0,66,0,85,255,246,0,66,0,87,255,238,0,66,0,88,255,243,0,66,0,90,255,236,0,66,0,94,255,231,0,66,0,110,255,248,0,66,0,134,255,237,0,66,0,135,255,240,0,66,0,136,255,240,0,66,0,137,255,240,0,66,0,138,255,240,0,66,0,139,255,240,0,66,0,140,255,240,0,66,0,141,255,240,0,66,0,142,255,240,0,66,0,143,255,240,0,66,0,144,255,240,0,66,0,145,255,237,0,66,0,146,255,237,0,66,0,147,255,237,0,66,0,148,255,237,0,66,0,149,255,237,0,66,0,151,255,237,0,66,0,152,255,227,0,66,0,153,255,227,0,66,0,154,255,227,0,66,0,155,255,227,0,66,0,156,255,165,0,66,0,157,255,240,0,66,0,158,255,249,0,66,0,188,255,236,0,66,0,190,255,236,0,66,0,194,255,237,0,66,0,196,255,250,0,66,0,198,255,165,0,66,0,209,255,186,0,66,0,210,255,183,0,66,0,212,255,186,0,66,0,213,255,183,0,66,0,240,255,230,0,67,0,3,255,234,0,67,0,7,255,246,0,67,0,8,255,234,0,67,0,10,255,227,0,67,0,11,255,232,0,67,0,13,255,246,0,67,0,15,255,247,0,67,0,18,255,235,0,67,0,19,255,232,0,67,0,24,255,226,0,67,0,32,255,224,0,67,0,34,255,240,0,67,0,35,255,237,0,67,0,36,255,246,0,67,0,37,255,237,0,67,0,38,255,237,0,67,0,39,255,237,0,67,0,40,255,246,0,67,0,41,255,237,0,67,0,42,255,237,0,67,0,43,255,237,0,67,0,44,255,237,0,67,0,45,255,237,0,67,0,46,255,239,0,67,0,47,255,237,0,67,0,48,255,246,0,67,0,49,255,237,0,67,0,50,255,246,0,67,0,51,255,237,0,67,0,52,255,237,0,67,0,53,255,171,0,67,0,54,255,238,0,67,0,55,255,193,0,67,0,56,255,212,0,67,0,57,255,217,0,67,0,58,255,167,0,67,0,59,255,227,0,67,0,61,255,217,0,67,0,62,255,217,0,67,0,71,255,251,0,67,0,85,255,250,0,67,0,87,255,247,0,67,0,88,255,251,0,67,0,89,255,238,0,67,0,90,255,245,0,67,0,91,255,246,0,67,0,94,255,226,0,67,0,122,255,247,0,67,0,127,255,240,0,67,0,128,255,240,0,67,0,129,255,240,0,67,0,130,255,240,0,67,0,131,255,240,0,67,0,132,255,240,0,67,0,134,255,246,0,67,0,135,255,237,0,67,0,136,255,237,0,67,0,137,255,237,0,67,0,138,255,237,0,67,0,139,255,237,0,67,0,140,255,237,0,67,0,141,255,237,0,67,0,142,255,237,0,67,0,143,255,237,0,67,0,144,255,237,0,67,0,145,255,246,0,67,0,146,255,246,0,67,0,147,255,246,0,67,0,148,255,246,0,67,0,149,255,246,0,67,0,151,255,246,0,67,0,152,255,238,0,67,0,153,255,238,0,67,0,154,255,238,0,67,0,155,255,238,0,67,0,156,255,167,0,67,0,157,255,237,0,67,0,158,255,248,0,67,0,188,255,245,0,67,0,190,255,245,0,67,0,194,255,246,0,67,0,196,255,237,0,67,0,198,255,167,0,67,0,199,255,227,0,67,0,200,255,246,0,67,0,209,255,181,0,67,0,210,255,178,0,67,0,211,255,246,0,67,0,212,255,181,0,67,0,213,255,178,0,67,0,214,255,246,0,67,0,218,255,247,0,67,0,221,255,247,0,67,0,240,255,234,0,68,0,7,255,240,0,68,0,10,255,244,0,68,0,14,255,219,0,68,0,21,255,231,0,68,0,24,255,245,0,68,0,32,255,228,0,68,0,35,255,247,0,68,0,36,255,244,0,68,0,37,255,247,0,68,0,38,255,247,0,68,0,39,255,247,0,68,0,40,255,244,0,68,0,41,255,247,0,68,0,42,255,247,0,68,0,43,255,247,0,68,0,44,255,247,0,68,0,45,255,247,0,68,0,46,255,251,0,68,0,47,255,247,0,68,0,48,255,244,0,68,0,49,255,247,0,68,0,50,255,244,0,68,0,51,255,247,0,68,0,52,255,244,0,68,0,53,255,190,0,68,0,54,255,243,0,68,0,55,255,236,0,68,0,56,255,241,0,68,0,58,255,218,0,68,0,61,255,240,0,68,0,62,255,232,0,68,0,68,255,249,0,68,0,69,255,249,0,68,0,70,255,249,0,68,0,80,255,249,0,68,0,82,255,249,0,68,0,94,255,239,0,68,0,107,255,243,0,68,0,134,255,244,0,68,0,135,255,247,0,68,0,136,255,247,0,68,0,137,255,247,0,68,0,138,255,247,0,68,0,139,255,247,0,68,0,140,255,247,0,68,0,141,255,247,0,68,0,142,255,247,0,68,0,143,255,247,0,68,0,144,255,247,0,68,0,145,255,244,0,68,0,146,255,244,0,68,0,147,255,244,0,68,0,148,255,244,0,68,0,149,255,244,0,68,0,151,255,244,0,68,0,152,255,243,0,68,0,153,255,243,0,68,0,154,255,243,0,68,0,155,255,243,0,68,0,156,255,218,0,68,0,157,255,247,0,68,0,166,255,249,0,68,0,167,255,249,0,68,0,168,255,249,0,68,0,169,255,249,0,68,0,170,255,249,0,68,0,175,255,251,0,68,0,177,255,249,0,68,0,178,255,249,0,68,0,179,255,249,0,68,0,180,255,249,0,68,0,181,255,249,0,68,0,183,255,249,0,68,0,194,255,244,0,68,0,195,255,249,0,68,0,196,255,244,0,68,0,198,255,218,0,68,0,207,255,219,0,68,0,208,255,219,0,68,0,209,255,216,0,68,0,210,255,213,0,68,0,212,255,216,0,68,0,213,255,213,0,68,0,220,255,243,0,68,0,240,255,245,0,69,0,7,255,244,0,69,0,34,255,249,0,69,0,35,255,242,0,69,0,36,255,245,0,69,0,37,255,242,0,69,0,38,255,242,0,69,0,39,255,242,0,69,0,40,255,245,0,69,0,41,255,242,0,69,0,42,255,242,0,69,0,43,255,242,0,69,0,44,255,242,0,69,0,45,255,242,0,69,0,46,255,240,0,69,0,47,255,242,0,69,0,48,255,245,0,69,0,49,255,242,0,69,0,50,255,245,0,69,0,51,255,242,0,69,0,52,255,246,0,69,0,53,255,245,0,69,0,54,255,240,0,69,0,55,255,250,0,69,0,56,255,248,0,69,0,58,255,251,0,69,0,59,255,245,0,69,0,127,255,249,0,69,0,128,255,249,0,69,0,129,255,249,0,69,0,130,255,249,0,69,0,131,255,249,0,69,0,132,255,249,0,69,0,134,255,245,0,69,0,135,255,242,0,69,0,136,255,242,0,69,0,137,255,242,0,69,0,138,255,242,0,69,0,139,255,242,0,69,0,140,255,242,0,69,0,141,255,242,0,69,0,142,255,242,0,69,0,143,255,242,0,69,0,144,255,242,0,69,0,145,255,245,0,69,0,146,255,245,0,69,0,147,255,245,0,69,0,148,255,245,0,69,0,149,255,245,0,69,0,151,255,245,0,69,0,152,255,240,0,69,0,153,255,240,0,69,0,154,255,240,0,69,0,155,255,240,0,69,0,156,255,251,0,69,0,157,255,242,0,69,0,194,255,245,0,69,0,196,255,246,0,69,0,198,255,251,0,69,0,199,255,245,0,70,0,3,255,241,0,70,0,7,255,246,0,70,0,8,255,241,0,70,0,10,255,230,0,70,0,11,255,238,0,70,0,18,255,235,0,70,0,19,255,245,0,70,0,24,255,230,0,70,0,32,255,223,0,70,0,34,255,251,0,70,0,35,255,241,0,70,0,36,255,250,0,70,0,37,255,241,0,70,0,38,255,241,0,70,0,39,255,241,0,70,0,40,255,250,0,70,0,41,255,241,0,70,0,42,255,241,0,70,0,43,255,241,0,70,0,44,255,241,0,70,0,45,255,241,0,70,0,46,255,243,0,70,0,47,255,241,0,70,0,48,255,250,0,70,0,49,255,241,0,70,0,50,255,250,0,70,0,51,255,241,0,70,0,52,255,241,0,70,0,53,255,187,0,70,0,54,255,240,0,70,0,55,255,209,0,70,0,56,255,213,0,70,0,57,255,243,0,70,0,58,255,174,0,70,0,59,255,243,0,70,0,61,255,220,0,70,0,62,255,220,0,70,0,87,255,252,0,70,0,89,255,251,0,70,0,90,255,251,0,70,0,94,255,227,0,70,0,127,255,251,0,70,0,128,255,251,0,70,0,129,255,251,0,70,0,130,255,251,0,70,0,131,255,251,0,70,0,132,255,251,0,70,0,134,255,250,0,70,0,135,255,241,0,70,0,136,255,241,0,70,0,137,255,241,0,70,0,138,255,241,0,70,0,139,255,241,0,70,0,140,255,241,0,70,0,141,255,241,0,70,0,142,255,241,0,70,0,143,255,241,0,70,0,144,255,241,0,70,0,145,255,250,0,70,0,146,255,250,0,70,0,147,255,250,0,70,0,148,255,250,0,70,0,149,255,250,0,70,0,151,255,250,0,70,0,152,255,240,0,70,0,153,255,240,0,70,0,154,255,240,0,70,0,155,255,240,0,70,0,156,255,174,0,70,0,157,255,241,0,70,0,188,255,251,0,70,0,190,255,251,0,70,0,194,255,250,0,70,0,196,255,241,0,70,0,198,255,174,0,70,0,199,255,243,0,70,0,209,255,189,0,70,0,210,255,186,0,70,0,212,255,189,0,70,0,213,255,186,0,70,0,240,255,237,0,71,0,7,255,235,0,71,0,13,255,229,0,71,0,14,255,232,0,71,0,15,255,229,0,71,0,16,255,234,0,71,0,21,255,244,0,71,0,33,255,239,0,71,0,34,255,211,0,71,0,35,255,244,0,71,0,37,255,244,0,71,0,38,255,244,0,71,0,39,255,244,0,71,0,41,255,244,0,71,0,42,255,244,0,71,0,43,255,244,0,71,0,44,255,244,0,71,0,45,255,244,0,71,0,46,255,229,0,71,0,47,255,244,0,71,0,49,255,244,0,71,0,51,255,244,0,71,0,54,255,247,0,71,0,59,255,243,0,71,0,66,255,251,0,71,0,68,255,246,0,71,0,69,255,246,0,71,0,70,255,246,0,71,0,72,255,252,0,71,0,80,255,246,0,71,0,82,255,246,0,71,0,94,0,8,0,71,0,107,255,239,0,71,0,127,255,211,0,71,0,128,255,211,0,71,0,129,255,211,0,71,0,130,255,211,0,71,0,131,255,211,0,71,0,132,255,211,0,71,0,135,255,244,0,71,0,136,255,244,0,71,0,137,255,244,0,71,0,138,255,244,0,71,0,139,255,244,0,71,0,140,255,244,0,71,0,141,255,244,0,71,0,142,255,244,0,71,0,143,255,244,0,71,0,144,255,244,0,71,0,152,255,247,0,71,0,153,255,247,0,71,0,154,255,247,0,71,0,155,255,247,0,71,0,157,255,244,0,71,0,159,255,251,0,71,0,160,255,251,0,71,0,161,255,251,0,71,0,162,255,251,0,71,0,163,255,251,0,71,0,164,255,251,0,71,0,165,255,251,0,71,0,166,255,246,0,71,0,167,255,246,0,71,0,168,255,246,0,71,0,169,255,246,0,71,0,170,255,246,0,71,0,175,255,224,0,71,0,177,255,246,0,71,0,178,255,246,0,71,0,179,255,246,0,71,0,180,255,246,0,71,0,181,255,246,0,71,0,183,255,246,0,71,0,195,255,246,0,71,0,199,255,243,0,71,0,207,255,232,0,71,0,208,255,232,0,71,0,211,255,229,0,71,0,214,255,229,0,71,0,218,255,229,0,71,0,220,255,239,0,72,0,7,255,244,0,72,0,10,0,5,0,72,0,16,0,14,0,72,0,24,255,225,0,72,0,32,255,217,0,72,0,34,255,249,0,72,0,35,255,245,0,72,0,37,255,245,0,72,0,38,255,245,0,72,0,39,255,245,0,72,0,41,255,245,0,72,0,42,255,245,0,72,0,43,0,45,0,72,0,44,255,245,0,72,0,45,255,245,0,72,0,46,255,242,0,72,0,47,255,245,0,72,0,49,255,245,0,72,0,51,255,245,0,72,0,53,255,208,0,72,0,54,255,246,0,72,0,55,255,247,0,72,0,56,255,250,0,72,0,57,255,250,0,72,0,58,255,238,0,72,0,59,255,245,0,72,0,62,0,25,0,72,0,75,0,19,0,72,0,94,0,29,0,72,0,127,255,249,0,72,0,128,255,249,0,72,0,129,255,249,0,72,0,130,255,249,0,72,0,131,255,249,0,72,0,132,255,249,0,72,0,135,255,245,0,72,0,136,255,245,0,72,0,137,255,245,0,72,0,138,255,245,0,72,0,139,255,245,0,72,0,140,255,245,0,72,0,141,255,245,0,72,0,142,255,245,0,72,0,143,255,245,0,72,0,144,255,245,0,72,0,152,255,246,0,72,0,153,255,246,0,72,0,154,255,246,0,72,0,155,255,246,0,72,0,156,255,238,0,72,0,157,255,245,0,72,0,175,255,250,0,72,0,198,255,238,0,72,0,199,255,245,0,72,0,209,255,223,0,72,0,210,255,221,0,72,0,212,255,223,0,72,0,213,255,221,0,73,0,2,255,248,0,73,0,3,255,238,0,73,0,7,255,245,0,73,0,8,255,238,0,73,0,10,255,232,0,73,0,11,255,235,0,73,0,18,255,231,0,73,0,24,255,233,0,73,0,32,255,224,0,73,0,34,255,250,0,73,0,35,255,238,0,73,0,36,255,243,0,73,0,37,255,238,0,73,0,38,255,238,0,73,0,39,255,238,0,73,0,40,255,243,0,73,0,41,255,238,0,73,0,42,255,238,0,73,0,43,255,238,0,73,0,44,255,238,0,73,0,45,255,238,0,73,0,46,255,241,0,73,0,47,255,238,0,73,0,48,255,243,0,73,0,49,255,238,0,73,0,50,255,243,0,73,0,51,255,238,0,73,0,52,255,241,0,73,0,53,255,162,0,73,0,54,255,231,0,73,0,55,255,198,0,73,0,56,255,214,0,73,0,57,255,249,0,73,0,58,255,163,0,73,0,59,255,245,0,73,0,61,255,214,0,73,0,62,255,216,0,73,0,71,255,251,0,73,0,85,255,248,0,73,0,87,255,243,0,73,0,88,255,248,0,73,0,90,255,242,0,73,0,94,255,225,0,73,0,127,255,250,0,73,0,128,255,250,0,73,0,129,255,250,0,73,0,130,255,250,0,73,0,131,255,250,0,73,0,132,255,250,0,73,0,134,255,243,0,73,0,135,255,238,0,73,0,136,255,238,0,73,0,137,255,238,0,73,0,138,255,238,0,73,0,139,255,238,0,73,0,140,255,238,0,73,0,141,255,238,0,73,0,142,255,238,0,73,0,143,255,238,0,73,0,144,255,238,0,73,0,145,255,243,0,73,0,146,255,243,0,73,0,147,255,243,0,73,0,148,255,243,0,73,0,149,255,243,0,73,0,151,255,243,0,73,0,152,255,231,0,73,0,153,255,231,0,73,0,154,255,231,0,73,0,155,255,231,0,73,0,156,255,163,0,73,0,157,255,238,0,73,0,158,255,248,0,73,0,188,255,242,0,73,0,190,255,242,0,73,0,194,255,243,0,73,0,196,255,241,0,73,0,198,255,163,0,73,0,199,255,245,0,73,0,209,255,187,0,73,0,210,255,184,0,73,0,212,255,187,0,73,0,213,255,184,0,73,0,240,255,235,0,74,0,7,255,244,0,74,0,34,255,248,0,74,0,35,255,242,0,74,0,36,255,244,0,74,0,37,255,242,0,74,0,38,255,242,0,74,0,39,255,242,0,74,0,40,255,244,0,74,0,41,255,242,0,74,0,42,255,242,0,74,0,43,255,242,0,74,0,44,255,242,0,74,0,45,255,242,0,74,0,46,255,241,0,74,0,47,255,242,0,74,0,48,255,244,0,74,0,49,255,242,0,74,0,50,255,244,0,74,0,51,255,242,0,74,0,52,255,244,0,74,0,53,255,242,0,74,0,54,255,238,0,74,0,55,255,247,0,74,0,56,255,246,0,74,0,58,255,247,0,74,0,59,255,245,0,74,0,127,255,248,0,74,0,128,255,248,0,74,0,129,255,248,0,74,0,130,255,248,0,74,0,131,255,248,0,74,0,132,255,248,0,74,0,134,255,244,0,74,0,135,255,242,0,74,0,136,255,242,0,74,0,137,255,242,0,74,0,138,255,242,0,74,0,139,255,242,0,74,0,140,255,242,0,74,0,141,255,242,0,74,0,142,255,242,0,74,0,143,255,242,0,74,0,144,255,242,0,74,0,145,255,244,0,74,0,146,255,244,0,74,0,147,255,244,0,74,0,148,255,244,0,74,0,149,255,244,0,74,0,151,255,244,0,74,0,152,255,238,0,74,0,153,255,238,0,74,0,154,255,238,0,74,0,155,255,238,0,74,0,156,255,247,0,74,0,157,255,242,0,74,0,194,255,244,0,74,0,196,255,244,0,74,0,198,255,247,0,74,0,199,255,245,0,75,0,7,255,244,0,75,0,34,255,248,0,75,0,35,255,242,0,75,0,36,255,244,0,75,0,37,255,242,0,75,0,38,255,242,0,75,0,39,255,242,0,75,0,40,255,244,0,75,0,41,255,242,0,75,0,42,255,242,0,75,0,43,255,242,0,75,0,44,255,242,0,75,0,45,255,242,0,75,0,46,255,241,0,75,0,47,255,242,0,75,0,48,255,244,0,75,0,49,255,242,0,75,0,50,255,244,0,75,0,51,255,242,0,75,0,52,255,244,0,75,0,53,255,242,0,75,0,54,255,238,0,75,0,55,255,247,0,75,0,56,255,246,0,75,0,58,255,247,0,75,0,59,255,245,0,75,0,127,255,248,0,75,0,128,255,248,0,75,0,129,255,248,0,75,0,130,255,248,0,75,0,131,255,248,0,75,0,132,255,248,0,75,0,134,255,244,0,75,0,135,255,242,0,75,0,136,255,242,0,75,0,137,255,242,0,75,0,138,255,242,0,75,0,139,255,242,0,75,0,140,255,242,0,75,0,141,255,242,0,75,0,142,255,242,0,75,0,143,255,242,0,75,0,144,255,242,0,75,0,145,255,244,0,75,0,146,255,244,0,75,0,147,255,244,0,75,0,148,255,244,0,75,0,149,255,244,0,75,0,151,255,244,0,75,0,152,255,238,0,75,0,153,255,238,0,75,0,154,255,238,0,75,0,155,255,238,0,75,0,156,255,247,0,75,0,157,255,242,0,75,0,194,255,244,0,75,0,196,255,244,0,75,0,198,255,247,0,75,0,199,255,245,0,76,0,7,255,242,0,76,0,14,255,241,0,76,0,32,255,237,0,76,0,36,255,234,0,76,0,40,255,234,0,76,0,48,255,234,0,76,0,50,255,234,0,76,0,53,255,166,0,76,0,54,255,251,0,76,0,55,255,245,0,76,0,56,255,251,0,76,0,58,255,217,0,76,0,62,255,239,0,76,0,66,255,251,0,76,0,68,255,234,0,76,0,69,255,234,0,76,0,70,255,234,0,76,0,72,255,238,0,76,0,80,255,234,0,76,0,82,255,234,0,76,0,107,255,238,0,76,0,134,255,234,0,76,0,145,255,234,0,76,0,146,255,234,0,76,0,147,255,234,0,76,0,148,255,234,0,76,0,149,255,234,0,76,0,151,255,234,0,76,0,152,255,251,0,76,0,153,255,251,0,76,0,154,255,251,0,76,0,155,255,251,0,76,0,156,255,217,0,76,0,159,255,251,0,76,0,160,255,251,0,76,0,161,255,251,0,76,0,162,255,251,0,76,0,163,255,251,0,76,0,164,255,251,0,76,0,165,255,251,0,76,0,166,255,234,0,76,0,167,255,234,0,76,0,168,255,234,0,76,0,169,255,234,0,76,0,170,255,234,0,76,0,175,255,230,0,76,0,177,255,234,0,76,0,178,255,234,0,76,0,179,255,234,0,76,0,180,255,234,0,76,0,181,255,234,0,76,0,183,255,234,0,76,0,194,255,234,0,76,0,195,255,234,0,76,0,198,255,217,0,76,0,207,255,241,0,76,0,208,255,241,0,76,0,209,255,229,0,76,0,210,255,227,0,76,0,212,255,229,0,76,0,213,255,227,0,76,0,220,255,238,0,77,0,3,255,247,0,77,0,7,255,244,0,77,0,8,255,247,0,77,0,11,255,246,0,77,0,35,255,240,0,77,0,36,255,237,0,77,0,37,255,240,0,77,0,38,255,240,0,77,0,39,255,240,0,77,0,40,255,237,0,77,0,41,255,240,0,77,0,42,255,240,0,77,0,43,255,240,0,77,0,44,255,240,0,77,0,45,255,240,0,77,0,46,255,248,0,77,0,47,255,240,0,77,0,48,255,237,0,77,0,49,255,240,0,77,0,50,255,237,0,77,0,51,255,240,0,77,0,53,255,234,0,77,0,54,255,228,0,77,0,55,255,239,0,77,0,56,255,237,0,77,0,58,255,241,0,77,0,68,255,251,0,77,0,69,255,251,0,77,0,70,255,251,0,77,0,80,255,251,0,77,0,82,255,251,0,77,0,85,255,251,0,77,0,87,255,249,0,77,0,88,255,251,0,77,0,90,255,249,0,77,0,107,255,247,0,77,0,134,255,237,0,77,0,135,255,240,0,77,0,136,255,240,0,77,0,137,255,240,0,77,0,138,255,240,0,77,0,139,255,240,0,77,0,140,255,240,0,77,0,141,255,240,0,77,0,142,255,240,0,77,0,143,255,240,0,77,0,144,255,240,0,77,0,145,255,237,0,77,0,146,255,237,0,77,0,147,255,237,0,77,0,148,255,237,0,77,0,149,255,237,0,77,0,151,255,237,0,77,0,152,255,228,0,77,0,153,255,228,0,77,0,154,255,228,0,77,0,155,255,228,0,77,0,156,255,241,0,77,0,157,255,240,0,77,0,166,255,251,0,77,0,167,255,251,0,77,0,168,255,251,0,77,0,169,255,251,0,77,0,170,255,251,0,77,0,177,255,251,0,77,0,178,255,251,0,77,0,179,255,251,0,77,0,180,255,251,0,77,0,181,255,251,0,77,0,183,255,251,0,77,0,188,255,249,0,77,0,190,255,249,0,77,0,194,255,237,0,77,0,195,255,251,0,77,0,198,255,241,0,77,0,209,255,245,0,77,0,210,255,246,0,77,0,212,255,245,0,77,0,213,255,246,0,77,0,220,255,247,0,78,0,2,255,248,0,78,0,3,255,238,0,78,0,7,255,245,0,78,0,8,255,238,0,78,0,10,255,232,0,78,0,11,255,235,0,78,0,18,255,231,0,78,0,24,255,233,0,78,0,32,255,224,0,78,0,34,255,250,0,78,0,35,255,238,0,78,0,36,255,243,0,78,0,37,255,238,0,78,0,38,255,238,0,78,0,39,255,238,0,78,0,40,255,243,0,78,0,41,255,238,0,78,0,42,255,238,0,78,0,43,255,238,0,78,0,44,255,238,0,78,0,45,255,238,0,78,0,46,255,241,0,78,0,47,255,238,0,78,0,48,255,243,0,78,0,49,255,238,0,78,0,50,255,243,0,78,0,51,255,238,0,78,0,52,255,241,0,78,0,53,255,162,0,78,0,54,255,231,0,78,0,55,255,198,0,78,0,56,255,214,0,78,0,57,255,249,0,78,0,58,255,163,0,78,0,59,255,245,0,78,0,61,255,214,0,78,0,62,255,216,0,78,0,71,255,251,0,78,0,85,255,248,0,78,0,87,255,243,0,78,0,88,255,248,0,78,0,90,255,242,0,78,0,94,255,225,0,78,0,127,255,250,0,78,0,128,255,250,0,78,0,129,255,250,0,78,0,130,255,250,0,78,0,131,255,250,0,78,0,132,255,250,0,78,0,134,255,243,0,78,0,135,255,238,0,78,0,136,255,238,0,78,0,137,255,238,0,78,0,138,255,238,0,78,0,139,255,238,0,78,0,140,255,238,0,78,0,141,255,238,0,78,0,142,255,238,0,78,0,143,255,238,0,78,0,144,255,238,0,78,0,145,255,243,0,78,0,146,255,243,0,78,0,147,255,243,0,78,0,148,255,243,0,78,0,149,255,243,0,78,0,151,255,243,0,78,0,152,255,231,0,78,0,153,255,231,0,78,0,154,255,231,0,78,0,155,255,231,0,78,0,156,255,163,0,78,0,157,255,238,0,78,0,158,255,248,0,78,0,188,255,242,0,78,0,190,255,242,0,78,0,194,255,243,0,78,0,196,255,241,0,78,0,198,255,163,0,78,0,199,255,245,0,78,0,209,255,187,0,78,0,210,255,184,0,78,0,212,255,187,0,78,0,213,255,184,0,78,0,240,255,235,0,79,0,2,255,248,0,79,0,3,255,238,0,79,0,7,255,245,0,79,0,8,255,238,0,79,0,10,255,232,0,79,0,11,255,235,0,79,0,18,255,231,0,79,0,24,255,233,0,79,0,32,255,224,0,79,0,34,255,250,0,79,0,35,255,238,0,79,0,36,255,243,0,79,0,37,255,238,0,79,0,38,255,238,0,79,0,39,255,238,0,79,0,40,255,243,0,79,0,41,255,238,0,79,0,42,255,238,0,79,0,43,255,238,0,79,0,44,255,238,0,79,0,45,255,238,0,79,0,46,255,241,0,79,0,47,255,238,0,79,0,48,255,243,0,79,0,49,255,238,0,79,0,50,255,243,0,79,0,51,255,238,0,79,0,52,255,241,0,79,0,53,255,162,0,79,0,54,255,231,0,79,0,55,255,198,0,79,0,56,255,214,0,79,0,57,255,249,0,79,0,58,255,163,0,79,0,59,255,245,0,79,0,61,255,214,0,79,0,62,255,216,0,79,0,71,255,251,0,79,0,85,255,248,0,79,0,87,255,243,0,79,0,88,255,248,0,79,0,90,255,242,0,79,0,94,255,225,0,79,0,127,255,250,0,79,0,128,255,250,0,79,0,129,255,250,0,79,0,130,255,250,0,79,0,131,255,250,0,79,0,132,255,250,0,79,0,134,255,243,0,79,0,135,255,238,0,79,0,136,255,238,0,79,0,137,255,238,0,79,0,138,255,238,0,79,0,139,255,238,0,79,0,140,255,238,0,79,0,141,255,238,0,79,0,142,255,238,0,79,0,143,255,238,0,79,0,144,255,238,0,79,0,145,255,243,0,79,0,146,255,243,0,79,0,147,255,243,0,79,0,148,255,243,0,79,0,149,255,243,0,79,0,151,255,243,0,79,0,152,255,231,0,79,0,153,255,231,0,79,0,154,255,231,0,79,0,155,255,231,0,79,0,156,255,163,0,79,0,157,255,238,0,79,0,158,255,248,0,79,0,188,255,242,0,79,0,190,255,242,0,79,0,194,255,243,0,79,0,196,255,241,0,79,0,198,255,163,0,79,0,199,255,245,0,79,0,209,255,187,0,79,0,210,255,184,0,79,0,212,255,187,0,79,0,213,255,184,0,79,0,240,255,235,0,80,0,3,255,236,0,80,0,7,255,246,0,80,0,8,255,236,0,80,0,10,255,224,0,80,0,11,255,234,0,80,0,18,255,230,0,80,0,19,255,229,0,80,0,24,255,223,0,80,0,32,255,222,0,80,0,34,255,240,0,80,0,35,255,237,0,80,0,36,255,246,0,80,0,37,255,237,0,80,0,38,255,237,0,80,0,39,255,237,0,80,0,40,255,246,0,80,0,41,255,237,0,80,0,42,255,237,0,80,0,43,255,237,0,80,0,44,255,237,0,80,0,45,255,237,0,80,0,46,255,239,0,80,0,47,255,237,0,80,0,48,255,246,0,80,0,49,255,237,0,80,0,50,255,246,0,80,0,51,255,237,0,80,0,52,255,238,0,80,0,53,255,173,0,80,0,54,255,238,0,80,0,55,255,192,0,80,0,56,255,212,0,80,0,57,255,218,0,80,0,58,255,167,0,80,0,59,255,227,0,80,0,61,255,214,0,80,0,62,255,213,0,80,0,71,255,251,0,80,0,85,255,249,0,80,0,87,255,247,0,80,0,88,255,251,0,80,0,89,255,237,0,80,0,90,255,245,0,80,0,91,255,246,0,80,0,94,255,222,0,80,0,122,255,247,0,80,0,127,255,240,0,80,0,128,255,240,0,80,0,129,255,240,0,80,0,130,255,240,0,80,0,131,255,240,0,80,0,132,255,240,0,80,0,134,255,246,0,80,0,135,255,237,0,80,0,136,255,237,0,80,0,137,255,237,0,80,0,138,255,237,0,80,0,139,255,237,0,80,0,140,255,237,0,80,0,141,255,237,0,80,0,142,255,237,0,80,0,143,255,237,0,80,0,144,255,237,0,80,0,145,255,246,0,80,0,146,255,246,0,80,0,147,255,246,0,80,0,148,255,246,0,80,0,149,255,246,0,80,0,151,255,246,0,80,0,152,255,238,0,80,0,153,255,238,0,80,0,154,255,238,0,80,0,155,255,238,0,80,0,156,255,167,0,80,0,157,255,237,0,80,0,158,255,248,0,80,0,188,255,245,0,80,0,190,255,245,0,80,0,194,255,246,0,80,0,196,255,238,0,80,0,198,255,167,0,80,0,199,255,227,0,80,0,200,255,246,0,80,0,209,255,182,0,80,0,210,255,179,0,80,0,212,255,182,0,80,0,213,255,179,0,80,0,221,255,247,0,80,0,240,255,236,0,81,0,3,255,236,0,81,0,7,255,246,0,81,0,8,255,236,0,81,0,10,255,224,0,81,0,11,255,234,0,81,0,18,255,230,0,81,0,19,255,229,0,81,0,24,255,223,0,81,0,32,255,222,0,81,0,34,255,240,0,81,0,35,255,237,0,81,0,36,255,246,0,81,0,37,255,237,0,81,0,38,255,237,0,81,0,39,255,237,0,81,0,40,255,246,0,81,0,41,255,237,0,81,0,42,255,237,0,81,0,43,255,237,0,81,0,44,255,237,0,81,0,45,255,237,0,81,0,46,255,239,0,81,0,47,255,237,0,81,0,48,255,246,0,81,0,49,255,237,0,81,0,50,255,246,0,81,0,51,255,237,0,81,0,52,255,238,0,81,0,53,255,173,0,81,0,54,255,238,0,81,0,55,255,192,0,81,0,56,255,212,0,81,0,57,255,218,0,81,0,58,255,167,0,81,0,59,255,227,0,81,0,61,255,214,0,81,0,62,255,213,0,81,0,71,255,251,0,81,0,85,255,249,0,81,0,87,255,247,0,81,0,88,255,251,0,81,0,89,255,237,0,81,0,90,255,245,0,81,0,91,255,246,0,81,0,94,255,222,0,81,0,122,255,247,0,81,0,127,255,240,0,81,0,128,255,240,0,81,0,129,255,240,0,81,0,130,255,240,0,81,0,131,255,240,0,81,0,132,255,240,0,81,0,134,255,246,0,81,0,135,255,237,0,81,0,136,255,237,0,81,0,137,255,237,0,81,0,138,255,237,0,81,0,139,255,237,0,81,0,140,255,237,0,81,0,141,255,237,0,81,0,142,255,237,0,81,0,143,255,237,0,81,0,144,255,237,0,81,0,145,255,246,0,81,0,146,255,246,0,81,0,147,255,246,0,81,0,148,255,246,0,81,0,149,255,246,0,81,0,151,255,246,0,81,0,152,255,238,0,81,0,153,255,238,0,81,0,154,255,238,0,81,0,155,255,238,0,81,0,156,255,167,0,81,0,157,255,237,0,81,0,158,255,248,0,81,0,188,255,245,0,81,0,190,255,245,0,81,0,194,255,246,0,81,0,196,255,238,0,81,0,198,255,167,0,81,0,199,255,227,0,81,0,200,255,246,0,81,0,209,255,182,0,81,0,210,255,179,0,81,0,212,255,182,0,81,0,213,255,179,0,81,0,221,255,247,0,81,0,240,255,236,0,82,0,7,255,244,0,82,0,10,255,233,0,82,0,11,255,244,0,82,0,24,255,232,0,82,0,32,255,223,0,82,0,34,255,248,0,82,0,35,255,242,0,82,0,36,255,244,0,82,0,37,255,242,0,82,0,38,255,242,0,82,0,39,255,242,0,82,0,40,255,244,0,82,0,41,255,242,0,82,0,42,255,242,0,82,0,43,255,242,0,82,0,44,255,242,0,82,0,45,255,242,0,82,0,46,255,241,0,82,0,47,255,242,0,82,0,48,255,244,0,82,0,49,255,242,0,82,0,50,255,244,0,82,0,51,255,242,0,82,0,52,255,243,0,82,0,53,255,164,0,82,0,54,255,235,0,82,0,55,255,216,0,82,0,56,255,218,0,82,0,57,255,246,0,82,0,58,255,183,0,82,0,59,255,242,0,82,0,61,255,228,0,82,0,62,255,215,0,82,0,94,255,226,0,82,0,127,255,248,0,82,0,128,255,248,0,82,0,129,255,248,0,82,0,130,255,248,0,82,0,131,255,248,0,82,0,132,255,248,0,82,0,134,255,244,0,82,0,135,255,242,0,82,0,136,255,242,0,82,0,137,255,242,0,82,0,138,255,242,0,82,0,139,255,242,0,82,0,140,255,242,0,82,0,141,255,242,0,82,0,142,255,242,0,82,0,143,255,242,0,82,0,144,255,242,0,82,0,145,255,244,0,82,0,146,255,244,0,82,0,147,255,244,0,82,0,148,255,244,0,82,0,149,255,244,0,82,0,151,255,244,0,82,0,152,255,235,0,82,0,153,255,235,0,82,0,154,255,235,0,82,0,155,255,235,0,82,0,156,255,183,0,82,0,157,255,242,0,82,0,194,255,244,0,82,0,196,255,243,0,82,0,198,255,183,0,82,0,199,255,242,0,82,0,209,255,211,0,82,0,210,255,209,0,82,0,212,255,211,0,82,0,213,255,209,0,82,0,240,255,239,0,83,0,7,255,237,0,83,0,10,255,232,0,83,0,13,255,227,0,83,0,14,255,234,0,83,0,15,255,227,0,83,0,16,255,225,0,83,0,20,255,231,0,83,0,21,255,238,0,83,0,24,255,200,0,83,0,32,255,202,0,83,0,33,255,232,0,83,0,34,255,211,0,83,0,35,255,243,0,83,0,37,255,243,0,83,0,38,255,243,0,83,0,39,255,243,0,83,0,41,255,243,0,83,0,42,255,243,0,83,0,43,255,243,0,83,0,44,255,243,0,83,0,45,255,243,0,83,0,46,255,230,0,83,0,47,255,243,0,83,0,49,255,243,0,83,0,51,255,243,0,83,0,53,255,163,0,83,0,54,255,247,0,83,0,55,255,243,0,83,0,56,255,247,0,83,0,57,255,214,0,83,0,58,255,225,0,83,0,59,255,227,0,83,0,62,255,217,0,83,0,66,255,249,0,83,0,68,255,243,0,83,0,69,255,243,0,83,0,70,255,243,0,83,0,72,255,250,0,83,0,80,255,243,0,83,0,82,255,243,0,83,0,94,255,228,0,83,0,107,255,237,0,83,0,127,255,211,0,83,0,128,255,211,0,83,0,129,255,211,0,83,0,130,255,211,0,83,0,131,255,211,0,83,0,132,255,211,0,83,0,135,255,243,0,83,0,136,255,243,0,83,0,137,255,243,0,83,0,138,255,243,0,83,0,139,255,243,0,83,0,140,255,243,0,83,0,141,255,243,0,83,0,142,255,243,0,83,0,143,255,243,0,83,0,144,255,243,0,83,0,152,255,247,0,83,0,153,255,247,0,83,0,154,255,247,0,83,0,155,255,247,0,83,0,156,255,225,0,83,0,157,255,243,0,83,0,159,255,249,0,83,0,160,255,249,0,83,0,161,255,249,0,83,0,162,255,249,0,83,0,163,255,249,0,83,0,164,255,249,0,83,0,165,255,249,0,83,0,166,255,243,0,83,0,167,255,243,0,83,0,168,255,243,0,83,0,169,255,243,0,83,0,170,255,243,0,83,0,175,255,218,0,83,0,177,255,243,0,83,0,178,255,243,0,83,0,179,255,243,0,83,0,180,255,243,0,83,0,181,255,243,0,83,0,183,255,243,0,83,0,195,255,243,0,83,0,198,255,225,0,83,0,199,255,227,0,83,0,207,255,234,0,83,0,208,255,234,0,83,0,209,255,233,0,83,0,210,255,230,0,83,0,211,255,227,0,83,0,212,255,233,0,83,0,213,255,230,0,83,0,214,255,227,0,83,0,218,255,227,0,83,0,220,255,237,0,84,0,10,255,231,0,84,0,11,255,241,0,84,0,24,255,234,0,84,0,32,255,224,0,84,0,35,255,241,0,84,0,36,255,244,0,84,0,37,255,241,0,84,0,38,255,241,0,84,0,39,255,241,0,84,0,40,255,244,0,84,0,41,255,241,0,84,0,42,255,241,0,84,0,43,255,241,0,84,0,44,255,241,0,84,0,45,255,241,0,84,0,46,255,245,0,84,0,47,255,241,0,84,0,48,255,244,0,84,0,49,255,241,0,84,0,50,255,244,0,84,0,51,255,241,0,84,0,52,255,248,0,84,0,53,255,202,0,84,0,54,255,238,0,84,0,55,255,216,0,84,0,56,255,224,0,84,0,57,255,244,0,84,0,58,255,209,0,84,0,59,255,245,0,84,0,61,255,225,0,84,0,62,255,220,0,84,0,94,255,229,0,84,0,134,255,244,0,84,0,135,255,241,0,84,0,136,255,241,0,84,0,137,255,241,0,84,0,138,255,241,0,84,0,139,255,241,0,84,0,140,255,241,0,84,0,141,255,241,0,84,0,142,255,241,0,84,0,143,255,241,0,84,0,144,255,241,0,84,0,145,255,244,0,84,0,146,255,244,0,84,0,147,255,244,0,84,0,148,255,244,0,84,0,149,255,244,0,84,0,151,255,244,0,84,0,152,255,238,0,84,0,153,255,238,0,84,0,154,255,238,0,84,0,155,255,238,0,84,0,156,255,209,0,84,0,157,255,241,0,84,0,194,255,244,0,84,0,196,255,248,0,84,0,198,255,209,0,84,0,199,255,245,0,84,0,209,255,203,0,84,0,210,255,200,0,84,0,212,255,203,0,84,0,213,255,200,0,84,0,240,255,235,0,85,0,7,255,246,0,85,0,21,255,234,0,85,0,24,255,246,0,85,0,32,255,229,0,85,0,35,255,248,0,85,0,37,255,248,0,85,0,38,255,248,0,85,0,39,255,248,0,85,0,41,255,248,0,85,0,42,255,248,0,85,0,43,255,248,0,85,0,44,255,248,0,85,0,45,255,248,0,85,0,46,255,248,0,85,0,47,255,248,0,85,0,49,255,248,0,85,0,51,255,248,0,85,0,53,255,209,0,85,0,54,255,246,0,85,0,55,255,237,0,85,0,56,255,243,0,85,0,58,255,211,0,85,0,62,255,230,0,85,0,68,255,252,0,85,0,69,255,252,0,85,0,70,255,252,0,85,0,80,255,252,0,85,0,82,255,252,0,85,0,94,255,242,0,85,0,107,255,244,0,85,0,135,255,248,0,85,0,136,255,248,0,85,0,137,255,248,0,85,0,138,255,248,0,85,0,139,255,248,0,85,0,140,255,248,0,85,0,141,255,248,0,85,0,142,255,248,0,85,0,143,255,248,0,85,0,144,255,248,0,85,0,152,255,246,0,85,0,153,255,246,0,85,0,154,255,246,0,85,0,155,255,246,0,85,0,156,255,211,0,85,0,157,255,248,0,85,0,166,255,252,0,85,0,167,255,252,0,85,0,168,255,252,0,85,0,169,255,252,0,85,0,170,255,252,0,85,0,175,255,251,0,85,0,177,255,252,0,85,0,178,255,252,0,85,0,179,255,252,0,85,0,180,255,252,0,85,0,181,255,252,0,85,0,183,255,252,0,85,0,195,255,252,0,85,0,198,255,211,0,85,0,209,255,234,0,85,0,210,255,233,0,85,0,212,255,234,0,85,0,213,255,233,0,85,0,220,255,244,0,86,0,7,255,244,0,86,0,10,255,233,0,86,0,11,255,244,0,86,0,24,255,232,0,86,0,32,255,223,0,86,0,34,255,248,0,86,0,35,255,242,0,86,0,36,255,244,0,86,0,37,255,242,0,86,0,38,255,242,0,86,0,39,255,242,0,86,0,40,255,244,0,86,0,41,255,242,0,86,0,42,255,242,0,86,0,43,255,242,0,86,0,44,255,242,0,86,0,45,255,242,0,86,0,46,255,241,0,86,0,47,255,242,0,86,0,48,255,244,0,86,0,49,255,242,0,86,0,50,255,244,0,86,0,51,255,242,0,86,0,52,255,243,0,86,0,53,255,164,0,86,0,54,255,235,0,86,0,55,255,216,0,86,0,56,255,218,0,86,0,57,255,246,0,86,0,58,255,183,0,86,0,59,255,242,0,86,0,61,255,228,0,86,0,62,255,215,0,86,0,94,255,226,0,86,0,127,255,248,0,86,0,128,255,248,0,86,0,129,255,248,0,86,0,130,255,248,0,86,0,131,255,248,0,86,0,132,255,248,0,86,0,134,255,244,0,86,0,135,255,242,0,86,0,136,255,242,0,86,0,137,255,242,0,86,0,138,255,242,0,86,0,139,255,242,0,86,0,140,255,242,0,86,0,141,255,242,0,86,0,142,255,242,0,86,0,143,255,242,0,86,0,144,255,242,0,86,0,145,255,244,0,86,0,146,255,244,0,86,0,147,255,244,0,86,0,148,255,244,0,86,0,149,255,244,0,86,0,151,255,244,0,86,0,152,255,235,0,86,0,153,255,235,0,86,0,154,255,235,0,86,0,155,255,235,0,86,0,156,255,183,0,86,0,157,255,242,0,86,0,194,255,244,0,86,0,196,255,243,0,86,0,198,255,183,0,86,0,199,255,242,0,86,0,209,255,211,0,86,0,210,255,209,0,86,0,212,255,211,0,86,0,213,255,209,0,86,0,240,255,239,0,87,0,7,255,238,0,87,0,10,255,231,0,87,0,13,255,227,0,87,0,15,255,227,0,87,0,16,255,223,0,87,0,20,255,231,0,87,0,24,255,200,0,87,0,32,255,206,0,87,0,33,255,240,0,87,0,34,255,216,0,87,0,35,255,242,0,87,0,37,255,242,0,87,0,38,255,242,0,87,0,39,255,242,0,87,0,41,255,242,0,87,0,42,255,242,0,87,0,43,255,242,0,87,0,44,255,242,0,87,0,45,255,242,0,87,0,46,255,229,0,87,0,47,255,242,0,87,0,49,255,242,0,87,0,51,255,242,0,87,0,53,255,170,0,87,0,54,255,245,0,87,0,55,255,237,0,87,0,56,255,242,0,87,0,57,255,208,0,87,0,58,255,210,0,87,0,59,255,224,0,87,0,62,255,214,0,87,0,66,255,250,0,87,0,68,255,247,0,87,0,69,255,247,0,87,0,70,255,247,0,87,0,72,255,250,0,87,0,80,255,247,0,87,0,82,255,247,0,87,0,84,255,252,0,87,0,94,255,227,0,87,0,127,255,216,0,87,0,128,255,216,0,87,0,129,255,216,0,87,0,130,255,216,0,87,0,131,255,216,0,87,0,132,255,216,0,87,0,135,255,242,0,87,0,136,255,242,0,87,0,137,255,242,0,87,0,138,255,242,0,87,0,139,255,242,0,87,0,140,255,242,0,87,0,141,255,242,0,87,0,142,255,242,0,87,0,143,255,242,0,87,0,144,255,242,0,87,0,152,255,245,0,87,0,153,255,245,0,87,0,154,255,245,0,87,0,155,255,245,0,87,0,156,255,210,0,87,0,157,255,242,0,87,0,159,255,250,0,87,0,160,255,250,0,87,0,161,255,250,0,87,0,162,255,250,0,87,0,163,255,250,0,87,0,164,255,250,0,87,0,165,255,250,0,87,0,166,255,247,0,87,0,167,255,247,0,87,0,168,255,247,0,87,0,169,255,247,0,87,0,170,255,247,0,87,0,175,255,238,0,87,0,177,255,247,0,87,0,178,255,247,0,87,0,179,255,247,0,87,0,180,255,247,0,87,0,181,255,247,0,87,0,183,255,247,0,87,0,195,255,247,0,87,0,197,255,252,0,87,0,198,255,210,0,87,0,199,255,224,0,87,0,209,255,226,0,87,0,210,255,224,0,87,0,211,255,227,0,87,0,212,255,226,0,87,0,213,255,224,0,87,0,214,255,227,0,87,0,218,255,227,0,88,0,7,255,240,0,88,0,10,255,232,0,88,0,13,255,235,0,88,0,15,255,236,0,88,0,16,255,231,0,88,0,20,255,240,0,88,0,24,255,207,0,88,0,32,255,211,0,88,0,33,255,247,0,88,0,34,255,223,0,88,0,35,255,243,0,88,0,37,255,243,0,88,0,38,255,243,0,88,0,39,255,243,0,88,0,41,255,243,0,88,0,42,255,243,0,88,0,43,255,243,0,88,0,44,255,243,0,88,0,45,255,243,0,88,0,46,255,232,0,88,0,47,255,243,0,88,0,49,255,243,0,88,0,51,255,243,0,88,0,53,255,178,0,88,0,54,255,246,0,88,0,55,255,236,0,88,0,56,255,242,0,88,0,57,255,213,0,88,0,58,255,211,0,88,0,59,255,228,0,88,0,62,255,218,0,88,0,66,255,252,0,88,0,68,255,251,0,88,0,69,255,251,0,88,0,70,255,251,0,88,0,80,255,251,0,88,0,82,255,251,0,88,0,94,255,229,0,88,0,127,255,223,0,88,0,128,255,223,0,88,0,129,255,223,0,88,0,130,255,223,0,88,0,131,255,223,0,88,0,132,255,223,0,88,0,135,255,243,0,88,0,136,255,243,0,88,0,137,255,243,0,88,0,138,255,243,0,88,0,139,255,243,0,88,0,140,255,243,0,88,0,141,255,243,0,88,0,142,255,243,0,88,0,143,255,243,0,88,0,144,255,243,0,88,0,152,255,246,0,88,0,153,255,246,0,88,0,154,255,246,0,88,0,155,255,246,0,88,0,156,255,211,0,88,0,157,255,243,0,88,0,159,255,252,0,88,0,160,255,252,0,88,0,161,255,252,0,88,0,162,255,252,0,88,0,163,255,252,0,88,0,164,255,252,0,88,0,165,255,252,0,88,0,166,255,251,0,88,0,167,255,251,0,88,0,168,255,251,0,88,0,169,255,251,0,88,0,170,255,251,0,88,0,175,255,246,0,88,0,177,255,251,0,88,0,178,255,251,0,88,0,179,255,251,0,88,0,180,255,251,0,88,0,181,255,251,0,88,0,183,255,251,0,88,0,195,255,251,0,88,0,198,255,211,0,88,0,199,255,228,0,88,0,209,255,227,0,88,0,210,255,225,0,88,0,211,255,235,0,88,0,212,255,227,0,88,0,213,255,225,0,88,0,214,255,235,0,88,0,218,255,236,0,89,0,7,255,238,0,89,0,14,255,247,0,89,0,32,255,227,0,89,0,35,255,247,0,89,0,36,255,240,0,89,0,37,255,247,0,89,0,38,255,247,0,89,0,39,255,247,0,89,0,40,255,240,0,89,0,41,255,247,0,89,0,42,255,247,0,89,0,43,255,247,0,89,0,44,255,247,0,89,0,45,255,247,0,89,0,46,255,250,0,89,0,47,255,247,0,89,0,48,255,240,0,89,0,49,255,247,0,89,0,50,255,240,0,89,0,51,255,247,0,89,0,52,255,248,0,89,0,53,255,167,0,89,0,54,255,244,0,89,0,55,255,236,0,89,0,56,255,242,0,89,0,58,255,208,0,89,0,61,255,247,0,89,0,62,255,230,0,89,0,66,255,252,0,89,0,68,255,238,0,89,0,69,255,238,0,89,0,70,255,238,0,89,0,72,255,247,0,89,0,80,255,238,0,89,0,82,255,238,0,89,0,94,255,237,0,89,0,107,255,236,0,89,0,134,255,240,0,89,0,135,255,247,0,89,0,136,255,247,0,89,0,137,255,247,0,89,0,138,255,247,0,89,0,139,255,247,0,89,0,140,255,247,0,89,0,141,255,247,0,89,0,142,255,247,0,89,0,143,255,247,0,89,0,144,255,247,0,89,0,145,255,240,0,89,0,146,255,240,0,89,0,147,255,240,0,89,0,148,255,240,0,89,0,149,255,240,0,89,0,151,255,240,0,89,0,152,255,244,0,89,0,153,255,244,0,89,0,154,255,244,0,89,0,155,255,244,0,89,0,156,255,208,0,89,0,157,255,247,0,89,0,159,255,252,0,89,0,160,255,252,0,89,0,161,255,252,0,89,0,162,255,252,0,89,0,163,255,252,0,89,0,164,255,252,0,89,0,165,255,252,0,89,0,166,255,238,0,89,0,167,255,238,0,89,0,168,255,238,0,89,0,169,255,238,0,89,0,170,255,238,0,89,0,175,255,240,0,89,0,177,255,238,0,89,0,178,255,238,0,89,0,179,255,238,0,89,0,180,255,238,0,89,0,181,255,238,0,89,0,183,255,238,0,89,0,194,255,240,0,89,0,195,255,238,0,89,0,196,255,248,0,89,0,198,255,208,0,89,0,207,255,247,0,89,0,208,255,247,0,89,0,209,255,224,0,89,0,210,255,222,0,89,0,212,255,224,0,89,0,213,255,222,0,89,0,220,255,236,0,89,0,240,255,248,0,90,0,7,255,238,0,90,0,10,255,231,0,90,0,13,255,225,0,90,0,15,255,225,0,90,0,16,255,220,0,90,0,19,255,227,0,90,0,20,255,230,0,90,0,24,255,198,0,90,0,32,255,205,0,90,0,33,255,238,0,90,0,34,255,214,0,90,0,35,255,243,0,90,0,37,255,243,0,90,0,38,255,243,0,90,0,39,255,243,0,90,0,41,255,243,0,90,0,42,255,243,0,90,0,43,255,243,0,90,0,44,255,243,0,90,0,45,255,243,0,90,0,46,255,229,0,90,0,47,255,243,0,90,0,49,255,243,0,90,0,51,255,243,0,90,0,53,255,168,0,90,0,54,255,245,0,90,0,55,255,238,0,90,0,56,255,242,0,90,0,57,255,208,0,90,0,58,255,211,0,90,0,59,255,225,0,90,0,62,255,214,0,90,0,66,255,250,0,90,0,68,255,246,0,90,0,69,255,246,0,90,0,70,255,246,0,90,0,72,255,250,0,90,0,80,255,246,0,90,0,82,255,246,0,90,0,84,255,252,0,90,0,94,255,227,0,90,0,127,255,214,0,90,0,128,255,214,0,90,0,129,255,214,0,90,0,130,255,214,0,90,0,131,255,214,0,90,0,132,255,214,0,90,0,135,255,243,0,90,0,136,255,243,0,90,0,137,255,243,0,90,0,138,255,243,0,90,0,139,255,243,0,90,0,140,255,243,0,90,0,141,255,243,0,90,0,142,255,243,0,90,0,143,255,243,0,90,0,144,255,243,0,90,0,152,255,245,0,90,0,153,255,245,0,90,0,154,255,245,0,90,0,155,255,245,0,90,0,156,255,211,0,90,0,157,255,243,0,90,0,159,255,250,0,90,0,160,255,250,0,90,0,161,255,250,0,90,0,162,255,250,0,90,0,163,255,250,0,90,0,164,255,250,0,90,0,165,255,250,0,90,0,166,255,246,0,90,0,167,255,246,0,90,0,168,255,246,0,90,0,169,255,246,0,90,0,170,255,246,0,90,0,175,255,236,0,90,0,177,255,246,0,90,0,178,255,246,0,90,0,179,255,246,0,90,0,180,255,246,0,90,0,181,255,246,0,90,0,183,255,246,0,90,0,195,255,246,0,90,0,197,255,252,0,90,0,198,255,211,0,90,0,199,255,225,0,90,0,209,255,227,0,90,0,210,255,225,0,90,0,211,255,225,0,90,0,212,255,227,0,90,0,213,255,225,0,90,0,214,255,225,0,90,0,218,255,225,0,91,0,7,255,245,0,91,0,10,255,246,0,91,0,14,255,240,0,91,0,21,255,225,0,91,0,24,255,244,0,91,0,32,255,221,0,91,0,35,255,242,0,91,0,36,255,244,0,91,0,37,255,242,0,91,0,38,255,242,0,91,0,39,255,242,0,91,0,40,255,244,0,91,0,41,255,242,0,91,0,42,255,242,0,91,0,43,255,242,0,91,0,44,255,242,0,91,0,45,255,242,0,91,0,46,255,245,0,91,0,47,255,242,0,91,0,48,255,244,0,91,0,49,255,242,0,91,0,50,255,244,0,91,0,51,255,242,0,91,0,53,255,203,0,91,0,54,255,239,0,91,0,55,255,240,0,91,0,56,255,243,0,91,0,58,255,227,0,91,0,61,255,242,0,91,0,62,255,222,0,91,0,68,255,245,0,91,0,69,255,245,0,91,0,70,255,245,0,91,0,72,255,251,0,91,0,80,255,245,0,91,0,82,255,245,0,91,0,94,255,232,0,91,0,107,255,232,0,91,0,134,255,244,0,91,0,135,255,242,0,91,0,136,255,242,0,91,0,137,255,242,0,91,0,138,255,242,0,91,0,139,255,242,0,91,0,140,255,242,0,91,0,141,255,242,0,91,0,142,255,242,0,91,0,143,255,242,0,91,0,144,255,242,0,91,0,145,255,244,0,91,0,146,255,244,0,91,0,147,255,244,0,91,0,148,255,244,0,91,0,149,255,244,0,91,0,151,255,244,0,91,0,152,255,239,0,91,0,153,255,239,0,91,0,154,255,239,0,91,0,155,255,239,0,91,0,156,255,227,0,91,0,157,255,242,0,91,0,166,255,245,0,91,0,167,255,245,0,91,0,168,255,245,0,91,0,169,255,245,0,91,0,170,255,245,0,91,0,175,255,247,0,91,0,177,255,245,0,91,0,178,255,245,0,91,0,179,255,245,0,91,0,180,255,245,0,91,0,181,255,245,0,91,0,183,255,245,0,91,0,194,255,244,0,91,0,195,255,245,0,91,0,198,255,227,0,91,0,207,255,240,0,91,0,208,255,240,0,91,0,209,255,219,0,91,0,210,255,216,0,91,0,212,255,219,0,91,0,213,255,216,0,91,0,220,255,232,0,91,0,240,255,242,0,92,0,17,255,238,0,92,0,21,255,238,0,92,0,23,255,235,0,92,0,34,255,244,0,92,0,36,255,231,0,92,0,40,255,231,0,92,0,43,0,47,0,92,0,46,255,247,0,92,0,48,255,231,0,92,0,50,255,231,0,92,0,53,0,21,0,92,0,55,0,29,0,92,0,56,0,25,0,92,0,57,0,28,0,92,0,58,0,34,0,92,0,66,255,229,0,92,0,68,255,222,0,92,0,69,255,222,0,92,0,70,255,222,0,92,0,78,255,227,0,92,0,79,255,227,0,92,0,80,255,222,0,92,0,81,255,227,0,92,0,82,255,222,0,92,0,83,255,227,0,92,0,84,255,229,0,92,0,85,255,231,0,92,0,86,255,225,0,92,0,87,255,227,0,92,0,88,255,228,0,92,0,89,255,238,0,92,0,90,255,227,0,92,0,91,255,232,0,92,0,127,255,244,0,92,0,128,255,244,0,92,0,129,255,244,0,92,0,130,255,244,0,92,0,131,255,244,0,92,0,132,255,244,0,92,0,134,255,231,0,92,0,145,255,231,0,92,0,146,255,231,0,92,0,147,255,231,0,92,0,148,255,231,0,92,0,149,255,231,0,92,0,151,255,231,0,92,0,156,0,34,0,92,0,158,255,247,0,92,0,159,255,229,0,92,0,160,255,229,0,92,0,161,255,229,0,92,0,162,255,229,0,92,0,163,255,229,0,92,0,164,255,229,0,92,0,165,255,229,0,92,0,166,255,222,0,92,0,167,255,222,0,92,0,168,255,222,0,92,0,169,255,222,0,92,0,170,255,222,0,92,0,171,0,12,0,92,0,173,0,33,0,92,0,174,0,44,0,92,0,175,255,234,0,92,0,176,255,227,0,92,0,177,255,222,0,92,0,178,255,222,0,92,0,179,255,222,0,92,0,180,255,222,0,92,0,181,255,222,0,92,0,183,255,222,0,92,0,184,255,225,0,92,0,185,255,225,0,92,0,186,255,225,0,92,0,187,255,225,0,92,0,188,255,227,0,92,0,189,255,249,0,92,0,190,255,227,0,92,0,194,255,231,0,92,0,195,255,222,0,92,0,197,255,229,0,92,0,198,0,34,0,92,0,200,255,232,0,97,0,53,255,200,0,97,0,55,255,236,0,97,0,56,255,244,0,97,0,58,255,224,0,97,0,156,255,224,0,97,0,198,255,224,0,107,0,53,255,197,0,107,0,55,255,245,0,107,0,58,255,226,0,107,0,68,255,247,0,107,0,69,255,247,0,107,0,70,255,247,0,107,0,80,255,247,0,107,0,82,255,247,0,107,0,156,255,226,0,107,0,166,255,247,0,107,0,167,255,247,0,107,0,168,255,247,0,107,0,169,255,247,0,107,0,170,255,247,0,107,0,177,255,247,0,107,0,178,255,247,0,107,0,179,255,247,0,107,0,180,255,247,0,107,0,181,255,247,0,107,0,183,255,247,0,107,0,195,255,247,0,107,0,198,255,226,0,107,0,210,255,229,0,107,0,213,255,229,0,110,0,34,255,237,0,110,0,46,255,247,0,110,0,53,255,230,0,110,0,55,255,243,0,110,0,56,255,248,0,110,0,57,255,236,0,110,0,58,255,229,0,110,0,59,255,231,0,110,0,127,255,237,0,110,0,128,255,237,0,110,0,129,255,237,0,110,0,130,255,237,0,110,0,131,255,237,0,110,0,132,255,237,0,110,0,133,255,236,0,110,0,156,255,229,0,110,0,198,255,229,0,110,0,199,255,231,0,111,0,21,255,229,0,111,0,23,255,239,0,122,0,3,255,241,0,122,0,8,255,241,0,122,0,34,255,247,0,122,0,52,255,234,0,122,0,53,255,195,0,122,0,55,255,220,0,122,0,56,255,230,0,122,0,57,255,224,0,122,0,58,255,198,0,122,0,59,255,223,0,122,0,85,255,247,0,122,0,89,255,236,0,122,0,90,255,248,0,122,0,91,255,233,0,122,0,127,255,247,0,122,0,128,255,247,0,122,0,129,255,247,0,122,0,130,255,247,0,122,0,131,255,247,0,122,0,132,255,247,0,122,0,133,255,243,0,122,0,156,255,198,0,122,0,158,255,248,0,122,0,188,255,248,0,122,0,190,255,248,0,122,0,196,255,234,0,122,0,198,255,198,0,122,0,199,255,223,0,122,0,200,255,233,0,122,0,210,255,204,0,122,0,213,255,204,0,126,0,34,255,233,0,126,0,35,255,247,0,126,0,37,255,247,0,126,0,38,255,247,0,126,0,39,255,247,0,126,0,41,255,247,0,126,0,42,255,247,0,126,0,43,0,19,0,126,0,44,255,247,0,126,0,45,255,247,0,126,0,46,255,238,0,126,0,47,255,247,0,126,0,49,255,247,0,126,0,51,255,247,0,126,0,53,255,192,0,126,0,54,255,245,0,126,0,55,255,233,0,126,0,56,255,241,0,126,0,57,255,231,0,126,0,58,255,219,0,126,0,59,255,220,0,126,0,66,255,241,0,126,0,67,255,247,0,126,0,68,255,243,0,126,0,69,255,243,0,126,0,70,255,243,0,126,0,72,255,243,0,126,0,73,255,247,0,126,0,74,255,242,0,126,0,75,0,20,0,126,0,76,255,247,0,126,0,77,255,247,0,126,0,78,255,241,0,126,0,79,255,241,0,126,0,80,255,243,0,126,0,81,255,241,0,126,0,82,255,243,0,126,0,83,255,241,0,126,0,84,255,241,0,126,0,86,255,243,0,126,0,89,255,248,0,126,0,91,255,241,0,126,0,127,255,233,0,126,0,128,255,233,0,126,0,129,255,233,0,126,0,130,255,233,0,126,0,131,255,233,0,126,0,132,255,233,0,126,0,133,255,235,0,126,0,135,255,247,0,126,0,136,255,247,0,126,0,137,255,247,0,126,0,138,255,247,0,126,0,139,255,247,0,126,0,140,255,247,0,126,0,141,255,247,0,126,0,142,255,247,0,126,0,143,255,247,0,126,0,144,255,247,0,126,0,152,255,245,0,126,0,153,255,245,0,126,0,154,255,245,0,126,0,155,255,245,0,126,0,156,255,219,0,126,0,157,255,247,0,126,0,159,255,241,0,126,0,160,255,241,0,126,0,161,255,241,0,126,0,162,255,241,0,126,0,163,255,241,0,126,0,164,255,241,0,126,0,165,255,241,0,126,0,166,255,243,0,126,0,167,255,243,0,126,0,168,255,243,0,126,0,169,255,243,0,126,0,170,255,243,0,126,0,171,255,242,0,126,0,172,255,242,0,126,0,173,255,242,0,126,0,174,255,242,0,126,0,175,255,240,0,126,0,176,255,241,0,126,0,177,255,243,0,126,0,178,255,243,0,126,0,179,255,243,0,126,0,180,255,243,0,126,0,181,255,243,0,126,0,183,255,243,0,126,0,184,255,243,0,126,0,185,255,243,0,126,0,186,255,243,0,126,0,187,255,243,0,126,0,189,255,241,0,126,0,193,255,242,0,126,0,195,255,243,0,126,0,197,255,241,0,126,0,198,255,219,0,126,0,199,255,220,0,126,0,200,255,241,0,127,0,3,255,213,0,127,0,8,255,213,0,127,0,11,255,212,0,127,0,18,255,239,0,127,0,26,255,242,0,127,0,32,255,239,0,127,0,36,255,245,0,127,0,40,255,245,0,127,0,48,255,245,0,127,0,50,255,245,0,127,0,53,255,202,0,127,0,54,255,240,0,127,0,55,255,207,0,127,0,56,255,219,0,127,0,58,255,192,0,127,0,61,255,208,0,127,0,68,255,245,0,127,0,69,255,245,0,127,0,70,255,245,0,127,0,71,255,241,0,127,0,72,255,248,0,127,0,77,255,249,0,127,0,80,255,245,0,127,0,82,255,245,0,127,0,85,255,229,0,127,0,86,255,244,0,127,0,87,255,221,0,127,0,88,255,228,0,127,0,90,255,217,0,127,0,94,255,246,0,127,0,107,255,247,0,127,0,110,255,241,0,127,0,134,255,245,0,127,0,145,255,245,0,127,0,146,255,245,0,127,0,147,255,245,0,127,0,148,255,245,0,127,0,149,255,245,0,127,0,151,255,245,0,127,0,152,255,240,0,127,0,153,255,240,0,127,0,154,255,240,0,127,0,155,255,240,0,127,0,156,255,192,0,127,0,158,255,242,0,127,0,166,255,245,0,127,0,167,255,245,0,127,0,168,255,245,0,127,0,169,255,245,0,127,0,170,255,245,0,127,0,175,255,250,0,127,0,177,255,245,0,127,0,178,255,245,0,127,0,179,255,245,0,127,0,180,255,245,0,127,0,181,255,245,0,127,0,183,255,245,0,127,0,184,255,244,0,127,0,185,255,244,0,127,0,186,255,244,0,127,0,187,255,244,0,127,0,188,255,217,0,127,0,190,255,217,0,127,0,194,255,245,0,127,0,195,255,245,0,127,0,198,255,192,0,127,0,209,255,205,0,127,0,210,255,204,0,127,0,212,255,205,0,127,0,213,255,204,0,127,0,220,255,247,0,127,0,240,255,212,0,128,0,3,255,213,0,128,0,8,255,213,0,128,0,11,255,212,0,128,0,18,255,239,0,128,0,26,255,242,0,128,0,32,255,239,0,128,0,36,255,245,0,128,0,40,255,245,0,128,0,48,255,245,0,128,0,50,255,245,0,128,0,53,255,202,0,128,0,54,255,240,0,128,0,55,255,207,0,128,0,56,255,219,0,128,0,58,255,192,0,128,0,61,255,208,0,128,0,68,255,245,0,128,0,69,255,245,0,128,0,70,255,245,0,128,0,71,255,241,0,128,0,72,255,248,0,128,0,77,255,249,0,128,0,80,255,245,0,128,0,82,255,245,0,128,0,85,255,229,0,128,0,86,255,244,0,128,0,87,255,221,0,128,0,88,255,228,0,128,0,90,255,217,0,128,0,94,255,246,0,128,0,107,255,247,0,128,0,110,255,241,0,128,0,134,255,245,0,128,0,145,255,245,0,128,0,146,255,245,0,128,0,147,255,245,0,128,0,148,255,245,0,128,0,149,255,245,0,128,0,151,255,245,0,128,0,152,255,240,0,128,0,153,255,240,0,128,0,154,255,240,0,128,0,155,255,240,0,128,0,156,255,192,0,128,0,158,255,242,0,128,0,166,255,245,0,128,0,167,255,245,0,128,0,168,255,245,0,128,0,169,255,245,0,128,0,170,255,245,0,128,0,175,255,250,0,128,0,177,255,245,0,128,0,178,255,245,0,128,0,179,255,245,0,128,0,180,255,245,0,128,0,181,255,245,0,128,0,183,255,245,0,128,0,184,255,244,0,128,0,185,255,244,0,128,0,186,255,244,0,128,0,187,255,244,0,128,0,188,255,217,0,128,0,190,255,217,0,128,0,194,255,245,0,128,0,195,255,245,0,128,0,198,255,192,0,128,0,209,255,205,0,128,0,210,255,204,0,128,0,212,255,205,0,128,0,213,255,204,0,128,0,220,255,247,0,128,0,240,255,212,0,129,0,3,255,213,0,129,0,8,255,213,0,129,0,11,255,212,0,129,0,18,255,239,0,129,0,26,255,242,0,129,0,32,255,239,0,129,0,36,255,245,0,129,0,40,255,245,0,129,0,48,255,245,0,129,0,50,255,245,0,129,0,53,255,202,0,129,0,54,255,240,0,129,0,55,255,207,0,129,0,56,255,219,0,129,0,58,255,192,0,129,0,61,255,208,0,129,0,68,255,245,0,129,0,69,255,245,0,129,0,70,255,245,0,129,0,71,255,241,0,129,0,72,255,248,0,129,0,77,255,249,0,129,0,80,255,245,0,129,0,82,255,245,0,129,0,85,255,229,0,129,0,86,255,244,0,129,0,87,255,221,0,129,0,88,255,228,0,129,0,90,255,217,0,129,0,94,255,246,0,129,0,107,255,247,0,129,0,110,255,241,0,129,0,134,255,245,0,129,0,145,255,245,0,129,0,146,255,245,0,129,0,147,255,245,0,129,0,148,255,245,0,129,0,149,255,245,0,129,0,151,255,245,0,129,0,152,255,240,0,129,0,153,255,240,0,129,0,154,255,240,0,129,0,155,255,240,0,129,0,156,255,192,0,129,0,158,255,242,0,129,0,166,255,245,0,129,0,167,255,245,0,129,0,168,255,245,0,129,0,169,255,245,0,129,0,170,255,245,0,129,0,175,255,250,0,129,0,177,255,245,0,129,0,178,255,245,0,129,0,179,255,245,0,129,0,180,255,245,0,129,0,181,255,245,0,129,0,183,255,245,0,129,0,184,255,244,0,129,0,185,255,244,0,129,0,186,255,244,0,129,0,187,255,244,0,129,0,188,255,217,0,129,0,190,255,217,0,129,0,194,255,245,0,129,0,195,255,245,0,129,0,198,255,192,0,129,0,209,255,205,0,129,0,210,255,204,0,129,0,212,255,205,0,129,0,213,255,204,0,129,0,220,255,247,0,129,0,240,255,212,0,130,0,3,255,213,0,130,0,8,255,213,0,130,0,11,255,212,0,130,0,18,255,239,0,130,0,26,255,242,0,130,0,32,255,239,0,130,0,36,255,245,0,130,0,40,255,245,0,130,0,48,255,245,0,130,0,50,255,245,0,130,0,53,255,202,0,130,0,54,255,240,0,130,0,55,255,207,0,130,0,56,255,219,0,130,0,58,255,192,0,130,0,61,255,208,0,130,0,68,255,245,0,130,0,69,255,245,0,130,0,70,255,245,0,130,0,71,255,241,0,130,0,72,255,248,0,130,0,77,255,249,0,130,0,80,255,245,0,130,0,82,255,245,0,130,0,85,255,229,0,130,0,86,255,244,0,130,0,87,255,221,0,130,0,88,255,228,0,130,0,90,255,217,0,130,0,94,255,246,0,130,0,107,255,247,0,130,0,110,255,241,0,130,0,134,255,245,0,130,0,145,255,245,0,130,0,146,255,245,0,130,0,147,255,245,0,130,0,148,255,245,0,130,0,149,255,245,0,130,0,151,255,245,0,130,0,152,255,240,0,130,0,153,255,240,0,130,0,154,255,240,0,130,0,155,255,240,0,130,0,156,255,192,0,130,0,158,255,242,0,130,0,166,255,245,0,130,0,167,255,245,0,130,0,168,255,245,0,130,0,169,255,245,0,130,0,170,255,245,0,130,0,175,255,250,0,130,0,177,255,245,0,130,0,178,255,245,0,130,0,179,255,245,0,130,0,180,255,245,0,130,0,181,255,245,0,130,0,183,255,245,0,130,0,184,255,244,0,130,0,185,255,244,0,130,0,186,255,244,0,130,0,187,255,244,0,130,0,188,255,217,0,130,0,190,255,217,0,130,0,194,255,245,0,130,0,195,255,245,0,130,0,198,255,192,0,130,0,209,255,205,0,130,0,210,255,204,0,130,0,212,255,205,0,130,0,213,255,204,0,130,0,220,255,247,0,130,0,240,255,212,0,131,0,3,255,213,0,131,0,8,255,213,0,131,0,11,255,212,0,131,0,18,255,239,0,131,0,26,255,242,0,131,0,32,255,239,0,131,0,36,255,245,0,131,0,40,255,245,0,131,0,48,255,245,0,131,0,50,255,245,0,131,0,53,255,202,0,131,0,54,255,240,0,131,0,55,255,207,0,131,0,56,255,219,0,131,0,58,255,192,0,131,0,61,255,208,0,131,0,68,255,245,0,131,0,69,255,245,0,131,0,70,255,245,0,131,0,71,255,241,0,131,0,72,255,248,0,131,0,77,255,249,0,131,0,80,255,245,0,131,0,82,255,245,0,131,0,85,255,229,0,131,0,86,255,244,0,131,0,87,255,221,0,131,0,88,255,228,0,131,0,90,255,217,0,131,0,94,255,246,0,131,0,107,255,247,0,131,0,110,255,241,0,131,0,134,255,245,0,131,0,145,255,245,0,131,0,146,255,245,0,131,0,147,255,245,0,131,0,148,255,245,0,131,0,149,255,245,0,131,0,151,255,245,0,131,0,152,255,240,0,131,0,153,255,240,0,131,0,154,255,240,0,131,0,155,255,240,0,131,0,156,255,192,0,131,0,158,255,242,0,131,0,166,255,245,0,131,0,167,255,245,0,131,0,168,255,245,0,131,0,169,255,245,0,131,0,170,255,245,0,131,0,175,255,250,0,131,0,177,255,245,0,131,0,178,255,245,0,131,0,179,255,245,0,131,0,180,255,245,0,131,0,181,255,245,0,131,0,183,255,245,0,131,0,184,255,244,0,131,0,185,255,244,0,131,0,186,255,244,0,131,0,187,255,244,0,131,0,188,255,217,0,131,0,190,255,217,0,131,0,194,255,245,0,131,0,195,255,245,0,131,0,198,255,192,0,131,0,209,255,205,0,131,0,210,255,204,0,131,0,212,255,205,0,131,0,213,255,204,0,131,0,220,255,247,0,131,0,240,255,212,0,132,0,3,255,213,0,132,0,8,255,213,0,132,0,11,255,212,0,132,0,18,255,239,0,132,0,26,255,242,0,132,0,32,255,239,0,132,0,36,255,245,0,132,0,40,255,245,0,132,0,48,255,245,0,132,0,50,255,245,0,132,0,53,255,202,0,132,0,54,255,240,0,132,0,55,255,207,0,132,0,56,255,219,0,132,0,58,255,192,0,132,0,61,255,208,0,132,0,68,255,245,0,132,0,69,255,245,0,132,0,70,255,245,0,132,0,71,255,241,0,132,0,72,255,248,0,132,0,77,255,249,0,132,0,80,255,245,0,132,0,82,255,245,0,132,0,85,255,229,0,132,0,86,255,244,0,132,0,87,255,221,0,132,0,88,255,228,0,132,0,90,255,217,0,132,0,94,255,246,0,132,0,107,255,247,0,132,0,110,255,241,0,132,0,134,255,245,0,132,0,145,255,245,0,132,0,146,255,245,0,132,0,147,255,245,0,132,0,148,255,245,0,132,0,149,255,245,0,132,0,151,255,245,0,132,0,152,255,240,0,132,0,153,255,240,0,132,0,154,255,240,0,132,0,155,255,240,0,132,0,156,255,192,0,132,0,158,255,242,0,132,0,166,255,245,0,132,0,167,255,245,0,132,0,168,255,245,0,132,0,169,255,245,0,132,0,170,255,245,0,132,0,175,255,250,0,132,0,177,255,245,0,132,0,178,255,245,0,132,0,179,255,245,0,132,0,180,255,245,0,132,0,181,255,245,0,132,0,183,255,245,0,132,0,184,255,244,0,132,0,185,255,244,0,132,0,186,255,244,0,132,0,187,255,244,0,132,0,188,255,217,0,132,0,190,255,217,0,132,0,194,255,245,0,132,0,195,255,245,0,132,0,198,255,192,0,132,0,209,255,205,0,132,0,210,255,204,0,132,0,212,255,205,0,132,0,213,255,204,0,132,0,220,255,247,0,132,0,240,255,212,0,133,0,14,255,244,0,133,0,21,255,220,0,133,0,36,255,245,0,133,0,40,255,245,0,133,0,48,255,245,0,133,0,50,255,245,0,133,0,68,255,240,0,133,0,69,255,240,0,133,0,70,255,240,0,133,0,71,255,243,0,133,0,72,255,241,0,133,0,78,255,247,0,133,0,79,255,247,0,133,0,80,255,240,0,133,0,81,255,247,0,133,0,82,255,240,0,133,0,83,255,247,0,133,0,84,255,251,0,133,0,85,255,242,0,133,0,86,255,238,0,133,0,87,255,241,0,133,0,88,255,243,0,133,0,90,255,240,0,133,0,107,255,235,0,133,0,110,255,248,0,133,0,134,255,245,0,133,0,145,255,245,0,133,0,146,255,245,0,133,0,147,255,245,0,133,0,148,255,245,0,133,0,149,255,245,0,133,0,151,255,245,0,133,0,158,255,243,0,133,0,166,255,240,0,133,0,167,255,240,0,133,0,168,255,240,0,133,0,169,255,240,0,133,0,170,255,240,0,133,0,173,0,21,0,133,0,175,255,246,0,133,0,176,255,247,0,133,0,177,255,240,0,133,0,178,255,240,0,133,0,179,255,240,0,133,0,180,255,240,0,133,0,181,255,240,0,133,0,183,255,240,0,133,0,184,255,238,0,133,0,185,255,238,0,133,0,186,255,238,0,133,0,187,255,238,0,133,0,188,255,240,0,133,0,189,255,247,0,133,0,190,255,240,0,133,0,194,255,245,0,133,0,195,255,240,0,133,0,197,255,251,0,133,0,207,255,244,0,133,0,208,255,244,0,133,0,220,255,235,0,134,0,14,255,195,0,134,0,21,255,207,0,134,0,36,255,242,0,134,0,40,255,242,0,134,0,48,255,242,0,134,0,50,255,242,0,134,0,68,255,242,0,134,0,69,255,242,0,134,0,70,255,242,0,134,0,71,255,249,0,134,0,72,255,241,0,134,0,78,255,249,0,134,0,79,255,249,0,134,0,80,255,242,0,134,0,81,255,249,0,134,0,82,255,242,0,134,0,83,255,249,0,134,0,85,255,249,0,134,0,86,255,241,0,134,0,87,255,249,0,134,0,88,255,250,0,134,0,90,255,249,0,134,0,107,255,226,0,134,0,134,255,242,0,134,0,145,255,242,0,134,0,146,255,242,0,134,0,147,255,242,0,134,0,148,255,242,0,134,0,149,255,242,0,134,0,151,255,242,0,134,0,158,255,250,0,134,0,166,255,242,0,134,0,167,255,242,0,134,0,168,255,242,0,134,0,169,255,242,0,134,0,170,255,242,0,134,0,173,0,31,0,134,0,174,0,12,0,134,0,175,255,249,0,134,0,176,255,249,0,134,0,177,255,242,0,134,0,178,255,242,0,134,0,179,255,242,0,134,0,180,255,242,0,134,0,181,255,242,0,134,0,183,255,242,0,134,0,184,255,241,0,134,0,185,255,241,0,134,0,186,255,241,0,134,0,187,255,241,0,134,0,188,255,249,0,134,0,189,255,249,0,134,0,190,255,249,0,134,0,194,255,242,0,134,0,195,255,242,0,134,0,207,255,195,0,134,0,208,255,195,0,134,0,220,255,226,0,135,0,14,255,244,0,135,0,21,255,220,0,135,0,36,255,245,0,135,0,40,255,245,0,135,0,48,255,245,0,135,0,50,255,245,0,135,0,68,255,240,0,135,0,69,255,240,0,135,0,70,255,240,0,135,0,71,255,243,0,135,0,72,255,241,0,135,0,78,255,247,0,135,0,79,255,247,0,135,0,80,255,240,0,135,0,81,255,247,0,135,0,82,255,240,0,135,0,83,255,247,0,135,0,84,255,251,0,135,0,85,255,242,0,135,0,86,255,238,0,135,0,87,255,241,0,135,0,88,255,243,0,135,0,90,255,240,0,135,0,107,255,235,0,135,0,110,255,248,0,135,0,134,255,245,0,135,0,145,255,245,0,135,0,146,255,245,0,135,0,147,255,245,0,135,0,148,255,245,0,135,0,149,255,245,0,135,0,151,255,245,0,135,0,158,255,243,0,135,0,166,255,240,0,135,0,167,255,240,0,135,0,168,255,240,0,135,0,169,255,240,0,135,0,170,255,240,0,135,0,173,0,21,0,135,0,175,255,246,0,135,0,176,255,247,0,135,0,177,255,240,0,135,0,178,255,240,0,135,0,179,255,240,0,135,0,180,255,240,0,135,0,181,255,240,0,135,0,183,255,240,0,135,0,184,255,238,0,135,0,185,255,238,0,135,0,186,255,238,0,135,0,187,255,238,0,135,0,188,255,240,0,135,0,189,255,247,0,135,0,190,255,240,0,135,0,194,255,245,0,135,0,195,255,240,0,135,0,197,255,251,0,135,0,207,255,244,0,135,0,208,255,244,0,135,0,220,255,235,0,136,0,14,255,244,0,136,0,21,255,220,0,136,0,36,255,245,0,136,0,40,255,245,0,136,0,48,255,245,0,136,0,50,255,245,0,136,0,68,255,240,0,136,0,69,255,240,0,136,0,70,255,240,0,136,0,71,255,243,0,136,0,72,255,241,0,136,0,78,255,247,0,136,0,79,255,247,0,136,0,80,255,240,0,136,0,81,255,247,0,136,0,82,255,240,0,136,0,83,255,247,0,136,0,84,255,251,0,136,0,85,255,242,0,136,0,86,255,238,0,136,0,87,255,241,0,136,0,88,255,243,0,136,0,90,255,240,0,136,0,107,255,235,0,136,0,110,255,248,0,136,0,134,255,245,0,136,0,145,255,245,0,136,0,146,255,245,0,136,0,147,255,245,0,136,0,148,255,245,0,136,0,149,255,245,0,136,0,151,255,245,0,136,0,158,255,243,0,136,0,166,255,240,0,136,0,167,255,240,0,136,0,168,255,240,0,136,0,169,255,240,0,136,0,170,255,240,0,136,0,173,0,21,0,136,0,175,255,246,0,136,0,176,255,247,0,136,0,177,255,240,0,136,0,178,255,240,0,136,0,179,255,240,0,136,0,180,255,240,0,136,0,181,255,240,0,136,0,183,255,240,0,136,0,184,255,238,0,136,0,185,255,238,0,136,0,186,255,238,0,136,0,187,255,238,0,136,0,188,255,240,0,136,0,189,255,247,0,136,0,190,255,240,0,136,0,194,255,245,0,136,0,195,255,240,0,136,0,197,255,251,0,136,0,207,255,244,0,136,0,208,255,244,0,136,0,220,255,235,0,137,0,14,255,244,0,137,0,21,255,220,0,137,0,36,255,245,0,137,0,40,255,245,0,137,0,48,255,245,0,137,0,50,255,245,0,137,0,68,255,240,0,137,0,69,255,240,0,137,0,70,255,240,0,137,0,71,255,243,0,137,0,72,255,241,0,137,0,78,255,247,0,137,0,79,255,247,0,137,0,80,255,240,0,137,0,81,255,247,0,137,0,82,255,240,0,137,0,83,255,247,0,137,0,84,255,251,0,137,0,85,255,242,0,137,0,86,255,238,0,137,0,87,255,241,0,137,0,88,255,243,0,137,0,90,255,240,0,137,0,107,255,235,0,137,0,110,255,248,0,137,0,134,255,245,0,137,0,145,255,245,0,137,0,146,255,245,0,137,0,147,255,245,0,137,0,148,255,245,0,137,0,149,255,245,0,137,0,151,255,245,0,137,0,158,255,243,0,137,0,166,255,240,0,137,0,167,255,240,0,137,0,168,255,240,0,137,0,169,255,240,0,137,0,170,255,240,0,137,0,173,0,21,0,137,0,175,255,246,0,137,0,176,255,247,0,137,0,177,255,240,0,137,0,178,255,240,0,137,0,179,255,240,0,137,0,180,255,240,0,137,0,181,255,240,0,137,0,183,255,240,0,137,0,184,255,238,0,137,0,185,255,238,0,137,0,186,255,238,0,137,0,187,255,238,0,137,0,188,255,240,0,137,0,189,255,247,0,137,0,190,255,240,0,137,0,194,255,245,0,137,0,195,255,240,0,137,0,197,255,251,0,137,0,207,255,244,0,137,0,208,255,244,0,137,0,220,255,235,0,138,0,14,255,244,0,138,0,21,255,220,0,138,0,36,255,245,0,138,0,40,255,245,0,138,0,48,255,245,0,138,0,50,255,245,0,138,0,68,255,240,0,138,0,69,255,240,0,138,0,70,255,240,0,138,0,71,255,243,0,138,0,72,255,241,0,138,0,78,255,247,0,138,0,79,255,247,0,138,0,80,255,240,0,138,0,81,255,247,0,138,0,82,255,240,0,138,0,83,255,247,0,138,0,84,255,251,0,138,0,85,255,242,0,138,0,86,255,238,0,138,0,87,255,241,0,138,0,88,255,243,0,138,0,90,255,240,0,138,0,107,255,235,0,138,0,110,255,248,0,138,0,134,255,245,0,138,0,145,255,245,0,138,0,146,255,245,0,138,0,147,255,245,0,138,0,148,255,245,0,138,0,149,255,245,0,138,0,151,255,245,0,138,0,158,255,243,0,138,0,166,255,240,0,138,0,167,255,240,0,138,0,168,255,240,0,138,0,169,255,240,0,138,0,170,255,240,0,138,0,173,0,21,0,138,0,175,255,246,0,138,0,176,255,247,0,138,0,177,255,240,0,138,0,178,255,240,0,138,0,179,255,240,0,138,0,180,255,240,0,138,0,181,255,240,0,138,0,183,255,240,0,138,0,184,255,238,0,138,0,185,255,238,0,138,0,186,255,238,0,138,0,187,255,238,0,138,0,188,255,240,0,138,0,189,255,247,0,138,0,190,255,240,0,138,0,194,255,245,0,138,0,195,255,240,0,138,0,197,255,251,0,138,0,207,255,244,0,138,0,208,255,244,0,138,0,220,255,235,0,139,0,10,255,246,0,139,0,46,255,251,0,139,0,66,255,246,0,139,0,67,255,247,0,139,0,68,255,242,0,139,0,69,255,242,0,139,0,70,255,242,0,139,0,71,255,247,0,139,0,72,255,241,0,139,0,73,255,247,0,139,0,74,255,247,0,139,0,75,255,247,0,139,0,76,255,247,0,139,0,77,255,246,0,139,0,78,255,247,0,139,0,79,255,247,0,139,0,80,255,242,0,139,0,81,255,247,0,139,0,82,255,242,0,139,0,83,255,247,0,139,0,84,255,246,0,139,0,85,255,247,0,139,0,86,255,245,0,139,0,87,255,247,0,139,0,88,255,248,0,139,0,90,255,247,0,139,0,91,255,246,0,139,0,158,255,244,0,139,0,159,255,246,0,139,0,160,255,246,0,139,0,161,255,246,0,139,0,162,255,246,0,139,0,163,255,246,0,139,0,164,255,246,0,139,0,165,255,246,0,139,0,166,255,242,0,139,0,167,255,242,0,139,0,168,255,242,0,139,0,169,255,242,0,139,0,170,255,242,0,139,0,171,255,247,0,139,0,172,255,247,0,139,0,173,255,247,0,139,0,174,255,247,0,139,0,175,255,243,0,139,0,176,255,247,0,139,0,177,255,242,0,139,0,178,255,242,0,139,0,179,255,242,0,139,0,180,255,242,0,139,0,181,255,242,0,139,0,183,255,242,0,139,0,184,255,245,0,139,0,185,255,245,0,139,0,186,255,245,0,139,0,187,255,245,0,139,0,188,255,247,0,139,0,189,255,247,0,139,0,190,255,247,0,139,0,193,255,247,0,139,0,195,255,242,0,139,0,197,255,246,0,139,0,200,255,246,0,140,0,10,255,246,0,140,0,46,255,251,0,140,0,66,255,246,0,140,0,67,255,247,0,140,0,68,255,242,0,140,0,69,255,242,0,140,0,70,255,242,0,140,0,71,255,247,0,140,0,72,255,241,0,140,0,73,255,247,0,140,0,74,255,247,0,140,0,75,255,247,0,140,0,76,255,247,0,140,0,77,255,246,0,140,0,78,255,247,0,140,0,79,255,247,0,140,0,80,255,242,0,140,0,81,255,247,0,140,0,82,255,242,0,140,0,83,255,247,0,140,0,84,255,246,0,140,0,85,255,247,0,140,0,86,255,245,0,140,0,87,255,247,0,140,0,88,255,248,0,140,0,90,255,247,0,140,0,91,255,246,0,140,0,158,255,244,0,140,0,159,255,246,0,140,0,160,255,246,0,140,0,161,255,246,0,140,0,162,255,246,0,140,0,163,255,246,0,140,0,164,255,246,0,140,0,165,255,246,0,140,0,166,255,242,0,140,0,167,255,242,0,140,0,168,255,242,0,140,0,169,255,242,0,140,0,170,255,242,0,140,0,171,255,247,0,140,0,172,255,247,0,140,0,173,255,247,0,140,0,174,255,247,0,140,0,175,255,243,0,140,0,176,255,247,0,140,0,177,255,242,0,140,0,178,255,242,0,140,0,179,255,242,0,140,0,180,255,242,0,140,0,181,255,242,0,140,0,183,255,242,0,140,0,184,255,245,0,140,0,185,255,245,0,140,0,186,255,245,0,140,0,187,255,245,0,140,0,188,255,247,0,140,0,189,255,247,0,140,0,190,255,247,0,140,0,193,255,247,0,140,0,195,255,242,0,140,0,197,255,246,0,140,0,200,255,246,0,141,0,10,255,246,0,141,0,46,255,251,0,141,0,66,255,246,0,141,0,67,255,247,0,141,0,68,255,242,0,141,0,69,255,242,0,141,0,70,255,242,0,141,0,71,255,247,0,141,0,72,255,241,0,141,0,73,255,247,0,141,0,74,255,247,0,141,0,75,255,247,0,141,0,76,255,247,0,141,0,77,255,246,0,141,0,78,255,247,0,141,0,79,255,247,0,141,0,80,255,242,0,141,0,81,255,247,0,141,0,82,255,242,0,141,0,83,255,247,0,141,0,84,255,246,0,141,0,85,255,247,0,141,0,86,255,245,0,141,0,87,255,247,0,141,0,88,255,248,0,141,0,90,255,247,0,141,0,91,255,246,0,141,0,158,255,244,0,141,0,159,255,246,0,141,0,160,255,246,0,141,0,161,255,246,0,141,0,162,255,246,0,141,0,163,255,246,0,141,0,164,255,246,0,141,0,165,255,246,0,141,0,166,255,242,0,141,0,167,255,242,0,141,0,168,255,242,0,141,0,169,255,242,0,141,0,170,255,242,0,141,0,171,255,247,0,141,0,172,255,247,0,141,0,173,255,247,0,141,0,174,255,247,0,141,0,175,255,243,0,141,0,176,255,247,0,141,0,177,255,242,0,141,0,178,255,242,0,141,0,179,255,242,0,141,0,180,255,242,0,141,0,181,255,242,0,141,0,183,255,242,0,141,0,184,255,245,0,141,0,185,255,245,0,141,0,186,255,245,0,141,0,187,255,245,0,141,0,188,255,247,0,141,0,189,255,247,0,141,0,190,255,247,0,141,0,193,255,247,0,141,0,195,255,242,0,141,0,197,255,246,0,141,0,200,255,246,0,142,0,10,255,246,0,142,0,46,255,251,0,142,0,66,255,246,0,142,0,67,255,247,0,142,0,68,255,242,0,142,0,69,255,242,0,142,0,70,255,242,0,142,0,71,255,247,0,142,0,72,255,241,0,142,0,73,255,247,0,142,0,74,255,247,0,142,0,75,255,247,0,142,0,76,255,247,0,142,0,77,255,246,0,142,0,78,255,247,0,142,0,79,255,247,0,142,0,80,255,242,0,142,0,81,255,247,0,142,0,82,255,242,0,142,0,83,255,247,0,142,0,84,255,246,0,142,0,85,255,247,0,142,0,86,255,245,0,142,0,87,255,247,0,142,0,88,255,248,0,142,0,90,255,247,0,142,0,91,255,246,0,142,0,158,255,244,0,142,0,159,255,246,0,142,0,160,255,246,0,142,0,161,255,246,0,142,0,162,255,246,0,142,0,163,255,246,0,142,0,164,255,246,0,142,0,165,255,246,0,142,0,166,255,242,0,142,0,167,255,242,0,142,0,168,255,242,0,142,0,169,255,242,0,142,0,170,255,242,0,142,0,171,255,247,0,142,0,172,255,247,0,142,0,173,255,247,0,142,0,174,255,247,0,142,0,175,255,243,0,142,0,176,255,247,0,142,0,177,255,242,0,142,0,178,255,242,0,142,0,179,255,242,0,142,0,180,255,242,0,142,0,181,255,242,0,142,0,183,255,242,0,142,0,184,255,245,0,142,0,185,255,245,0,142,0,186,255,245,0,142,0,187,255,245,0,142,0,188,255,247,0,142,0,189,255,247,0,142,0,190,255,247,0,142,0,193,255,247,0,142,0,195,255,242,0,142,0,197,255,246,0,142,0,200,255,246,0,143,0,10,255,228,0,143,0,13,255,241,0,143,0,15,255,242,0,143,0,16,255,237,0,143,0,20,255,248,0,143,0,24,255,240,0,143,0,32,255,237,0,143,0,34,255,244,0,143,0,46,255,250,0,143,0,53,255,228,0,143,0,55,255,243,0,143,0,56,255,248,0,143,0,57,255,225,0,143,0,58,255,227,0,143,0,59,255,235,0,143,0,61,255,244,0,143,0,62,255,224,0,143,0,66,255,248,0,143,0,67,255,249,0,143,0,68,255,250,0,143,0,69,255,250,0,143,0,70,255,250,0,143,0,72,255,250,0,143,0,73,255,249,0,143,0,74,255,249,0,143,0,75,255,249,0,143,0,76,255,249,0,143,0,77,255,249,0,143,0,78,255,249,0,143,0,79,255,249,0,143,0,80,255,250,0,143,0,81,255,249,0,143,0,82,255,250,0,143,0,83,255,249,0,143,0,84,255,250,0,143,0,86,255,250,0,143,0,89,255,244,0,143,0,91,255,250,0,143,0,94,255,229,0,143,0,127,255,244,0,143,0,128,255,244,0,143,0,129,255,244,0,143,0,130,255,244,0,143,0,131,255,244,0,143,0,132,255,244,0,143,0,133,255,226,0,143,0,156,255,227,0,143,0,158,255,250,0,143,0,159,255,248,0,143,0,160,255,248,0,143,0,161,255,248,0,143,0,162,255,248,0,143,0,163,255,248,0,143,0,164,255,248,0,143,0,165,255,248,0,143,0,166,255,250,0,143,0,167,255,250,0,143,0,168,255,250,0,143,0,169,255,250,0,143,0,170,255,250,0,143,0,171,255,249,0,143,0,172,255,249,0,143,0,173,255,249,0,143,0,174,255,249,0,143,0,175,255,249,0,143,0,176,255,249,0,143,0,177,255,250,0,143,0,178,255,250,0,143,0,179,255,250,0,143,0,180,255,250,0,143,0,181,255,250,0,143,0,183,255,250,0,143,0,184,255,250,0,143,0,185,255,250,0,143,0,186,255,250,0,143,0,187,255,250,0,143,0,189,255,249,0,143,0,193,255,249,0,143,0,195,255,250,0,143,0,197,255,250,0,143,0,198,255,227,0,143,0,199,255,235,0,143,0,200,255,250,0,143,0,210,255,247,0,143,0,211,255,241,0,143,0,213,255,247,0,143,0,214,255,241,0,143,0,218,255,242,0,143,0,240,255,246,0,144,0,10,255,246,0,144,0,46,255,251,0,144,0,66,255,246,0,144,0,67,255,247,0,144,0,68,255,242,0,144,0,69,255,242,0,144,0,70,255,242,0,144,0,71,255,247,0,144,0,72,255,241,0,144,0,73,255,247,0,144,0,74,255,247,0,144,0,75,255,247,0,144,0,76,255,247,0,144,0,77,255,246,0,144,0,78,255,247,0,144,0,79,255,247,0,144,0,80,255,242,0,144,0,81,255,247,0,144,0,82,255,242,0,144,0,83,255,247,0,144,0,84,255,246,0,144,0,85,255,247,0,144,0,86,255,245,0,144,0,87,255,247,0,144,0,88,255,248,0,144,0,90,255,247,0,144,0,91,255,246,0,144,0,158,255,244,0,144,0,159,255,246,0,144,0,160,255,246,0,144,0,161,255,246,0,144,0,162,255,246,0,144,0,163,255,246,0,144,0,164,255,246,0,144,0,165,255,246,0,144,0,166,255,242,0,144,0,167,255,242,0,144,0,168,255,242,0,144,0,169,255,242,0,144,0,170,255,242,0,144,0,171,255,247,0,144,0,172,255,247,0,144,0,173,255,247,0,144,0,174,255,247,0,144,0,175,255,243,0,144,0,176,255,247,0,144,0,177,255,242,0,144,0,178,255,242,0,144,0,179,255,242,0,144,0,180,255,242,0,144,0,181,255,242,0,144,0,183,255,242,0,144,0,184,255,245,0,144,0,185,255,245,0,144,0,186,255,245,0,144,0,187,255,245,0,144,0,188,255,247,0,144,0,189,255,247,0,144,0,190,255,247,0,144,0,193,255,247,0,144,0,195,255,242,0,144,0,197,255,246,0,144,0,200,255,246,0,145,0,10,255,229,0,145,0,13,255,242,0,145,0,15,255,242,0,145,0,16,255,239,0,145,0,24,255,243,0,145,0,32,255,240,0,145,0,34,255,245,0,145,0,46,255,251,0,145,0,53,255,232,0,145,0,55,255,244,0,145,0,56,255,248,0,145,0,57,255,229,0,145,0,58,255,230,0,145,0,59,255,238,0,145,0,61,255,245,0,145,0,62,255,227,0,145,0,66,255,247,0,145,0,67,255,250,0,145,0,68,255,250,0,145,0,69,255,250,0,145,0,70,255,250,0,145,0,72,255,250,0,145,0,73,255,250,0,145,0,74,255,249,0,145,0,75,255,249,0,145,0,76,255,250,0,145,0,77,255,250,0,145,0,78,255,249,0,145,0,79,255,249,0,145,0,80,255,250,0,145,0,81,255,249,0,145,0,82,255,250,0,145,0,83,255,249,0,145,0,84,255,250,0,145,0,86,255,251,0,145,0,89,255,245,0,145,0,91,255,250,0,145,0,94,255,231,0,145,0,127,255,245,0,145,0,128,255,245,0,145,0,129,255,245,0,145,0,130,255,245,0,145,0,131,255,245,0,145,0,132,255,245,0,145,0,133,255,229,0,145,0,156,255,230,0,145,0,158,255,251,0,145,0,159,255,247,0,145,0,160,255,247,0,145,0,161,255,247,0,145,0,162,255,247,0,145,0,163,255,247,0,145,0,164,255,247,0,145,0,165,255,247,0,145,0,166,255,250,0,145,0,167,255,250,0,145,0,168,255,250,0,145,0,169,255,250,0,145,0,170,255,250,0,145,0,171,255,249,0,145,0,172,255,249,0,145,0,173,255,249,0,145,0,174,255,249,0,145,0,175,255,250,0,145,0,176,255,249,0,145,0,177,255,250,0,145,0,178,255,250,0,145,0,179,255,250,0,145,0,180,255,250,0,145,0,181,255,250,0,145,0,183,255,250,0,145,0,184,255,251,0,145,0,185,255,251,0,145,0,186,255,251,0,145,0,187,255,251,0,145,0,189,255,249,0,145,0,193,255,249,0,145,0,195,255,250,0,145,0,197,255,250,0,145,0,198,255,230,0,145,0,199,255,238,0,145,0,200,255,250,0,145,0,210,255,247,0,145,0,211,255,242,0,145,0,213,255,247,0,145,0,214,255,242,0,145,0,218,255,242,0,145,0,240,255,246,0,146,0,10,255,229,0,146,0,13,255,242,0,146,0,15,255,242,0,146,0,16,255,239,0,146,0,24,255,243,0,146,0,32,255,240,0,146,0,34,255,245,0,146,0,46,255,251,0,146,0,53,255,232,0,146,0,55,255,244,0,146,0,56,255,248,0,146,0,57,255,229,0,146,0,58,255,230,0,146,0,59,255,238,0,146,0,61,255,245,0,146,0,62,255,227,0,146,0,66,255,247,0,146,0,67,255,250,0,146,0,68,255,250,0,146,0,69,255,250,0,146,0,70,255,250,0,146,0,72,255,250,0,146,0,73,255,250,0,146,0,74,255,249,0,146,0,75,255,249,0,146,0,76,255,250,0,146,0,77,255,250,0,146,0,78,255,249,0,146,0,79,255,249,0,146,0,80,255,250,0,146,0,81,255,249,0,146,0,82,255,250,0,146,0,83,255,249,0,146,0,84,255,250,0,146,0,86,255,251,0,146,0,89,255,245,0,146,0,91,255,250,0,146,0,94,255,231,0,146,0,127,255,245,0,146,0,128,255,245,0,146,0,129,255,245,0,146,0,130,255,245,0,146,0,131,255,245,0,146,0,132,255,245,0,146,0,133,255,229,0,146,0,156,255,230,0,146,0,158,255,251,0,146,0,159,255,247,0,146,0,160,255,247,0,146,0,161,255,247,0,146,0,162,255,247,0,146,0,163,255,247,0,146,0,164,255,247,0,146,0,165,255,247,0,146,0,166,255,250,0,146,0,167,255,250,0,146,0,168,255,250,0,146,0,169,255,250,0,146,0,170,255,250,0,146,0,171,255,249,0,146,0,172,255,249,0,146,0,173,255,249,0,146,0,174,255,249,0,146,0,175,255,250,0,146,0,176,255,249,0,146,0,177,255,250,0,146,0,178,255,250,0,146,0,179,255,250,0,146,0,180,255,250,0,146,0,181,255,250,0,146,0,183,255,250,0,146,0,184,255,251,0,146,0,185,255,251,0,146,0,186,255,251,0,146,0,187,255,251,0,146,0,189,255,249,0,146,0,193,255,249,0,146,0,195,255,250,0,146,0,197,255,250,0,146,0,198,255,230,0,146,0,199,255,238,0,146,0,200,255,250,0,146,0,210,255,247,0,146,0,211,255,242,0,146,0,213,255,247,0,146,0,214,255,242,0,146,0,218,255,242,0,146,0,240,255,246,0,147,0,10,255,229,0,147,0,13,255,242,0,147,0,15,255,242,0,147,0,16,255,239,0,147,0,24,255,243,0,147,0,32,255,240,0,147,0,34,255,245,0,147,0,46,255,251,0,147,0,53,255,232,0,147,0,55,255,244,0,147,0,56,255,248,0,147,0,57,255,229,0,147,0,58,255,230,0,147,0,59,255,238,0,147,0,61,255,245,0,147,0,62,255,227,0,147,0,66,255,247,0,147,0,67,255,250,0,147,0,68,255,250,0,147,0,69,255,250,0,147,0,70,255,250,0,147,0,72,255,250,0,147,0,73,255,250,0,147,0,74,255,249,0,147,0,75,255,249,0,147,0,76,255,250,0,147,0,77,255,250,0,147,0,78,255,249,0,147,0,79,255,249,0,147,0,80,255,250,0,147,0,81,255,249,0,147,0,82,255,250,0,147,0,83,255,249,0,147,0,84,255,250,0,147,0,86,255,251,0,147,0,89,255,245,0,147,0,91,255,250,0,147,0,94,255,231,0,147,0,127,255,245,0,147,0,128,255,245,0,147,0,129,255,245,0,147,0,130,255,245,0,147,0,131,255,245,0,147,0,132,255,245,0,147,0,133,255,229,0,147,0,156,255,230,0,147,0,158,255,251,0,147,0,159,255,247,0,147,0,160,255,247,0,147,0,161,255,247,0,147,0,162,255,247,0,147,0,163,255,247,0,147,0,164,255,247,0,147,0,165,255,247,0,147,0,166,255,250,0,147,0,167,255,250,0,147,0,168,255,250,0,147,0,169,255,250,0,147,0,170,255,250,0,147,0,171,255,249,0,147,0,172,255,249,0,147,0,173,255,249,0,147,0,174,255,249,0,147,0,175,255,250,0,147,0,176,255,249,0,147,0,177,255,250,0,147,0,178,255,250,0,147,0,179,255,250,0,147,0,180,255,250,0,147,0,181,255,250,0,147,0,183,255,250,0,147,0,184,255,251,0,147,0,185,255,251,0,147,0,186,255,251,0,147,0,187,255,251,0,147,0,189,255,249,0,147,0,193,255,249,0,147,0,195,255,250,0,147,0,197,255,250,0,147,0,198,255,230,0,147,0,199,255,238,0,147,0,200,255,250,0,147,0,210,255,247,0,147,0,211,255,242,0,147,0,213,255,247,0,147,0,214,255,242,0,147,0,218,255,242,0,147,0,240,255,246,0,148,0,10,255,229,0,148,0,13,255,242,0,148,0,15,255,242,0,148,0,16,255,239,0,148,0,24,255,243,0,148,0,32,255,240,0,148,0,34,255,245,0,148,0,46,255,251,0,148,0,53,255,232,0,148,0,55,255,244,0,148,0,56,255,248,0,148,0,57,255,229,0,148,0,58,255,230,0,148,0,59,255,238,0,148,0,61,255,245,0,148,0,62,255,227,0,148,0,66,255,247,0,148,0,67,255,250,0,148,0,68,255,250,0,148,0,69,255,250,0,148,0,70,255,250,0,148,0,72,255,250,0,148,0,73,255,250,0,148,0,74,255,249,0,148,0,75,255,249,0,148,0,76,255,250,0,148,0,77,255,250,0,148,0,78,255,249,0,148,0,79,255,249,0,148,0,80,255,250,0,148,0,81,255,249,0,148,0,82,255,250,0,148,0,83,255,249,0,148,0,84,255,250,0,148,0,86,255,251,0,148,0,89,255,245,0,148,0,91,255,250,0,148,0,94,255,231,0,148,0,127,255,245,0,148,0,128,255,245,0,148,0,129,255,245,0,148,0,130,255,245,0,148,0,131,255,245,0,148,0,132,255,245,0,148,0,133,255,229,0,148,0,156,255,230,0,148,0,158,255,251,0,148,0,159,255,247,0,148,0,160,255,247,0,148,0,161,255,247,0,148,0,162,255,247,0,148,0,163,255,247,0,148,0,164,255,247,0,148,0,165,255,247,0,148,0,166,255,250,0,148,0,167,255,250,0,148,0,168,255,250,0,148,0,169,255,250,0,148,0,170,255,250,0,148,0,171,255,249,0,148,0,172,255,249,0,148,0,173,255,249,0,148,0,174,255,249,0,148,0,175,255,250,0,148,0,176,255,249,0,148,0,177,255,250,0,148,0,178,255,250,0,148,0,179,255,250,0,148,0,180,255,250,0,148,0,181,255,250,0,148,0,183,255,250,0,148,0,184,255,251,0,148,0,185,255,251,0,148,0,186,255,251,0,148,0,187,255,251,0,148,0,189,255,249,0,148,0,193,255,249,0,148,0,195,255,250,0,148,0,197,255,250,0,148,0,198,255,230,0,148,0,199,255,238,0,148,0,200,255,250,0,148,0,210,255,247,0,148,0,211,255,242,0,148,0,213,255,247,0,148,0,214,255,242,0,148,0,218,255,242,0,148,0,240,255,246,0,149,0,10,255,229,0,149,0,13,255,242,0,149,0,15,255,242,0,149,0,16,255,239,0,149,0,24,255,243,0,149,0,32,255,240,0,149,0,34,255,245,0,149,0,46,255,251,0,149,0,53,255,232,0,149,0,55,255,244,0,149,0,56,255,248,0,149,0,57,255,229,0,149,0,58,255,230,0,149,0,59,255,238,0,149,0,61,255,245,0,149,0,62,255,227,0,149,0,66,255,247,0,149,0,67,255,250,0,149,0,68,255,250,0,149,0,69,255,250,0,149,0,70,255,250,0,149,0,72,255,250,0,149,0,73,255,250,0,149,0,74,255,249,0,149,0,75,255,249,0,149,0,76,255,250,0,149,0,77,255,250,0,149,0,78,255,249,0,149,0,79,255,249,0,149,0,80,255,250,0,149,0,81,255,249,0,149,0,82,255,250,0,149,0,83,255,249,0,149,0,84,255,250,0,149,0,86,255,251,0,149,0,89,255,245,0,149,0,91,255,250,0,149,0,94,255,231,0,149,0,127,255,245,0,149,0,128,255,245,0,149,0,129,255,245,0,149,0,130,255,245,0,149,0,131,255,245,0,149,0,132,255,245,0,149,0,133,255,229,0,149,0,156,255,230,0,149,0,158,255,251,0,149,0,159,255,247,0,149,0,160,255,247,0,149,0,161,255,247,0,149,0,162,255,247,0,149,0,163,255,247,0,149,0,164,255,247,0,149,0,165,255,247,0,149,0,166,255,250,0,149,0,167,255,250,0,149,0,168,255,250,0,149,0,169,255,250,0,149,0,170,255,250,0,149,0,171,255,249,0,149,0,172,255,249,0,149,0,173,255,249,0,149,0,174,255,249,0,149,0,175,255,250,0,149,0,176,255,249,0,149,0,177,255,250,0,149,0,178,255,250,0,149,0,179,255,250,0,149,0,180,255,250,0,149,0,181,255,250,0,149,0,183,255,250,0,149,0,184,255,251,0,149,0,185,255,251,0,149,0,186,255,251,0,149,0,187,255,251,0,149,0,189,255,249,0,149,0,193,255,249,0,149,0,195,255,250,0,149,0,197,255,250,0,149,0,198,255,230,0,149,0,199,255,238,0,149,0,200,255,250,0,149,0,210,255,247,0,149,0,211,255,242,0,149,0,213,255,247,0,149,0,214,255,242,0,149,0,218,255,242,0,149,0,240,255,246,0,151,0,10,255,229,0,151,0,13,255,242,0,151,0,15,255,242,0,151,0,16,255,239,0,151,0,24,255,243,0,151,0,32,255,240,0,151,0,34,255,245,0,151,0,46,255,251,0,151,0,53,255,232,0,151,0,55,255,244,0,151,0,56,255,248,0,151,0,57,255,229,0,151,0,58,255,230,0,151,0,59,255,238,0,151,0,61,255,245,0,151,0,62,255,227,0,151,0,66,255,247,0,151,0,67,255,250,0,151,0,68,255,250,0,151,0,69,255,250,0,151,0,70,255,250,0,151,0,72,255,250,0,151,0,73,255,250,0,151,0,74,255,249,0,151,0,75,255,249,0,151,0,76,255,250,0,151,0,77,255,250,0,151,0,78,255,249,0,151,0,79,255,249,0,151,0,80,255,250,0,151,0,81,255,249,0,151,0,82,255,250,0,151,0,83,255,249,0,151,0,84,255,250,0,151,0,86,255,251,0,151,0,89,255,245,0,151,0,91,255,250,0,151,0,94,255,231,0,151,0,127,255,245,0,151,0,128,255,245,0,151,0,129,255,245,0,151,0,130,255,245,0,151,0,131,255,245,0,151,0,132,255,245,0,151,0,133,255,229,0,151,0,156,255,230,0,151,0,158,255,251,0,151,0,159,255,247,0,151,0,160,255,247,0,151,0,161,255,247,0,151,0,162,255,247,0,151,0,163,255,247,0,151,0,164,255,247,0,151,0,165,255,247,0,151,0,166,255,250,0,151,0,167,255,250,0,151,0,168,255,250,0,151,0,169,255,250,0,151,0,170,255,250,0,151,0,171,255,249,0,151,0,172,255,249,0,151,0,173,255,249,0,151,0,174,255,249,0,151,0,175,255,250,0,151,0,176,255,249,0,151,0,177,255,250,0,151,0,178,255,250,0,151,0,179,255,250,0,151,0,180,255,250,0,151,0,181,255,250,0,151,0,183,255,250,0,151,0,184,255,251,0,151,0,185,255,251,0,151,0,186,255,251,0,151,0,187,255,251,0,151,0,189,255,249,0,151,0,193,255,249,0,151,0,195,255,250,0,151,0,197,255,250,0,151,0,198,255,230,0,151,0,199,255,238,0,151,0,200,255,250,0,151,0,210,255,247,0,151,0,211,255,242,0,151,0,213,255,247,0,151,0,214,255,242,0,151,0,218,255,242,0,151,0,240,255,246,0,152,0,10,255,245,0,152,0,13,255,243,0,152,0,15,255,243,0,152,0,16,255,234,0,152,0,34,255,240,0,152,0,46,255,248,0,152,0,59,255,251,0,152,0,66,255,242,0,152,0,67,255,245,0,152,0,68,255,243,0,152,0,69,255,243,0,152,0,70,255,243,0,152,0,71,255,250,0,152,0,72,255,242,0,152,0,73,255,245,0,152,0,74,255,243,0,152,0,75,255,243,0,152,0,76,255,245,0,152,0,77,255,244,0,152,0,78,255,240,0,152,0,79,255,240,0,152,0,80,255,243,0,152,0,81,255,240,0,152,0,82,255,243,0,152,0,83,255,240,0,152,0,84,255,243,0,152,0,85,255,249,0,152,0,86,255,242,0,152,0,87,255,250,0,152,0,88,255,250,0,152,0,89,255,250,0,152,0,90,255,250,0,152,0,91,255,244,0,152,0,127,255,240,0,152,0,128,255,240,0,152,0,129,255,240,0,152,0,130,255,240,0,152,0,131,255,240,0,152,0,132,255,240,0,152,0,133,255,240,0,152,0,158,255,248,0,152,0,159,255,242,0,152,0,160,255,242,0,152,0,161,255,242,0,152,0,162,255,242,0,152,0,163,255,242,0,152,0,164,255,242,0,152,0,165,255,242,0,152,0,166,255,243,0,152,0,167,255,243,0,152,0,168,255,243,0,152,0,169,255,243,0,152,0,170,255,243,0,152,0,171,255,243,0,152,0,172,255,243,0,152,0,173,255,251,0,152,0,174,255,243,0,152,0,175,255,242,0,152,0,176,255,240,0,152,0,177,255,243,0,152,0,178,255,243,0,152,0,179,255,243,0,152,0,180,255,243,0,152,0,181,255,243,0,152,0,183,255,243,0,152,0,184,255,242,0,152,0,185,255,242,0,152,0,186,255,242,0,152,0,187,255,242,0,152,0,188,255,250,0,152,0,189,255,240,0,152,0,190,255,250,0,152,0,193,255,243,0,152,0,195,255,243,0,152,0,197,255,243,0,152,0,199,255,251,0,152,0,200,255,244,0,152,0,211,255,243,0,152,0,214,255,243,0,152,0,218,255,243,0,153,0,10,255,245,0,153,0,13,255,243,0,153,0,15,255,243,0,153,0,16,255,234,0,153,0,34,255,240,0,153,0,46,255,248,0,153,0,59,255,251,0,153,0,66,255,242,0,153,0,67,255,245,0,153,0,68,255,243,0,153,0,69,255,243,0,153,0,70,255,243,0,153,0,71,255,250,0,153,0,72,255,242,0,153,0,73,255,245,0,153,0,74,255,243,0,153,0,75,255,243,0,153,0,76,255,245,0,153,0,77,255,244,0,153,0,78,255,240,0,153,0,79,255,240,0,153,0,80,255,243,0,153,0,81,255,240,0,153,0,82,255,243,0,153,0,83,255,240,0,153,0,84,255,243,0,153,0,85,255,249,0,153,0,86,255,242,0,153,0,87,255,250,0,153,0,88,255,250,0,153,0,89,255,250,0,153,0,90,255,250,0,153,0,91,255,244,0,153,0,127,255,240,0,153,0,128,255,240,0,153,0,129,255,240,0,153,0,130,255,240,0,153,0,131,255,240,0,153,0,132,255,240,0,153,0,133,255,240,0,153,0,158,255,248,0,153,0,159,255,242,0,153,0,160,255,242,0,153,0,161,255,242,0,153,0,162,255,242,0,153,0,163,255,242,0,153,0,164,255,242,0,153,0,165,255,242,0,153,0,166,255,243,0,153,0,167,255,243,0,153,0,168,255,243,0,153,0,169,255,243,0,153,0,170,255,243,0,153,0,171,255,243,0,153,0,172,255,243,0,153,0,173,255,251,0,153,0,174,255,243,0,153,0,175,255,242,0,153,0,176,255,240,0,153,0,177,255,243,0,153,0,178,255,243,0,153,0,179,255,243,0,153,0,180,255,243,0,153,0,181,255,243,0,153,0,183,255,243,0,153,0,184,255,242,0,153,0,185,255,242,0,153,0,186,255,242,0,153,0,187,255,242,0,153,0,188,255,250,0,153,0,189,255,240,0,153,0,190,255,250,0,153,0,193,255,243,0,153,0,195,255,243,0,153,0,197,255,243,0,153,0,199,255,251,0,153,0,200,255,244,0,153,0,211,255,243,0,153,0,214,255,243,0,153,0,218,255,243,0,154,0,10,255,245,0,154,0,13,255,243,0,154,0,15,255,243,0,154,0,16,255,234,0,154,0,34,255,240,0,154,0,46,255,248,0,154,0,59,255,251,0,154,0,66,255,242,0,154,0,67,255,245,0,154,0,68,255,243,0,154,0,69,255,243,0,154,0,70,255,243,0,154,0,71,255,250,0,154,0,72,255,242,0,154,0,73,255,245,0,154,0,74,255,243,0,154,0,75,255,243,0,154,0,76,255,245,0,154,0,77,255,244,0,154,0,78,255,240,0,154,0,79,255,240,0,154,0,80,255,243,0,154,0,81,255,240,0,154,0,82,255,243,0,154,0,83,255,240,0,154,0,84,255,243,0,154,0,85,255,249,0,154,0,86,255,242,0,154,0,87,255,250,0,154,0,88,255,250,0,154,0,89,255,250,0,154,0,90,255,250,0,154,0,91,255,244,0,154,0,127,255,240,0,154,0,128,255,240,0,154,0,129,255,240,0,154,0,130,255,240,0,154,0,131,255,240,0,154,0,132,255,240,0,154,0,133,255,240,0,154,0,158,255,248,0,154,0,159,255,242,0,154,0,160,255,242,0,154,0,161,255,242,0,154,0,162,255,242,0,154,0,163,255,242,0,154,0,164,255,242,0,154,0,165,255,242,0,154,0,166,255,243,0,154,0,167,255,243,0,154,0,168,255,243,0,154,0,169,255,243,0,154,0,170,255,243,0,154,0,171,255,243,0,154,0,172,255,243,0,154,0,173,255,251,0,154,0,174,255,243,0,154,0,175,255,242,0,154,0,176,255,240,0,154,0,177,255,243,0,154,0,178,255,243,0,154,0,179,255,243,0,154,0,180,255,243,0,154,0,181,255,243,0,154,0,183,255,243,0,154,0,184,255,242,0,154,0,185,255,242,0,154,0,186,255,242,0,154,0,187,255,242,0,154,0,188,255,250,0,154,0,189,255,240,0,154,0,190,255,250,0,154,0,193,255,243,0,154,0,195,255,243,0,154,0,197,255,243,0,154,0,199,255,251,0,154,0,200,255,244,0,154,0,211,255,243,0,154,0,214,255,243,0,154,0,218,255,243,0,155,0,10,255,245,0,155,0,13,255,243,0,155,0,15,255,243,0,155,0,16,255,234,0,155,0,34,255,240,0,155,0,46,255,248,0,155,0,59,255,251,0,155,0,66,255,242,0,155,0,67,255,245,0,155,0,68,255,243,0,155,0,69,255,243,0,155,0,70,255,243,0,155,0,71,255,250,0,155,0,72,255,242,0,155,0,73,255,245,0,155,0,74,255,243,0,155,0,75,255,243,0,155,0,76,255,245,0,155,0,77,255,244,0,155,0,78,255,240,0,155,0,79,255,240,0,155,0,80,255,243,0,155,0,81,255,240,0,155,0,82,255,243,0,155,0,83,255,240,0,155,0,84,255,243,0,155,0,85,255,249,0,155,0,86,255,242,0,155,0,87,255,250,0,155,0,88,255,250,0,155,0,89,255,250,0,155,0,90,255,250,0,155,0,91,255,244,0,155,0,127,255,240,0,155,0,128,255,240,0,155,0,129,255,240,0,155,0,130,255,240,0,155,0,131,255,240,0,155,0,132,255,240,0,155,0,133,255,240,0,155,0,158,255,248,0,155,0,159,255,242,0,155,0,160,255,242,0,155,0,161,255,242,0,155,0,162,255,242,0,155,0,163,255,242,0,155,0,164,255,242,0,155,0,165,255,242,0,155,0,166,255,243,0,155,0,167,255,243,0,155,0,168,255,243,0,155,0,169,255,243,0,155,0,170,255,243,0,155,0,171,255,243,0,155,0,172,255,243,0,155,0,173,255,251,0,155,0,174,255,243,0,155,0,175,255,242,0,155,0,176,255,240,0,155,0,177,255,243,0,155,0,178,255,243,0,155,0,179,255,243,0,155,0,180,255,243,0,155,0,181,255,243,0,155,0,183,255,243,0,155,0,184,255,242,0,155,0,185,255,242,0,155,0,186,255,242,0,155,0,187,255,242,0,155,0,188,255,250,0,155,0,189,255,240,0,155,0,190,255,250,0,155,0,193,255,243,0,155,0,195,255,243,0,155,0,197,255,243,0,155,0,199,255,251,0,155,0,200,255,244,0,155,0,211,255,243,0,155,0,214,255,243,0,155,0,218,255,243,0,156,0,7,255,237,0,156,0,11,0,13,0,156,0,13,255,215,0,156,0,14,255,222,0,156,0,15,255,215,0,156,0,16,255,201,0,156,0,17,255,233,0,156,0,21,255,206,0,156,0,23,255,218,0,156,0,25,255,246,0,156,0,27,255,235,0,156,0,28,255,235,0,156,0,32,0,13,0,156,0,33,255,198,0,156,0,34,255,192,0,156,0,36,255,230,0,156,0,40,255,230,0,156,0,46,255,232,0,156,0,48,255,230,0,156,0,50,255,230,0,156,0,61,0,7,0,156,0,62,0,31,0,156,0,66,255,189,0,156,0,68,255,171,0,156,0,69,255,171,0,156,0,70,255,171,0,156,0,71,255,237,0,156,0,72,255,180,0,156,0,78,255,187,0,156,0,79,255,187,0,156,0,80,255,171,0,156,0,81,255,187,0,156,0,82,255,171,0,156,0,83,255,187,0,156,0,84,255,186,0,156,0,85,255,221,0,156,0,86,255,190,0,156,0,87,255,215,0,156,0,88,255,216,0,156,0,89,255,214,0,156,0,90,255,217,0,156,0,91,255,229,0,156,0,94,0,33,0,156,0,107,255,198,0,156,0,110,255,230,0,156,0,122,255,225,0,156,0,127,255,192,0,156,0,128,255,192,0,156,0,129,255,192,0,156,0,130,255,192,0,156,0,131,255,192,0,156,0,132,255,192,0,156,0,133,255,180,0,156,0,134,255,230,0,156,0,145,255,230,0,156,0,146,255,230,0,156,0,147,255,230,0,156,0,148,255,230,0,156,0,149,255,230,0,156,0,151,255,230,0,156,0,158,255,230,0,156,0,159,255,189,0,156,0,160,255,189,0,156,0,161,255,189,0,156,0,162,255,189,0,156,0,163,255,189,0,156,0,164,255,189,0,156,0,165,255,189,0,156,0,166,255,171,0,156,0,167,255,171,0,156,0,168,255,171,0,156,0,169,255,171,0,156,0,170,255,171,0,156,0,171,0,16,0,156,0,173,0,38,0,156,0,174,0,47,0,156,0,175,255,216,0,156,0,176,255,187,0,156,0,177,255,171,0,156,0,178,255,171,0,156,0,179,255,171,0,156,0,180,255,171,0,156,0,181,255,171,0,156,0,183,255,171,0,156,0,184,255,190,0,156,0,185,255,190,0,156,0,186,255,190,0,156,0,187,255,190,0,156,0,188,255,217,0,156,0,189,255,225,0,156,0,190,255,217,0,156,0,194,255,230,0,156,0,195,255,171,0,156,0,197,255,234,0,156,0,200,255,229,0,156,0,207,255,222,0,156,0,208,255,222,0,156,0,211,255,215,0,156,0,214,255,215,0,156,0,218,255,215,0,156,0,220,255,198,0,156,0,221,255,225,0,156,0,240,0,33,0,157,0,10,255,228,0,157,0,13,255,177,0,157,0,15,255,177,0,157,0,16,255,221,0,157,0,32,255,223,0,157,0,34,255,235,0,157,0,46,255,251,0,157,0,53,255,202,0,157,0,55,255,248,0,157,0,57,255,205,0,157,0,58,255,228,0,157,0,59,255,203,0,157,0,61,255,247,0,157,0,62,255,214,0,157,0,66,255,247,0,157,0,89,255,250,0,157,0,94,255,226,0,157,0,127,255,235,0,157,0,128,255,235,0,157,0,129,255,235,0,157,0,130,255,235,0,157,0,131,255,235,0,157,0,132,255,235,0,157,0,133,255,201,0,157,0,156,255,228,0,157,0,159,255,247,0,157,0,160,255,247,0,157,0,161,255,247,0,157,0,162,255,247,0,157,0,163,255,247,0,157,0,164,255,247,0,157,0,165,255,247,0,157,0,198,255,228,0,157,0,199,255,203,0,157,0,211,255,177,0,157,0,214,255,177,0,157,0,218,255,177,0,158,0,3,255,243,0,158,0,8,255,243,0,158,0,10,255,239,0,158,0,11,255,241,0,158,0,71,255,250,0,158,0,85,255,247,0,158,0,87,255,245,0,158,0,88,255,248,0,158,0,89,255,251,0,158,0,90,255,245,0,158,0,188,255,245,0,158,0,190,255,245,0,158,0,209,255,245,0,158,0,210,255,243,0,158,0,212,255,245,0,158,0,213,255,243,0,158,0,240,255,242,0,159,0,3,255,234,0,159,0,7,255,245,0,159,0,8,255,234,0,159,0,10,255,246,0,159,0,11,255,231,0,159,0,18,255,234,0,159,0,26,255,247,0,159,0,32,255,229,0,159,0,35,255,240,0,159,0,36,255,237,0,159,0,37,255,240,0,159,0,38,255,240,0,159,0,39,255,240,0,159,0,40,255,237,0,159,0,41,255,240,0,159,0,42,255,240,0,159,0,43,255,240,0,159,0,44,255,240,0,159,0,45,255,240,0,159,0,46,255,248,0,159,0,47,255,240,0,159,0,48,255,237,0,159,0,49,255,240,0,159,0,50,255,237,0,159,0,51,255,240,0,159,0,52,255,250,0,159,0,53,255,173,0,159,0,54,255,227,0,159,0,55,255,193,0,159,0,56,255,210,0,159,0,58,255,165,0,159,0,61,255,210,0,159,0,62,255,227,0,159,0,71,255,251,0,159,0,85,255,246,0,159,0,87,255,238,0,159,0,88,255,243,0,159,0,90,255,236,0,159,0,94,255,231,0,159,0,110,255,248,0,159,0,134,255,237,0,159,0,135,255,240,0,159,0,136,255,240,0,159,0,137,255,240,0,159,0,138,255,240,0,159,0,139,255,240,0,159,0,140,255,240,0,159,0,141,255,240,0,159,0,142,255,240,0,159,0,143,255,240,0,159,0,144,255,240,0,159,0,145,255,237,0,159,0,146,255,237,0,159,0,147,255,237,0,159,0,148,255,237,0,159,0,149,255,237,0,159,0,151,255,237,0,159,0,152,255,227,0,159,0,153,255,227,0,159,0,154,255,227,0,159,0,155,255,227,0,159,0,156,255,165,0,159,0,157,255,240,0,159,0,158,255,249,0,159,0,188,255,236,0,159,0,190,255,236,0,159,0,194,255,237,0,159,0,196,255,250,0,159,0,198,255,165,0,159,0,209,255,186,0,159,0,210,255,183,0,159,0,212,255,186,0,159,0,213,255,183,0,159,0,240,255,230,0,160,0,3,255,234,0,160,0,7,255,245,0,160,0,8,255,234,0,160,0,10,255,246,0,160,0,11,255,231,0,160,0,18,255,234,0,160,0,26,255,247,0,160,0,32,255,229,0,160,0,35,255,240,0,160,0,36,255,237,0,160,0,37,255,240,0,160,0,38,255,240,0,160,0,39,255,240,0,160,0,40,255,237,0,160,0,41,255,240,0,160,0,42,255,240,0,160,0,43,255,240,0,160,0,44,255,240,0,160,0,45,255,240,0,160,0,46,255,248,0,160,0,47,255,240,0,160,0,48,255,237,0,160,0,49,255,240,0,160,0,50,255,237,0,160,0,51,255,240,0,160,0,52,255,250,0,160,0,53,255,173,0,160,0,54,255,227,0,160,0,55,255,193,0,160,0,56,255,210,0,160,0,58,255,165,0,160,0,61,255,210,0,160,0,62,255,227,0,160,0,71,255,251,0,160,0,85,255,246,0,160,0,87,255,238,0,160,0,88,255,243,0,160,0,90,255,236,0,160,0,94,255,231,0,160,0,110,255,248,0,160,0,134,255,237,0,160,0,135,255,240,0,160,0,136,255,240,0,160,0,137,255,240,0,160,0,138,255,240,0,160,0,139,255,240,0,160,0,140,255,240,0,160,0,141,255,240,0,160,0,142,255,240,0,160,0,143,255,240,0,160,0,144,255,240,0,160,0,145,255,237,0,160,0,146,255,237,0,160,0,147,255,237,0,160,0,148,255,237,0,160,0,149,255,237,0,160,0,151,255,237,0,160,0,152,255,227,0,160,0,153,255,227,0,160,0,154,255,227,0,160,0,155,255,227,0,160,0,156,255,165,0,160,0,157,255,240,0,160,0,158,255,249,0,160,0,188,255,236,0,160,0,190,255,236,0,160,0,194,255,237,0,160,0,196,255,250,0,160,0,198,255,165,0,160,0,209,255,186,0,160,0,210,255,183,0,160,0,212,255,186,0,160,0,213,255,183,0,160,0,240,255,230,0,161,0,3,255,234,0,161,0,7,255,245,0,161,0,8,255,234,0,161,0,10,255,246,0,161,0,11,255,231,0,161,0,18,255,234,0,161,0,26,255,247,0,161,0,32,255,229,0,161,0,35,255,240,0,161,0,36,255,237,0,161,0,37,255,240,0,161,0,38,255,240,0,161,0,39,255,240,0,161,0,40,255,237,0,161,0,41,255,240,0,161,0,42,255,240,0,161,0,43,255,240,0,161,0,44,255,240,0,161,0,45,255,240,0,161,0,46,255,248,0,161,0,47,255,240,0,161,0,48,255,237,0,161,0,49,255,240,0,161,0,50,255,237,0,161,0,51,255,240,0,161,0,52,255,250,0,161,0,53,255,173,0,161,0,54,255,227,0,161,0,55,255,193,0,161,0,56,255,210,0,161,0,58,255,165,0,161,0,61,255,210,0,161,0,62,255,246,0,161,0,71,255,251,0,161,0,85,255,246,0,161,0,87,255,238,0,161,0,88,255,243,0,161,0,90,255,236,0,161,0,94,255,248,0,161,0,110,255,248,0,161,0,134,255,237,0,161,0,135,255,240,0,161,0,136,255,240,0,161,0,137,255,240,0,161,0,138,255,240,0,161,0,139,255,240,0,161,0,140,255,240,0,161,0,141,255,240,0,161,0,142,255,240,0,161,0,143,255,240,0,161,0,144,255,240,0,161,0,145,255,237,0,161,0,146,255,237,0,161,0,147,255,237,0,161,0,148,255,237,0,161,0,149,255,237,0,161,0,151,255,237,0,161,0,152,255,227,0,161,0,153,255,227,0,161,0,154,255,227,0,161,0,155,255,227,0,161,0,156,255,165,0,161,0,157,255,240,0,161,0,158,255,249,0,161,0,188,255,236,0,161,0,190,255,236,0,161,0,194,255,237,0,161,0,196,255,250,0,161,0,198,255,165,0,161,0,209,255,186,0,161,0,210,255,183,0,161,0,212,255,186,0,161,0,213,255,183,0,161,0,240,255,230,0,162,0,3,255,234,0,162,0,7,255,245,0,162,0,8,255,234,0,162,0,10,255,246,0,162,0,11,255,231,0,162,0,18,255,234,0,162,0,26,255,247,0,162,0,32,255,229,0,162,0,35,255,240,0,162,0,36,255,237,0,162,0,37,255,240,0,162,0,38,255,240,0,162,0,39,255,240,0,162,0,40,255,237,0,162,0,41,255,240,0,162,0,42,255,240,0,162,0,43,255,240,0,162,0,44,255,240,0,162,0,45,255,240,0,162,0,46,255,248,0,162,0,47,255,240,0,162,0,48,255,237,0,162,0,49,255,240,0,162,0,50,255,237,0,162,0,51,255,240,0,162,0,52,255,250,0,162,0,53,255,173,0,162,0,54,255,227,0,162,0,55,255,193,0,162,0,56,255,210,0,162,0,58,255,165,0,162,0,61,255,220,0,162,0,62,255,227,0,162,0,71,255,251,0,162,0,85,255,246,0,162,0,87,255,238,0,162,0,88,255,243,0,162,0,90,255,236,0,162,0,94,255,248,0,162,0,110,255,248,0,162,0,134,255,237,0,162,0,135,255,240,0,162,0,136,255,240,0,162,0,137,255,240,0,162,0,138,255,240,0,162,0,139,255,240,0,162,0,140,255,240,0,162,0,141,255,240,0,162,0,142,255,240,0,162,0,143,255,240,0,162,0,144,255,240,0,162,0,145,255,237,0,162,0,146,255,237,0,162,0,147,255,237,0,162,0,148,255,237,0,162,0,149,255,237,0,162,0,151,255,237,0,162,0,152,255,227,0,162,0,153,255,227,0,162,0,154,255,227,0,162,0,155,255,227,0,162,0,156,255,165,0,162,0,157,255,240,0,162,0,158,255,249,0,162,0,188,255,236,0,162,0,190,255,236,0,162,0,194,255,237,0,162,0,196,255,250,0,162,0,198,255,165,0,162,0,209,255,186,0,162,0,210,255,195,0,162,0,212,255,186,0,162,0,213,255,195,0,162,0,240,255,230,0,163,0,3,255,234,0,163,0,7,255,245,0,163,0,8,255,234,0,163,0,10,255,246,0,163,0,11,255,231,0,163,0,18,255,234,0,163,0,26,255,247,0,163,0,32,255,229,0,163,0,35,255,240,0,163,0,36,255,237,0,163,0,37,255,240,0,163,0,38,255,240,0,163,0,39,255,240,0,163,0,40,255,237,0,163,0,41,255,240,0,163,0,42,255,240,0,163,0,43,255,240,0,163,0,44,255,240,0,163,0,45,255,240,0,163,0,46,255,248,0,163,0,47,255,240,0,163,0,48,255,237,0,163,0,49,255,240,0,163,0,50,255,237,0,163,0,51,255,240,0,163,0,52,255,250,0,163,0,53,255,173,0,163,0,54,255,227,0,163,0,55,255,193,0,163,0,56,255,210,0,163,0,58,255,165,0,163,0,61,255,210,0,163,0,62,255,245,0,163,0,71,255,251,0,163,0,85,255,246,0,163,0,87,255,238,0,163,0,88,255,243,0,163,0,90,255,236,0,163,0,94,255,248,0,163,0,110,255,248,0,163,0,134,255,237,0,163,0,135,255,240,0,163,0,136,255,240,0,163,0,137,255,240,0,163,0,138,255,240,0,163,0,139,255,240,0,163,0,140,255,240,0,163,0,141,255,240,0,163,0,142,255,240,0,163,0,143,255,240,0,163,0,144,255,240,0,163,0,145,255,237,0,163,0,146,255,237,0,163,0,147,255,237,0,163,0,148,255,237,0,163,0,149,255,237,0,163,0,151,255,237,0,163,0,152,255,227,0,163,0,153,255,227,0,163,0,154,255,227,0,163,0,155,255,227,0,163,0,156,255,165,0,163,0,157,255,240,0,163,0,158,255,249,0,163,0,188,255,236,0,163,0,190,255,236,0,163,0,194,255,237,0,163,0,196,255,250,0,163,0,198,255,165,0,163,0,209,255,186,0,163,0,210,255,183,0,163,0,212,255,186,0,163,0,213,255,183,0,163,0,240,255,230,0,164,0,3,255,234,0,164,0,7,255,245,0,164,0,8,255,234,0,164,0,10,255,246,0,164,0,11,255,231,0,164,0,18,255,234,0,164,0,26,255,247,0,164,0,32,255,229,0,164,0,35,255,240,0,164,0,36,255,237,0,164,0,37,255,240,0,164,0,38,255,240,0,164,0,39,255,240,0,164,0,40,255,237,0,164,0,41,255,240,0,164,0,42,255,240,0,164,0,43,255,240,0,164,0,44,255,240,0,164,0,45,255,240,0,164,0,46,255,248,0,164,0,47,255,240,0,164,0,48,255,237,0,164,0,49,255,240,0,164,0,50,255,237,0,164,0,51,255,240,0,164,0,52,255,250,0,164,0,53,255,173,0,164,0,54,255,227,0,164,0,55,255,193,0,164,0,56,255,210,0,164,0,58,255,165,0,164,0,61,255,210,0,164,0,62,255,227,0,164,0,71,255,251,0,164,0,85,255,246,0,164,0,87,255,238,0,164,0,88,255,243,0,164,0,90,255,236,0,164,0,94,255,231,0,164,0,110,255,248,0,164,0,134,255,237,0,164,0,135,255,240,0,164,0,136,255,240,0,164,0,137,255,240,0,164,0,138,255,240,0,164,0,139,255,240,0,164,0,140,255,240,0,164,0,141,255,240,0,164,0,142,255,240,0,164,0,143,255,240,0,164,0,144,255,240,0,164,0,145,255,237,0,164,0,146,255,237,0,164,0,147,255,237,0,164,0,148,255,237,0,164,0,149,255,237,0,164,0,151,255,237,0,164,0,152,255,227,0,164,0,153,255,227,0,164,0,154,255,227,0,164,0,155,255,227,0,164,0,156,255,165,0,164,0,157,255,240,0,164,0,158,255,249,0,164,0,188,255,236,0,164,0,190,255,236,0,164,0,194,255,237,0,164,0,196,255,250,0,164,0,198,255,165,0,164,0,209,255,186,0,164,0,210,255,183,0,164,0,212,255,186,0,164,0,213,255,183,0,164,0,240,255,230,0,165,0,3,255,241,0,165,0,7,255,246,0,165,0,8,255,241,0,165,0,10,255,230,0,165,0,11,255,238,0,165,0,18,255,235,0,165,0,19,255,245,0,165,0,24,255,230,0,165,0,32,255,223,0,165,0,34,255,251,0,165,0,35,255,241,0,165,0,36,255,250,0,165,0,37,255,241,0,165,0,38,255,241,0,165,0,39,255,241,0,165,0,40,255,250,0,165,0,41,255,241,0,165,0,42,255,241,0,165,0,43,255,241,0,165,0,44,255,241,0,165,0,45,255,241,0,165,0,46,255,243,0,165,0,47,255,241,0,165,0,48,255,250,0,165,0,49,255,241,0,165,0,50,255,250,0,165,0,51,255,241,0,165,0,52,255,241,0,165,0,53,255,187,0,165,0,54,255,240,0,165,0,55,255,209,0,165,0,56,255,213,0,165,0,57,255,243,0,165,0,58,255,174,0,165,0,59,255,243,0,165,0,61,255,220,0,165,0,62,255,220,0,165,0,87,255,252,0,165,0,89,255,251,0,165,0,90,255,251,0,165,0,94,255,227,0,165,0,127,255,251,0,165,0,128,255,251,0,165,0,129,255,251,0,165,0,130,255,251,0,165,0,131,255,251,0,165,0,132,255,251,0,165,0,134,255,250,0,165,0,135,255,241,0,165,0,136,255,241,0,165,0,137,255,241,0,165,0,138,255,241,0,165,0,139,255,241,0,165,0,140,255,241,0,165,0,141,255,241,0,165,0,142,255,241,0,165,0,143,255,241,0,165,0,144,255,241,0,165,0,145,255,250,0,165,0,146,255,250,0,165,0,147,255,250,0,165,0,148,255,250,0,165,0,149,255,250,0,165,0,151,255,250,0,165,0,152,255,240,0,165,0,153,255,240,0,165,0,154,255,240,0,165,0,155,255,240,0,165,0,156,255,174,0,165,0,157,255,241,0,165,0,188,255,251,0,165,0,190,255,251,0,165,0,194,255,250,0,165,0,196,255,241,0,165,0,198,255,174,0,165,0,199,255,243,0,165,0,209,255,189,0,165,0,210,255,186,0,165,0,212,255,189,0,165,0,213,255,186,0,165,0,240,255,237,0,166,0,7,255,240,0,166,0,10,255,244,0,166,0,14,255,219,0,166,0,21,255,231,0,166,0,24,255,245,0,166,0,32,255,228,0,166,0,35,255,247,0,166,0,36,255,244,0,166,0,37,255,247,0,166,0,38,255,247,0,166,0,39,255,247,0,166,0,40,255,244,0,166,0,41,255,247,0,166,0,42,255,247,0,166,0,43,255,247,0,166,0,44,255,247,0,166,0,45,255,247,0,166,0,46,255,251,0,166,0,47,255,247,0,166,0,48,255,244,0,166,0,49,255,247,0,166,0,50,255,244,0,166,0,51,255,247,0,166,0,52,255,244,0,166,0,53,255,190,0,166,0,54,255,243,0,166,0,55,255,236,0,166,0,56,255,241,0,166,0,58,255,218,0,166,0,61,255,240,0,166,0,62,255,232,0,166,0,68,255,249,0,166,0,69,255,249,0,166,0,70,255,249,0,166,0,80,255,249,0,166,0,82,255,249,0,166,0,94,255,239,0,166,0,107,255,243,0,166,0,134,255,244,0,166,0,135,255,247,0,166,0,136,255,247,0,166,0,137,255,247,0,166,0,138,255,247,0,166,0,139,255,247,0,166,0,140,255,247,0,166,0,141,255,247,0,166,0,142,255,247,0,166,0,143,255,247,0,166,0,144,255,247,0,166,0,145,255,244,0,166,0,146,255,244,0,166,0,147,255,244,0,166,0,148,255,244,0,166,0,149,255,244,0,166,0,151,255,244,0,166,0,152,255,243,0,166,0,153,255,243,0,166,0,154,255,243,0,166,0,155,255,243,0,166,0,156,255,218,0,166,0,157,255,247,0,166,0,166,255,249,0,166,0,167,255,249,0,166,0,168,255,249,0,166,0,169,255,249,0,166,0,170,255,249,0,166,0,175,255,251,0,166,0,177,255,249,0,166,0,178,255,249,0,166,0,179,255,249,0,166,0,180,255,249,0,166,0,181,255,249,0,166,0,183,255,249,0,166,0,194,255,244,0,166,0,195,255,249,0,166,0,196,255,244,0,166,0,198,255,218,0,166,0,207,255,219,0,166,0,208,255,219,0,166,0,209,255,216,0,166,0,210,255,213,0,166,0,212,255,216,0,166,0,213,255,213,0,166,0,220,255,243,0,166,0,240,255,245,0,167,0,3,255,241,0,167,0,7,255,246,0,167,0,8,255,241,0,167,0,10,255,230,0,167,0,11,255,238,0,167,0,18,255,235,0,167,0,19,255,245,0,167,0,24,255,230,0,167,0,32,255,223,0,167,0,34,255,251,0,167,0,35,255,241,0,167,0,36,255,250,0,167,0,37,255,241,0,167,0,38,255,241,0,167,0,39,255,241,0,167,0,40,255,250,0,167,0,41,255,241,0,167,0,42,255,241,0,167,0,43,255,241,0,167,0,44,255,241,0,167,0,45,255,241,0,167,0,46,255,243,0,167,0,47,255,241,0,167,0,48,255,250,0,167,0,49,255,241,0,167,0,50,255,250,0,167,0,51,255,241,0,167,0,52,255,241,0,167,0,53,255,187,0,167,0,54,255,240,0,167,0,55,255,209,0,167,0,56,255,213,0,167,0,57,255,243,0,167,0,58,255,174,0,167,0,59,255,243,0,167,0,61,255,220,0,167,0,62,255,220,0,167,0,87,255,252,0,167,0,89,255,251,0,167,0,90,255,251,0,167,0,94,255,227,0,167,0,127,255,251,0,167,0,128,255,251,0,167,0,129,255,251,0,167,0,130,255,251,0,167,0,131,255,251,0,167,0,132,255,251,0,167,0,134,255,250,0,167,0,135,255,241,0,167,0,136,255,241,0,167,0,137,255,241,0,167,0,138,255,241,0,167,0,139,255,241,0,167,0,140,255,241,0,167,0,141,255,241,0,167,0,142,255,241,0,167,0,143,255,241,0,167,0,144,255,241,0,167,0,145,255,250,0,167,0,146,255,250,0,167,0,147,255,250,0,167,0,148,255,250,0,167,0,149,255,250,0,167,0,151,255,250,0,167,0,152,255,240,0,167,0,153,255,240,0,167,0,154,255,240,0,167,0,155,255,240,0,167,0,156,255,174,0,167,0,157,255,241,0,167,0,188,255,251,0,167,0,190,255,251,0,167,0,194,255,250,0,167,0,196,255,241,0,167,0,198,255,174,0,167,0,199,255,243,0,167,0,209,255,189,0,167,0,210,255,186,0,167,0,212,255,189,0,167,0,213,255,186,0,167,0,240,255,237,0,168,0,3,255,241,0,168,0,7,255,246,0,168,0,8,255,241,0,168,0,10,255,230,0,168,0,11,255,238,0,168,0,18,255,235,0,168,0,19,255,245,0,168,0,24,255,230,0,168,0,32,255,223,0,168,0,34,255,251,0,168,0,35,255,241,0,168,0,36,255,250,0,168,0,37,255,241,0,168,0,38,255,241,0,168,0,39,255,241,0,168,0,40,255,250,0,168,0,41,255,241,0,168,0,42,255,241,0,168,0,43,255,241,0,168,0,44,255,241,0,168,0,45,255,241,0,168,0,46,255,243,0,168,0,47,255,241,0,168,0,48,255,250,0,168,0,49,255,241,0,168,0,50,255,250,0,168,0,51,255,241,0,168,0,52,255,241,0,168,0,53,255,187,0,168,0,54,255,240,0,168,0,55,255,209,0,168,0,56,255,213,0,168,0,57,255,243,0,168,0,58,255,174,0,168,0,59,255,243,0,168,0,61,255,220,0,168,0,62,255,220,0,168,0,87,255,252,0,168,0,89,255,251,0,168,0,90,255,251,0,168,0,94,255,227,0,168,0,127,255,251,0,168,0,128,255,251,0,168,0,129,255,251,0,168,0,130,255,251,0,168,0,131,255,251,0,168,0,132,255,251,0,168,0,134,255,250,0,168,0,135,255,241,0,168,0,136,255,241,0,168,0,137,255,241,0,168,0,138,255,241,0,168,0,139,255,241,0,168,0,140,255,241,0,168,0,141,255,241,0,168,0,142,255,241,0,168,0,143,255,241,0,168,0,144,255,241,0,168,0,145,255,250,0,168,0,146,255,250,0,168,0,147,255,250,0,168,0,148,255,250,0,168,0,149,255,250,0,168,0,151,255,250,0,168,0,152,255,240,0,168,0,153,255,240,0,168,0,154,255,240,0,168,0,155,255,240,0,168,0,156,255,174,0,168,0,157,255,241,0,168,0,188,255,251,0,168,0,190,255,251,0,168,0,194,255,250,0,168,0,196,255,241,0,168,0,198,255,174,0,168,0,199,255,243,0,168,0,209,255,189,0,168,0,210,255,186,0,168,0,212,255,189,0,168,0,213,255,186,0,168,0,240,255,237,0,169,0,3,255,241,0,169,0,7,255,246,0,169,0,8,255,241,0,169,0,10,255,230,0,169,0,11,255,238,0,169,0,18,255,235,0,169,0,19,255,245,0,169,0,24,255,230,0,169,0,32,255,223,0,169,0,34,255,251,0,169,0,35,255,241,0,169,0,36,255,250,0,169,0,37,255,241,0,169,0,38,255,241,0,169,0,39,255,241,0,169,0,40,255,250,0,169,0,41,255,241,0,169,0,42,255,241,0,169,0,43,255,241,0,169,0,44,255,241,0,169,0,45,255,241,0,169,0,46,255,243,0,169,0,47,255,241,0,169,0,48,255,250,0,169,0,49,255,241,0,169,0,50,255,250,0,169,0,51,255,241,0,169,0,52,255,241,0,169,0,53,255,187,0,169,0,54,255,240,0,169,0,55,255,209,0,169,0,56,255,213,0,169,0,57,255,243,0,169,0,58,255,174,0,169,0,59,255,243,0,169,0,61,255,220,0,169,0,62,255,220,0,169,0,87,255,252,0,169,0,89,255,251,0,169,0,90,255,251,0,169,0,94,255,227,0,169,0,127,255,251,0,169,0,128,255,251,0,169,0,129,255,251,0,169,0,130,255,251,0,169,0,131,255,251,0,169,0,132,255,251,0,169,0,134,255,250,0,169,0,135,255,241,0,169,0,136,255,241,0,169,0,137,255,241,0,169,0,138,255,241,0,169,0,139,255,241,0,169,0,140,255,241,0,169,0,141,255,241,0,169,0,142,255,241,0,169,0,143,255,241,0,169,0,144,255,241,0,169,0,145,255,250,0,169,0,146,255,250,0,169,0,147,255,250,0,169,0,148,255,250,0,169,0,149,255,250,0,169,0,151,255,250,0,169,0,152,255,240,0,169,0,153,255,240,0,169,0,154,255,240,0,169,0,155,255,240,0,169,0,156,255,174,0,169,0,157,255,241,0,169,0,188,255,251,0,169,0,190,255,251,0,169,0,194,255,250,0,169,0,196,255,241,0,169,0,198,255,174,0,169,0,199,255,243,0,169,0,209,255,189,0,169,0,210,255,186,0,169,0,212,255,189,0,169,0,213,255,186,0,169,0,240,255,237,0,170,0,3,255,241,0,170,0,7,255,246,0,170,0,8,255,241,0,170,0,10,255,230,0,170,0,11,255,238,0,170,0,18,255,235,0,170,0,19,255,245,0,170,0,24,255,230,0,170,0,32,255,223,0,170,0,34,255,251,0,170,0,35,255,241,0,170,0,36,255,250,0,170,0,37,255,241,0,170,0,38,255,241,0,170,0,39,255,241,0,170,0,40,255,250,0,170,0,41,255,241,0,170,0,42,255,241,0,170,0,43,255,241,0,170,0,44,255,241,0,170,0,45,255,241,0,170,0,46,255,243,0,170,0,47,255,241,0,170,0,48,255,250,0,170,0,49,255,241,0,170,0,50,255,250,0,170,0,51,255,241,0,170,0,52,255,241,0,170,0,53,255,187,0,170,0,54,255,240,0,170,0,55,255,209,0,170,0,56,255,213,0,170,0,57,255,243,0,170,0,58,255,174,0,170,0,59,255,243,0,170,0,61,255,220,0,170,0,62,255,220,0,170,0,87,255,252,0,170,0,89,255,251,0,170,0,90,255,251,0,170,0,94,255,227,0,170,0,127,255,251,0,170,0,128,255,251,0,170,0,129,255,251,0,170,0,130,255,251,0,170,0,131,255,251,0,170,0,132,255,251,0,170,0,134,255,250,0,170,0,135,255,241,0,170,0,136,255,241,0,170,0,137,255,241,0,170,0,138,255,241,0,170,0,139,255,241,0,170,0,140,255,241,0,170,0,141,255,241,0,170,0,142,255,241,0,170,0,143,255,241,0,170,0,144,255,241,0,170,0,145,255,250,0,170,0,146,255,250,0,170,0,147,255,250,0,170,0,148,255,250,0,170,0,149,255,250,0,170,0,151,255,250,0,170,0,152,255,240,0,170,0,153,255,240,0,170,0,154,255,240,0,170,0,155,255,240,0,170,0,156,255,174,0,170,0,157,255,241,0,170,0,188,255,251,0,170,0,190,255,251,0,170,0,194,255,250,0,170,0,196,255,241,0,170,0,198,255,174,0,170,0,199,255,243,0,170,0,209,255,189,0,170,0,210,255,186,0,170,0,212,255,189,0,170,0,213,255,186,0,170,0,240,255,237,0,171,0,7,255,244,0,171,0,11,0,30,0,171,0,34,255,248,0,171,0,35,255,242,0,171,0,36,255,244,0,171,0,37,255,242,0,171,0,38,255,242,0,171,0,39,255,242,0,171,0,40,255,244,0,171,0,41,255,242,0,171,0,42,255,242,0,171,0,43,255,242,0,171,0,44,255,242,0,171,0,45,255,242,0,171,0,46,255,241,0,171,0,47,255,242,0,171,0,48,255,244,0,171,0,49,255,242,0,171,0,50,255,244,0,171,0,51,255,242,0,171,0,52,255,244,0,171,0,53,255,242,0,171,0,54,255,238,0,171,0,55,255,247,0,171,0,56,255,246,0,171,0,58,255,247,0,171,0,59,255,245,0,171,0,127,255,248,0,171,0,128,255,248,0,171,0,129,255,248,0,171,0,130,255,248,0,171,0,131,255,248,0,171,0,132,255,248,0,171,0,134,255,244,0,171,0,135,255,242,0,171,0,136,255,242,0,171,0,137,255,242,0,171,0,138,255,242,0,171,0,139,255,242,0,171,0,140,255,242,0,171,0,141,255,242,0,171,0,142,255,242,0,171,0,143,255,242,0,171,0,144,255,242,0,171,0,145,255,244,0,171,0,146,255,244,0,171,0,147,255,244,0,171,0,148,255,244,0,171,0,149,255,244,0,171,0,151,255,244,0,171,0,152,255,238,0,171,0,153,255,238,0,171,0,154,255,238,0,171,0,155,255,238,0,171,0,156,255,247,0,171,0,157,255,242,0,171,0,194,255,244,0,171,0,196,255,244,0,171,0,198,255,247,0,171,0,199,255,245,0,171,0,240,0,28,0,172,0,7,255,244,0,172,0,11,0,18,0,172,0,34,255,248,0,172,0,35,255,242,0,172,0,36,255,244,0,172,0,37,255,242,0,172,0,38,255,242,0,172,0,39,255,242,0,172,0,40,255,244,0,172,0,41,255,242,0,172,0,42,255,242,0,172,0,43,255,242,0,172,0,44,255,242,0,172,0,45,255,242,0,172,0,46,255,241,0,172,0,47,255,242,0,172,0,48,255,244,0,172,0,49,255,242,0,172,0,50,255,244,0,172,0,51,255,242,0,172,0,52,255,244,0,172,0,53,255,242,0,172,0,54,255,238,0,172,0,55,255,247,0,172,0,56,255,246,0,172,0,58,255,247,0,172,0,59,255,245,0,172,0,62,0,9,0,172,0,94,0,14,0,172,0,127,255,248,0,172,0,128,255,248,0,172,0,129,255,248,0,172,0,130,255,248,0,172,0,131,255,248,0,172,0,132,255,248,0,172,0,134,255,244,0,172,0,135,255,242,0,172,0,136,255,242,0,172,0,137,255,242,0,172,0,138,255,242,0,172,0,139,255,242,0,172,0,140,255,242,0,172,0,141,255,242,0,172,0,142,255,242,0,172,0,143,255,242,0,172,0,144,255,242,0,172,0,145,255,244,0,172,0,146,255,244,0,172,0,147,255,244,0,172,0,148,255,244,0,172,0,149,255,244,0,172,0,151,255,244,0,172,0,152,255,238,0,172,0,153,255,238,0,172,0,154,255,238,0,172,0,155,255,238,0,172,0,156,255,247,0,172,0,157,255,242,0,172,0,194,255,244,0,172,0,196,255,244,0,172,0,198,255,247,0,172,0,199,255,245,0,172,0,240,0,18,0,173,0,3,0,29,0,173,0,7,255,244,0,173,0,8,0,29,0,173,0,11,0,76,0,173,0,32,0,39,0,173,0,34,255,248,0,173,0,35,255,242,0,173,0,36,255,244,0,173,0,37,255,242,0,173,0,38,255,242,0,173,0,39,255,242,0,173,0,40,255,244,0,173,0,41,255,242,0,173,0,42,255,242,0,173,0,43,255,242,0,173,0,44,255,242,0,173,0,45,255,242,0,173,0,46,255,241,0,173,0,47,255,242,0,173,0,48,255,244,0,173,0,49,255,242,0,173,0,50,255,244,0,173,0,51,255,242,0,173,0,52,255,244,0,173,0,53,255,242,0,173,0,54,255,238,0,173,0,55,255,247,0,173,0,56,255,246,0,173,0,58,255,247,0,173,0,59,255,245,0,173,0,61,0,13,0,173,0,62,0,44,0,173,0,94,0,33,0,173,0,127,255,248,0,173,0,128,255,248,0,173,0,129,255,248,0,173,0,130,255,248,0,173,0,131,255,248,0,173,0,132,255,248,0,173,0,134,255,244,0,173,0,135,255,242,0,173,0,136,255,242,0,173,0,137,255,242,0,173,0,138,255,242,0,173,0,139,255,242,0,173,0,140,255,242,0,173,0,141,255,242,0,173,0,142,255,242,0,173,0,143,255,242,0,173,0,144,255,242,0,173,0,145,255,244,0,173,0,146,255,244,0,173,0,147,255,244,0,173,0,148,255,244,0,173,0,149,255,244,0,173,0,151,255,244,0,173,0,152,255,238,0,173,0,153,255,238,0,173,0,154,255,238,0,173,0,155,255,238,0,173,0,156,255,247,0,173,0,157,255,242,0,173,0,194,255,244,0,173,0,196,255,244,0,173,0,198,255,247,0,173,0,199,255,245,0,173,0,209,0,37,0,173,0,210,0,24,0,173,0,212,0,37,0,173,0,213,0,24,0,173,0,240,0,81,0,174,0,7,255,244,0,174,0,11,0,43,0,174,0,32,0,27,0,174,0,34,255,248,0,174,0,35,255,242,0,174,0,36,255,244,0,174,0,37,255,242,0,174,0,38,255,242,0,174,0,39,255,242,0,174,0,40,255,244,0,174,0,41,255,242,0,174,0,42,255,242,0,174,0,43,255,242,0,174,0,44,255,242,0,174,0,45,255,242,0,174,0,46,255,241,0,174,0,47,255,242,0,174,0,48,255,244,0,174,0,49,255,242,0,174,0,50,255,244,0,174,0,51,255,242,0,174,0,52,255,244,0,174,0,53,255,242,0,174,0,54,255,238,0,174,0,55,255,247,0,174,0,56,255,246,0,174,0,58,255,247,0,174,0,59,255,245,0,174,0,61,0,14,0,174,0,62,0,39,0,174,0,94,0,44,0,174,0,127,255,248,0,174,0,128,255,248,0,174,0,129,255,248,0,174,0,130,255,248,0,174,0,131,255,248,0,174,0,132,255,248,0,174,0,134,255,244,0,174,0,135,255,242,0,174,0,136,255,242,0,174,0,137,255,242,0,174,0,138,255,242,0,174,0,139,255,242,0,174,0,140,255,242,0,174,0,141,255,242,0,174,0,142,255,242,0,174,0,143,255,242,0,174,0,144,255,242,0,174,0,145,255,244,0,174,0,146,255,244,0,174,0,147,255,244,0,174,0,148,255,244,0,174,0,149,255,244,0,174,0,151,255,244,0,174,0,152,255,238,0,174,0,153,255,238,0,174,0,154,255,238,0,174,0,155,255,238,0,174,0,156,255,247,0,174,0,157,255,242,0,174,0,194,255,244,0,174,0,196,255,244,0,174,0,198,255,247,0,174,0,199,255,245,0,174,0,240,0,48,0,175,0,3,255,245,0,175,0,7,255,247,0,175,0,8,255,245,0,175,0,10,255,232,0,175,0,11,255,240,0,175,0,13,255,247,0,175,0,15,255,247,0,175,0,32,255,242,0,175,0,61,255,246,0,175,0,62,255,240,0,175,0,89,255,248,0,175,0,94,255,243,0,175,0,209,255,236,0,175,0,210,255,237,0,175,0,211,255,247,0,175,0,212,255,236,0,175,0,213,255,237,0,175,0,214,255,247,0,175,0,218,255,247,0,175,0,240,255,241,0,176,0,2,255,248,0,176,0,3,255,238,0,176,0,7,255,245,0,176,0,8,255,238,0,176,0,10,255,232,0,176,0,11,255,235,0,176,0,18,255,231,0,176,0,24,255,233,0,176,0,32,255,224,0,176,0,34,255,250,0,176,0,35,255,238,0,176,0,36,255,243,0,176,0,37,255,238,0,176,0,38,255,238,0,176,0,39,255,238,0,176,0,40,255,243,0,176,0,41,255,238,0,176,0,42,255,238,0,176,0,43,255,238,0,176,0,44,255,238,0,176,0,45,255,238,0,176,0,46,255,241,0,176,0,47,255,238,0,176,0,48,255,243,0,176,0,49,255,238,0,176,0,50,255,243,0,176,0,51,255,238,0,176,0,52,255,241,0,176,0,53,255,162,0,176,0,54,255,231,0,176,0,55,255,198,0,176,0,56,255,214,0,176,0,57,255,249,0,176,0,58,255,163,0,176,0,59,255,245,0,176,0,61,255,214,0,176,0,62,255,216,0,176,0,71,255,251,0,176,0,85,255,248,0,176,0,87,255,243,0,176,0,88,255,248,0,176,0,90,255,242,0,176,0,94,255,225,0,176,0,127,255,250,0,176,0,128,255,250,0,176,0,129,255,250,0,176,0,130,255,250,0,176,0,131,255,250,0,176,0,132,255,250,0,176,0,134,255,243,0,176,0,135,255,238,0,176,0,136,255,238,0,176,0,137,255,238,0,176,0,138,255,238,0,176,0,139,255,238,0,176,0,140,255,238,0,176,0,141,255,238,0,176,0,142,255,238,0,176,0,143,255,238,0,176,0,144,255,238,0,176,0,145,255,243,0,176,0,146,255,243,0,176,0,147,255,243,0,176,0,148,255,243,0,176,0,149,255,243,0,176,0,151,255,243,0,176,0,152,255,231,0,176,0,153,255,231,0,176,0,154,255,231,0,176,0,155,255,231,0,176,0,156,255,163,0,176,0,157,255,238,0,176,0,158,255,248,0,176,0,188,255,242,0,176,0,190,255,242,0,176,0,194,255,243,0,176,0,196,255,241,0,176,0,198,255,163,0,176,0,199,255,245,0,176,0,209,255,187,0,176,0,210,255,184,0,176,0,212,255,187,0,176,0,213,255,184,0,176,0,240,255,235,0,177,0,3,255,236,0,177,0,7,255,246,0,177,0,8,255,236,0,177,0,10,255,224,0,177,0,11,255,234,0,177,0,18,255,230,0,177,0,19,255,229,0,177,0,24,255,223,0,177,0,32,255,222,0,177,0,34,255,240,0,177,0,35,255,237,0,177,0,36,255,246,0,177,0,37,255,237,0,177,0,38,255,237,0,177,0,39,255,237,0,177,0,40,255,246,0,177,0,41,255,237,0,177,0,42,255,237,0,177,0,43,255,237,0,177,0,44,255,237,0,177,0,45,255,237,0,177,0,46,255,239,0,177,0,47,255,237,0,177,0,48,255,246,0,177,0,49,255,237,0,177,0,50,255,246,0,177,0,51,255,237,0,177,0,52,255,238,0,177,0,53,255,173,0,177,0,54,255,238,0,177,0,55,255,192,0,177,0,56,255,212,0,177,0,57,255,218,0,177,0,58,255,167,0,177,0,59,255,227,0,177,0,61,255,214,0,177,0,62,255,213,0,177,0,71,255,251,0,177,0,85,255,249,0,177,0,87,255,247,0,177,0,88,255,251,0,177,0,89,255,237,0,177,0,90,255,245,0,177,0,91,255,246,0,177,0,94,255,222,0,177,0,122,255,247,0,177,0,127,255,240,0,177,0,128,255,240,0,177,0,129,255,240,0,177,0,130,255,240,0,177,0,131,255,240,0,177,0,132,255,240,0,177,0,134,255,246,0,177,0,135,255,237,0,177,0,136,255,237,0,177,0,137,255,237,0,177,0,138,255,237,0,177,0,139,255,237,0,177,0,140,255,237,0,177,0,141,255,237,0,177,0,142,255,237,0,177,0,143,255,237,0,177,0,144,255,237,0,177,0,145,255,246,0,177,0,146,255,246,0,177,0,147,255,246,0,177,0,148,255,246,0,177,0,149,255,246,0,177,0,151,255,246,0,177,0,152,255,238,0,177,0,153,255,238,0,177,0,154,255,238,0,177,0,155,255,238,0,177,0,156,255,167,0,177,0,157,255,237,0,177,0,158,255,248,0,177,0,188,255,245,0,177,0,190,255,245,0,177,0,194,255,246,0,177,0,196,255,238,0,177,0,198,255,167,0,177,0,199,255,227,0,177,0,200,255,246,0,177,0,209,255,182,0,177,0,210,255,179,0,177,0,212,255,182,0,177,0,213,255,179,0,177,0,221,255,247,0,177,0,240,255,236,0,178,0,3,255,236,0,178,0,7,255,246,0,178,0,8,255,236,0,178,0,10,255,224,0,178,0,11,255,234,0,178,0,18,255,230,0,178,0,19,255,229,0,178,0,24,255,223,0,178,0,32,255,222,0,178,0,34,255,240,0,178,0,35,255,237,0,178,0,36,255,246,0,178,0,37,255,237,0,178,0,38,255,237,0,178,0,39,255,237,0,178,0,40,255,246,0,178,0,41,255,237,0,178,0,42,255,237,0,178,0,43,255,237,0,178,0,44,255,237,0,178,0,45,255,237,0,178,0,46,255,239,0,178,0,47,255,237,0,178,0,48,255,246,0,178,0,49,255,237,0,178,0,50,255,246,0,178,0,51,255,237,0,178,0,52,255,238,0,178,0,53,255,173,0,178,0,54,255,238,0,178,0,55,255,192,0,178,0,56,255,212,0,178,0,57,255,218,0,178,0,58,255,167,0,178,0,59,255,227,0,178,0,61,255,214,0,178,0,62,255,213,0,178,0,71,255,251,0,178,0,85,255,249,0,178,0,87,255,247,0,178,0,88,255,251,0,178,0,89,255,237,0,178,0,90,255,245,0,178,0,91,255,246,0,178,0,94,255,222,0,178,0,122,255,247,0,178,0,127,255,240,0,178,0,128,255,240,0,178,0,129,255,240,0,178,0,130,255,240,0,178,0,131,255,240,0,178,0,132,255,240,0,178,0,134,255,246,0,178,0,135,255,237,0,178,0,136,255,237,0,178,0,137,255,237,0,178,0,138,255,237,0,178,0,139,255,237,0,178,0,140,255,237,0,178,0,141,255,237,0,178,0,142,255,237,0,178,0,143,255,237,0,178,0,144,255,237,0,178,0,145,255,246,0,178,0,146,255,246,0,178,0,147,255,246,0,178,0,148,255,246,0,178,0,149,255,246,0,178,0,151,255,246,0,178,0,152,255,238,0,178,0,153,255,238,0,178,0,154,255,238,0,178,0,155,255,238,0,178,0,156,255,167,0,178,0,157,255,237,0,178,0,158,255,248,0,178,0,188,255,245,0,178,0,190,255,245,0,178,0,194,255,246,0,178,0,196,255,238,0,178,0,198,255,167,0,178,0,199,255,227,0,178,0,200,255,246,0,178,0,209,255,182,0,178,0,210,255,179,0,178,0,212,255,182,0,178,0,213,255,179,0,178,0,221,255,247,0,178,0,240,255,236,0,179,0,3,255,236,0,179,0,7,255,246,0,179,0,8,255,236,0,179,0,10,255,224,0,179,0,11,255,234,0,179,0,18,255,230,0,179,0,19,255,229,0,179,0,24,255,223,0,179,0,32,255,222,0,179,0,34,255,240,0,179,0,35,255,237,0,179,0,36,255,246,0,179,0,37,255,237,0,179,0,38,255,237,0,179,0,39,255,237,0,179,0,40,255,246,0,179,0,41,255,237,0,179,0,42,255,237,0,179,0,43,255,237,0,179,0,44,255,237,0,179,0,45,255,237,0,179,0,46,255,239,0,179,0,47,255,237,0,179,0,48,255,246,0,179,0,49,255,237,0,179,0,50,255,246,0,179,0,51,255,237,0,179,0,52,255,238,0,179,0,53,255,173,0,179,0,54,255,238,0,179,0,55,255,192,0,179,0,56,255,212,0,179,0,57,255,218,0,179,0,58,255,167,0,179,0,59,255,227,0,179,0,61,255,214,0,179,0,62,255,213,0,179,0,71,255,251,0,179,0,85,255,249,0,179,0,87,255,247,0,179,0,88,255,251,0,179,0,89,255,237,0,179,0,90,255,245,0,179,0,91,255,246,0,179,0,94,255,222,0,179,0,122,255,247,0,179,0,127,255,240,0,179,0,128,255,240,0,179,0,129,255,240,0,179,0,130,255,240,0,179,0,131,255,240,0,179,0,132,255,240,0,179,0,134,255,246,0,179,0,135,255,237,0,179,0,136,255,237,0,179,0,137,255,237,0,179,0,138,255,237,0,179,0,139,255,237,0,179,0,140,255,237,0,179,0,141,255,237,0,179,0,142,255,237,0,179,0,143,255,237,0,179,0,144,255,237,0,179,0,145,255,246,0,179,0,146,255,246,0,179,0,147,255,246,0,179,0,148,255,246,0,179,0,149,255,246,0,179,0,151,255,246,0,179,0,152,255,238,0,179,0,153,255,238,0,179,0,154,255,238,0,179,0,155,255,238,0,179,0,156,255,167,0,179,0,157,255,237,0,179,0,158,255,248,0,179,0,188,255,245,0,179,0,190,255,245,0,179,0,194,255,246,0,179,0,196,255,238,0,179,0,198,255,167,0,179,0,199,255,227,0,179,0,200,255,246,0,179,0,209,255,182,0,179,0,210,255,179,0,179,0,212,255,182,0,179,0,213,255,179,0,179,0,221,255,247,0,179,0,240,255,236,0,180,0,3,255,236,0,180,0,7,255,246,0,180,0,8,255,236,0,180,0,10,255,224,0,180,0,11,255,234,0,180,0,18,255,230,0,180,0,19,255,229,0,180,0,24,255,223,0,180,0,32,255,222,0,180,0,34,255,240,0,180,0,35,255,237,0,180,0,36,255,246,0,180,0,37,255,237,0,180,0,38,255,237,0,180,0,39,255,237,0,180,0,40,255,246,0,180,0,41,255,237,0,180,0,42,255,237,0,180,0,43,255,237,0,180,0,44,255,237,0,180,0,45,255,237,0,180,0,46,255,239,0,180,0,47,255,237,0,180,0,48,255,246,0,180,0,49,255,237,0,180,0,50,255,246,0,180,0,51,255,237,0,180,0,52,255,238,0,180,0,53,255,173,0,180,0,54,255,238,0,180,0,55,255,192,0,180,0,56,255,212,0,180,0,57,255,218,0,180,0,58,255,167,0,180,0,59,255,227,0,180,0,61,255,214,0,180,0,62,255,213,0,180,0,71,255,251,0,180,0,85,255,249,0,180,0,87,255,247,0,180,0,88,255,251,0,180,0,89,255,237,0,180,0,90,255,245,0,180,0,91,255,246,0,180,0,94,255,222,0,180,0,122,255,247,0,180,0,127,255,240,0,180,0,128,255,240,0,180,0,129,255,240,0,180,0,130,255,240,0,180,0,131,255,240,0,180,0,132,255,240,0,180,0,134,255,246,0,180,0,135,255,237,0,180,0,136,255,237,0,180,0,137,255,237,0,180,0,138,255,237,0,180,0,139,255,237,0,180,0,140,255,237,0,180,0,141,255,237,0,180,0,142,255,237,0,180,0,143,255,237,0,180,0,144,255,237,0,180,0,145,255,246,0,180,0,146,255,246,0,180,0,147,255,246,0,180,0,148,255,246,0,180,0,149,255,246,0,180,0,151,255,246,0,180,0,152,255,238,0,180,0,153,255,238,0,180,0,154,255,238,0,180,0,155,255,238,0,180,0,156,255,167,0,180,0,157,255,237,0,180,0,158,255,248,0,180,0,188,255,245,0,180,0,190,255,245,0,180,0,194,255,246,0,180,0,196,255,238,0,180,0,198,255,167,0,180,0,199,255,227,0,180,0,200,255,246,0,180,0,209,255,182,0,180,0,210,255,179,0,180,0,212,255,182,0,180,0,213,255,179,0,180,0,221,255,247,0,180,0,240,255,236,0,181,0,3,255,236,0,181,0,7,255,246,0,181,0,8,255,236,0,181,0,10,255,224,0,181,0,11,255,234,0,181,0,18,255,230,0,181,0,19,255,229,0,181,0,24,255,223,0,181,0,32,255,222,0,181,0,34,255,240,0,181,0,35,255,237,0,181,0,36,255,246,0,181,0,37,255,237,0,181,0,38,255,237,0,181,0,39,255,237,0,181,0,40,255,246,0,181,0,41,255,237,0,181,0,42,255,237,0,181,0,43,255,237,0,181,0,44,255,237,0,181,0,45,255,237,0,181,0,46,255,239,0,181,0,47,255,237,0,181,0,48,255,246,0,181,0,49,255,237,0,181,0,50,255,246,0,181,0,51,255,237,0,181,0,52,255,238,0,181,0,53,255,173,0,181,0,54,255,238,0,181,0,55,255,192,0,181,0,56,255,212,0,181,0,57,255,218,0,181,0,58,255,167,0,181,0,59,255,227,0,181,0,61,255,214,0,181,0,62,255,213,0,181,0,71,255,251,0,181,0,85,255,249,0,181,0,87,255,247,0,181,0,88,255,251,0,181,0,89,255,237,0,181,0,90,255,245,0,181,0,91,255,246,0,181,0,94,255,222,0,181,0,122,255,247,0,181,0,127,255,240,0,181,0,128,255,240,0,181,0,129,255,240,0,181,0,130,255,240,0,181,0,131,255,240,0,181,0,132,255,240,0,181,0,134,255,246,0,181,0,135,255,237,0,181,0,136,255,237,0,181,0,137,255,237,0,181,0,138,255,237,0,181,0,139,255,237,0,181,0,140,255,237,0,181,0,141,255,237,0,181,0,142,255,237,0,181,0,143,255,237,0,181,0,144,255,237,0,181,0,145,255,246,0,181,0,146,255,246,0,181,0,147,255,246,0,181,0,148,255,246,0,181,0,149,255,246,0,181,0,151,255,246,0,181,0,152,255,238,0,181,0,153,255,238,0,181,0,154,255,238,0,181,0,155,255,238,0,181,0,156,255,167,0,181,0,157,255,237,0,181,0,158,255,248,0,181,0,188,255,245,0,181,0,190,255,245,0,181,0,194,255,246,0,181,0,196,255,238,0,181,0,198,255,167,0,181,0,199,255,227,0,181,0,200,255,246,0,181,0,209,255,182,0,181,0,210,255,179,0,181,0,212,255,182,0,181,0,213,255,179,0,181,0,221,255,247,0,181,0,240,255,236,0,183,0,3,255,236,0,183,0,7,255,246,0,183,0,8,255,236,0,183,0,10,255,224,0,183,0,11,255,234,0,183,0,18,255,230,0,183,0,19,255,229,0,183,0,24,255,223,0,183,0,32,255,222,0,183,0,34,255,240,0,183,0,35,255,237,0,183,0,36,255,246,0,183,0,37,255,237,0,183,0,38,255,237,0,183,0,39,255,237,0,183,0,40,255,246,0,183,0,41,255,237,0,183,0,42,255,237,0,183,0,43,255,237,0,183,0,44,255,237,0,183,0,45,255,237,0,183,0,46,255,239,0,183,0,47,255,237,0,183,0,48,255,246,0,183,0,49,255,237,0,183,0,50,255,246,0,183,0,51,255,237,0,183,0,52,255,238,0,183,0,53,255,173,0,183,0,54,255,238,0,183,0,55,255,192,0,183,0,56,255,212,0,183,0,57,255,218,0,183,0,58,255,167,0,183,0,59,255,227,0,183,0,61,255,214,0,183,0,62,255,213,0,183,0,71,255,251,0,183,0,85,255,249,0,183,0,87,255,247,0,183,0,88,255,251,0,183,0,89,255,237,0,183,0,90,255,245,0,183,0,91,255,246,0,183,0,94,255,222,0,183,0,122,255,247,0,183,0,127,255,240,0,183,0,128,255,240,0,183,0,129,255,240,0,183,0,130,255,240,0,183,0,131,255,240,0,183,0,132,255,240,0,183,0,134,255,246,0,183,0,135,255,237,0,183,0,136,255,237,0,183,0,137,255,237,0,183,0,138,255,237,0,183,0,139,255,237,0,183,0,140,255,237,0,183,0,141,255,237,0,183,0,142,255,237,0,183,0,143,255,237,0,183,0,144,255,237,0,183,0,145,255,246,0,183,0,146,255,246,0,183,0,147,255,246,0,183,0,148,255,246,0,183,0,149,255,246,0,183,0,151,255,246,0,183,0,152,255,238,0,183,0,153,255,238,0,183,0,154,255,238,0,183,0,155,255,238,0,183,0,156,255,167,0,183,0,157,255,237,0,183,0,158,255,248,0,183,0,188,255,245,0,183,0,190,255,245,0,183,0,194,255,246,0,183,0,196,255,238,0,183,0,198,255,167,0,183,0,199,255,227,0,183,0,200,255,246,0,183,0,209,255,182,0,183,0,210,255,179,0,183,0,212,255,182,0,183,0,213,255,179,0,183,0,221,255,247,0,183,0,240,255,236,0,184,0,7,255,244,0,184,0,10,255,233,0,184,0,11,255,244,0,184,0,24,255,232,0,184,0,32,255,223,0,184,0,34,255,248,0,184,0,35,255,242,0,184,0,36,255,244,0,184,0,37,255,242,0,184,0,38,255,242,0,184,0,39,255,242,0,184,0,40,255,244,0,184,0,41,255,242,0,184,0,42,255,242,0,184,0,43,255,242,0,184,0,44,255,242,0,184,0,45,255,242,0,184,0,46,255,241,0,184,0,47,255,242,0,184,0,48,255,244,0,184,0,49,255,242,0,184,0,50,255,244,0,184,0,51,255,242,0,184,0,52,255,243,0,184,0,53,255,164,0,184,0,54,255,235,0,184,0,55,255,216,0,184,0,56,255,218,0,184,0,57,255,246,0,184,0,58,255,183,0,184,0,59,255,242,0,184,0,61,255,228,0,184,0,62,255,215,0,184,0,94,255,226,0,184,0,127,255,248,0,184,0,128,255,248,0,184,0,129,255,248,0,184,0,130,255,248,0,184,0,131,255,248,0,184,0,132,255,248,0,184,0,134,255,244,0,184,0,135,255,242,0,184,0,136,255,242,0,184,0,137,255,242,0,184,0,138,255,242,0,184,0,139,255,242,0,184,0,140,255,242,0,184,0,141,255,242,0,184,0,142,255,242,0,184,0,143,255,242,0,184,0,144,255,242,0,184,0,145,255,244,0,184,0,146,255,244,0,184,0,147,255,244,0,184,0,148,255,244,0,184,0,149,255,244,0,184,0,151,255,244,0,184,0,152,255,235,0,184,0,153,255,235,0,184,0,154,255,235,0,184,0,155,255,235,0,184,0,156,255,183,0,184,0,157,255,242,0,184,0,194,255,244,0,184,0,196,255,243,0,184,0,198,255,183,0,184,0,199,255,242,0,184,0,209,255,211,0,184,0,210,255,209,0,184,0,212,255,211,0,184,0,213,255,209,0,184,0,240,255,239,0,185,0,7,255,244,0,185,0,10,255,233,0,185,0,11,255,244,0,185,0,24,255,232,0,185,0,32,255,223,0,185,0,34,255,248,0,185,0,35,255,242,0,185,0,36,255,244,0,185,0,37,255,242,0,185,0,38,255,242,0,185,0,39,255,242,0,185,0,40,255,244,0,185,0,41,255,242,0,185,0,42,255,242,0,185,0,43,255,242,0,185,0,44,255,242,0,185,0,45,255,242,0,185,0,46,255,241,0,185,0,47,255,242,0,185,0,48,255,244,0,185,0,49,255,242,0,185,0,50,255,244,0,185,0,51,255,242,0,185,0,52,255,243,0,185,0,53,255,164,0,185,0,54,255,235,0,185,0,55,255,216,0,185,0,56,255,218,0,185,0,57,255,246,0,185,0,58,255,183,0,185,0,59,255,242,0,185,0,61,255,228,0,185,0,62,255,215,0,185,0,94,255,226,0,185,0,127,255,248,0,185,0,128,255,248,0,185,0,129,255,248,0,185,0,130,255,248,0,185,0,131,255,248,0,185,0,132,255,248,0,185,0,134,255,244,0,185,0,135,255,242,0,185,0,136,255,242,0,185,0,137,255,242,0,185,0,138,255,242,0,185,0,139,255,242,0,185,0,140,255,242,0,185,0,141,255,242,0,185,0,142,255,242,0,185,0,143,255,242,0,185,0,144,255,242,0,185,0,145,255,244,0,185,0,146,255,244,0,185,0,147,255,244,0,185,0,148,255,244,0,185,0,149,255,244,0,185,0,151,255,244,0,185,0,152,255,235,0,185,0,153,255,235,0,185,0,154,255,235,0,185,0,155,255,235,0,185,0,156,255,183,0,185,0,157,255,242,0,185,0,194,255,244,0,185,0,196,255,243,0,185,0,198,255,183,0,185,0,199,255,242,0,185,0,209,255,211,0,185,0,210,255,209,0,185,0,212,255,211,0,185,0,213,255,209,0,185,0,240,255,239,0,186,0,7,255,244,0,186,0,10,255,233,0,186,0,11,255,244,0,186,0,24,255,232,0,186,0,32,255,223,0,186,0,34,255,248,0,186,0,35,255,242,0,186,0,36,255,244,0,186,0,37,255,242,0,186,0,38,255,242,0,186,0,39,255,242,0,186,0,40,255,244,0,186,0,41,255,242,0,186,0,42,255,242,0,186,0,43,255,242,0,186,0,44,255,242,0,186,0,45,255,242,0,186,0,46,255,241,0,186,0,47,255,242,0,186,0,48,255,244,0,186,0,49,255,242,0,186,0,50,255,244,0,186,0,51,255,242,0,186,0,52,255,243,0,186,0,53,255,164,0,186,0,54,255,235,0,186,0,55,255,216,0,186,0,56,255,218,0,186,0,57,255,246,0,186,0,58,255,183,0,186,0,59,255,242,0,186,0,61,255,228,0,186,0,62,255,215,0,186,0,94,255,226,0,186,0,127,255,248,0,186,0,128,255,248,0,186,0,129,255,248,0,186,0,130,255,248,0,186,0,131,255,248,0,186,0,132,255,248,0,186,0,134,255,244,0,186,0,135,255,242,0,186,0,136,255,242,0,186,0,137,255,242,0,186,0,138,255,242,0,186,0,139,255,242,0,186,0,140,255,242,0,186,0,141,255,242,0,186,0,142,255,242,0,186,0,143,255,242,0,186,0,144,255,242,0,186,0,145,255,244,0,186,0,146,255,244,0,186,0,147,255,244,0,186,0,148,255,244,0,186,0,149,255,244,0,186,0,151,255,244,0,186,0,152,255,235,0,186,0,153,255,235,0,186,0,154,255,235,0,186,0,155,255,235,0,186,0,156,255,183,0,186,0,157,255,242,0,186,0,194,255,244,0,186,0,196,255,243,0,186,0,198,255,183,0,186,0,199,255,242,0,186,0,209,255,211,0,186,0,210,255,209,0,186,0,212,255,211,0,186,0,213,255,209,0,186,0,240,255,239,0,187,0,7,255,244,0,187,0,10,255,233,0,187,0,11,255,244,0,187,0,24,255,232,0,187,0,32,255,223,0,187,0,34,255,248,0,187,0,35,255,242,0,187,0,36,255,244,0,187,0,37,255,242,0,187,0,38,255,242,0,187,0,39,255,242,0,187,0,40,255,244,0,187,0,41,255,242,0,187,0,42,255,242,0,187,0,43,255,242,0,187,0,44,255,242,0,187,0,45,255,242,0,187,0,46,255,241,0,187,0,47,255,242,0,187,0,48,255,244,0,187,0,49,255,242,0,187,0,50,255,244,0,187,0,51,255,242,0,187,0,52,255,243,0,187,0,53,255,164,0,187,0,54,255,235,0,187,0,55,255,216,0,187,0,56,255,218,0,187,0,57,255,246,0,187,0,58,255,183,0,187,0,59,255,242,0,187,0,61,255,228,0,187,0,62,255,215,0,187,0,94,255,226,0,187,0,127,255,248,0,187,0,128,255,248,0,187,0,129,255,248,0,187,0,130,255,248,0,187,0,131,255,248,0,187,0,132,255,248,0,187,0,134,255,244,0,187,0,135,255,242,0,187,0,136,255,242,0,187,0,137,255,242,0,187,0,138,255,242,0,187,0,139,255,242,0,187,0,140,255,242,0,187,0,141,255,242,0,187,0,142,255,242,0,187,0,143,255,242,0,187,0,144,255,242,0,187,0,145,255,244,0,187,0,146,255,244,0,187,0,147,255,244,0,187,0,148,255,244,0,187,0,149,255,244,0,187,0,151,255,244,0,187,0,152,255,235,0,187,0,153,255,235,0,187,0,154,255,235,0,187,0,155,255,235,0,187,0,156,255,183,0,187,0,157,255,242,0,187,0,194,255,244,0,187,0,196,255,243,0,187,0,198,255,183,0,187,0,199,255,242,0,187,0,209,255,211,0,187,0,210,255,209,0,187,0,212,255,211,0,187,0,213,255,209,0,187,0,240,255,239,0,188,0,7,255,238,0,188,0,10,255,231,0,188,0,13,255,225,0,188,0,15,255,225,0,188,0,16,255,220,0,188,0,19,255,227,0,188,0,20,255,230,0,188,0,24,255,198,0,188,0,32,255,205,0,188,0,33,255,238,0,188,0,34,255,214,0,188,0,35,255,243,0,188,0,37,255,243,0,188,0,38,255,243,0,188,0,39,255,243,0,188,0,41,255,243,0,188,0,42,255,243,0,188,0,43,255,243,0,188,0,44,255,243,0,188,0,45,255,243,0,188,0,46,255,229,0,188,0,47,255,243,0,188,0,49,255,243,0,188,0,51,255,243,0,188,0,53,255,168,0,188,0,54,255,245,0,188,0,55,255,238,0,188,0,56,255,242,0,188,0,57,255,208,0,188,0,58,255,211,0,188,0,59,255,225,0,188,0,62,255,214,0,188,0,66,255,250,0,188,0,68,255,246,0,188,0,69,255,246,0,188,0,70,255,246,0,188,0,72,255,250,0,188,0,80,255,246,0,188,0,82,255,246,0,188,0,84,255,252,0,188,0,94,255,227,0,188,0,127,255,214,0,188,0,128,255,214,0,188,0,129,255,214,0,188,0,130,255,214,0,188,0,131,255,214,0,188,0,132,255,214,0,188,0,135,255,243,0,188,0,136,255,243,0,188,0,137,255,243,0,188,0,138,255,243,0,188,0,139,255,243,0,188,0,140,255,243,0,188,0,141,255,243,0,188,0,142,255,243,0,188,0,143,255,243,0,188,0,144,255,243,0,188,0,152,255,245,0,188,0,153,255,245,0,188,0,154,255,245,0,188,0,155,255,245,0,188,0,156,255,211,0,188,0,157,255,243,0,188,0,159,255,250,0,188,0,160,255,250,0,188,0,161,255,250,0,188,0,162,255,250,0,188,0,163,255,250,0,188,0,164,255,250,0,188,0,165,255,250,0,188,0,166,255,246,0,188,0,167,255,246,0,188,0,168,255,246,0,188,0,169,255,246,0,188,0,170,255,246,0,188,0,175,255,236,0,188,0,177,255,246,0,188,0,178,255,246,0,188,0,179,255,246,0,188,0,180,255,246,0,188,0,181,255,246,0,188,0,183,255,246,0,188,0,195,255,246,0,188,0,197,255,252,0,188,0,198,255,211,0,188,0,199,255,225,0,188,0,209,255,227,0,188,0,210,255,225,0,188,0,211,255,225,0,188,0,212,255,227,0,188,0,213,255,225,0,188,0,214,255,225,0,188,0,218,255,225,0,189,0,3,255,234,0,189,0,7,255,246,0,189,0,8,255,234,0,189,0,10,255,227,0,189,0,11,255,232,0,189,0,13,255,246,0,189,0,15,255,247,0,189,0,18,255,235,0,189,0,19,255,232,0,189,0,24,255,226,0,189,0,32,255,224,0,189,0,34,255,240,0,189,0,35,255,237,0,189,0,36,255,246,0,189,0,37,255,237,0,189,0,38,255,237,0,189,0,39,255,237,0,189,0,40,255,246,0,189,0,41,255,237,0,189,0,42,255,237,0,189,0,43,255,237,0,189,0,44,255,237,0,189,0,45,255,237,0,189,0,46,255,239,0,189,0,47,255,237,0,189,0,48,255,246,0,189,0,49,255,237,0,189,0,50,255,246,0,189,0,51,255,237,0,189,0,52,255,237,0,189,0,53,255,171,0,189,0,54,255,238,0,189,0,55,255,193,0,189,0,56,255,212,0,189,0,57,255,217,0,189,0,58,255,167,0,189,0,59,255,227,0,189,0,61,255,217,0,189,0,62,255,217,0,189,0,71,255,251,0,189,0,85,255,250,0,189,0,87,255,247,0,189,0,88,255,251,0,189,0,89,255,238,0,189,0,90,255,245,0,189,0,91,255,246,0,189,0,94,255,226,0,189,0,122,255,247,0,189,0,127,255,240,0,189,0,128,255,240,0,189,0,129,255,240,0,189,0,130,255,240,0,189,0,131,255,240,0,189,0,132,255,240,0,189,0,134,255,246,0,189,0,135,255,237,0,189,0,136,255,237,0,189,0,137,255,237,0,189,0,138,255,237,0,189,0,139,255,237,0,189,0,140,255,237,0,189,0,141,255,237,0,189,0,142,255,237,0,189,0,143,255,237,0,189,0,144,255,237,0,189,0,145,255,246,0,189,0,146,255,246,0,189,0,147,255,246,0,189,0,148,255,246,0,189,0,149,255,246,0,189,0,151,255,246,0,189,0,152,255,238,0,189,0,153,255,238,0,189,0,154,255,238,0,189,0,155,255,238,0,189,0,156,255,167,0,189,0,157,255,237,0,189,0,158,255,248,0,189,0,188,255,245,0,189,0,190,255,245,0,189,0,194,255,246,0,189,0,196,255,237,0,189,0,198,255,167,0,189,0,199,255,227,0,189,0,200,255,246,0,189,0,209,255,181,0,189,0,210,255,178,0,189,0,211,255,246,0,189,0,212,255,181,0,189,0,213,255,178,0,189,0,214,255,246,0,189,0,218,255,247,0,189,0,221,255,247,0,189,0,240,255,234,0,190,0,7,255,238,0,190,0,10,255,231,0,190,0,13,255,225,0,190,0,15,255,225,0,190,0,16,255,220,0,190,0,19,255,227,0,190,0,20,255,230,0,190,0,24,255,198,0,190,0,32,255,205,0,190,0,33,255,238,0,190,0,34,255,214,0,190,0,35,255,243,0,190,0,37,255,243,0,190,0,38,255,243,0,190,0,39,255,243,0,190,0,41,255,243,0,190,0,42,255,243,0,190,0,43,255,243,0,190,0,44,255,243,0,190,0,45,255,243,0,190,0,46,255,229,0,190,0,47,255,243,0,190,0,49,255,243,0,190,0,51,255,243,0,190,0,53,255,168,0,190,0,54,255,245,0,190,0,55,255,238,0,190,0,56,255,242,0,190,0,57,255,208,0,190,0,58,255,211,0,190,0,59,255,225,0,190,0,62,255,214,0,190,0,66,255,250,0,190,0,68,255,246,0,190,0,69,255,246,0,190,0,70,255,246,0,190,0,72,255,250,0,190,0,80,255,246,0,190,0,82,255,246,0,190,0,84,255,252,0,190,0,94,255,227,0,190,0,127,255,214,0,190,0,128,255,214,0,190,0,129,255,214,0,190,0,130,255,214,0,190,0,131,255,214,0,190,0,132,255,214,0,190,0,135,255,243,0,190,0,136,255,243,0,190,0,137,255,243,0,190,0,138,255,243,0,190,0,139,255,243,0,190,0,140,255,243,0,190,0,141,255,243,0,190,0,142,255,243,0,190,0,143,255,243,0,190,0,144,255,243,0,190,0,152,255,245,0,190,0,153,255,245,0,190,0,154,255,245,0,190,0,155,255,245,0,190,0,156,255,211,0,190,0,157,255,243,0,190,0,159,255,250,0,190,0,160,255,250,0,190,0,161,255,250,0,190,0,162,255,250,0,190,0,163,255,250,0,190,0,164,255,250,0,190,0,165,255,250,0,190,0,166,255,246,0,190,0,167,255,246,0,190,0,168,255,246,0,190,0,169,255,246,0,190,0,170,255,246,0,190,0,175,255,236,0,190,0,177,255,246,0,190,0,178,255,246,0,190,0,179,255,246,0,190,0,180,255,246,0,190,0,181,255,246,0,190,0,183,255,246,0,190,0,195,255,246,0,190,0,197,255,252,0,190,0,198,255,211,0,190,0,199,255,225,0,190,0,209,255,227,0,190,0,210,255,225,0,190,0,211,255,225,0,190,0,212,255,227,0,190,0,213,255,225,0,190,0,214,255,225,0,190,0,218,255,225,0,193,0,7,255,244,0,193,0,34,255,248,0,193,0,35,255,242,0,193,0,36,255,244,0,193,0,37,255,242,0,193,0,38,255,242,0,193,0,39,255,242,0,193,0,40,255,244,0,193,0,41,255,242,0,193,0,42,255,242,0,193,0,43,255,242,0,193,0,44,255,242,0,193,0,45,255,242,0,193,0,46,255,241,0,193,0,47,255,242,0,193,0,48,255,244,0,193,0,49,255,242,0,193,0,50,255,244,0,193,0,51,255,242,0,193,0,52,255,244,0,193,0,53,255,242,0,193,0,54,255,238,0,193,0,55,255,247,0,193,0,56,255,246,0,193,0,58,255,247,0,193,0,59,255,245,0,193,0,127,255,248,0,193,0,128,255,248,0,193,0,129,255,248,0,193,0,130,255,248,0,193,0,131,255,248,0,193,0,132,255,248,0,193,0,134,255,244,0,193,0,135,255,242,0,193,0,136,255,242,0,193,0,137,255,242,0,193,0,138,255,242,0,193,0,139,255,242,0,193,0,140,255,242,0,193,0,141,255,242,0,193,0,142,255,242,0,193,0,143,255,242,0,193,0,144,255,242,0,193,0,145,255,244,0,193,0,146,255,244,0,193,0,147,255,244,0,193,0,148,255,244,0,193,0,149,255,244,0,193,0,151,255,244,0,193,0,152,255,238,0,193,0,153,255,238,0,193,0,154,255,238,0,193,0,155,255,238,0,193,0,156,255,247,0,193,0,157,255,242,0,193,0,194,255,244,0,193,0,196,255,244,0,193,0,198,255,247,0,193,0,199,255,245,0,194,0,14,255,244,0,194,0,21,255,220,0,194,0,36,255,245,0,194,0,40,255,245,0,194,0,48,255,245,0,194,0,50,255,245,0,194,0,68,255,240,0,194,0,69,255,240,0,194,0,70,255,240,0,194,0,71,255,243,0,194,0,72,255,241,0,194,0,78,255,247,0,194,0,79,255,247,0,194,0,80,255,240,0,194,0,81,255,247,0,194,0,82,255,240,0,194,0,83,255,247,0,194,0,84,255,251,0,194,0,85,255,242,0,194,0,86,255,238,0,194,0,87,255,241,0,194,0,88,255,243,0,194,0,90,255,240,0,194,0,107,255,235,0,194,0,110,255,248,0,194,0,134,255,245,0,194,0,145,255,245,0,194,0,146,255,245,0,194,0,147,255,245,0,194,0,148,255,245,0,194,0,149,255,245,0,194,0,151,255,245,0,194,0,158,255,243,0,194,0,166,255,240,0,194,0,167,255,240,0,194,0,168,255,240,0,194,0,169,255,240,0,194,0,170,255,240,0,194,0,173,0,21,0,194,0,175,255,246,0,194,0,176,255,247,0,194,0,177,255,240,0,194,0,178,255,240,0,194,0,179,255,240,0,194,0,180,255,240,0,194,0,181,255,240,0,194,0,183,255,240,0,194,0,184,255,238,0,194,0,185,255,238,0,194,0,186,255,238,0,194,0,187,255,238,0,194,0,188,255,240,0,194,0,189,255,247,0,194,0,190,255,240,0,194,0,194,255,245,0,194,0,195,255,240,0,194,0,197,255,251,0,194,0,207,255,244,0,194,0,208,255,244,0,194,0,220,255,235,0,195,0,3,255,241,0,195,0,7,255,246,0,195,0,8,255,241,0,195,0,10,255,230,0,195,0,11,255,238,0,195,0,18,255,235,0,195,0,19,255,245,0,195,0,24,255,230,0,195,0,32,255,223,0,195,0,34,255,251,0,195,0,35,255,241,0,195,0,36,255,250,0,195,0,37,255,241,0,195,0,38,255,241,0,195,0,39,255,241,0,195,0,40,255,250,0,195,0,41,255,241,0,195,0,42,255,241,0,195,0,43,255,241,0,195,0,44,255,241,0,195,0,45,255,241,0,195,0,46,255,243,0,195,0,47,255,241,0,195,0,48,255,250,0,195,0,49,255,241,0,195,0,50,255,250,0,195,0,51,255,241,0,195,0,52,255,241,0,195,0,53,255,187,0,195,0,54,255,240,0,195,0,55,255,209,0,195,0,56,255,213,0,195,0,57,255,243,0,195,0,58,255,174,0,195,0,59,255,243,0,195,0,61,255,220,0,195,0,62,255,220,0,195,0,87,255,252,0,195,0,89,255,251,0,195,0,90,255,251,0,195,0,94,255,227,0,195,0,127,255,251,0,195,0,128,255,251,0,195,0,129,255,251,0,195,0,130,255,251,0,195,0,131,255,251,0,195,0,132,255,251,0,195,0,134,255,250,0,195,0,135,255,241,0,195,0,136,255,241,0,195,0,137,255,241,0,195,0,138,255,241,0,195,0,139,255,241,0,195,0,140,255,241,0,195,0,141,255,241,0,195,0,142,255,241,0,195,0,143,255,241,0,195,0,144,255,241,0,195,0,145,255,250,0,195,0,146,255,250,0,195,0,147,255,250,0,195,0,148,255,250,0,195,0,149,255,250,0,195,0,151,255,250,0,195,0,152,255,240,0,195,0,153,255,240,0,195,0,154,255,240,0,195,0,155,255,240,0,195,0,156,255,174,0,195,0,157,255,241,0,195,0,188,255,251,0,195,0,190,255,251,0,195,0,194,255,250,0,195,0,196,255,241,0,195,0,198,255,174,0,195,0,199,255,243,0,195,0,209,255,189,0,195,0,210,255,186,0,195,0,212,255,189,0,195,0,213,255,186,0,195,0,240,255,237,0,196,0,10,255,246,0,196,0,57,255,251,0,196,0,67,255,250,0,196,0,71,255,243,0,196,0,72,255,250,0,196,0,73,255,250,0,196,0,74,255,250,0,196,0,75,255,250,0,196,0,76,255,250,0,196,0,77,255,250,0,196,0,78,255,250,0,196,0,79,255,250,0,196,0,81,255,250,0,196,0,83,255,250,0,196,0,84,255,251,0,196,0,85,255,241,0,196,0,86,255,250,0,196,0,87,255,241,0,196,0,88,255,244,0,196,0,89,255,242,0,196,0,90,255,240,0,196,0,91,255,244,0,196,0,158,255,244,0,196,0,171,255,250,0,196,0,172,255,250,0,196,0,173,255,250,0,196,0,174,255,250,0,196,0,176,255,250,0,196,0,184,255,250,0,196,0,185,255,250,0,196,0,186,255,250,0,196,0,187,255,250,0,196,0,188,255,240,0,196,0,189,255,250,0,196,0,190,255,240,0,196,0,193,255,250,0,196,0,197,255,251,0,196,0,200,255,244,0,197,0,10,255,231,0,197,0,11,255,241,0,197,0,24,255,234,0,197,0,32,255,224,0,197,0,35,255,241,0,197,0,36,255,244,0,197,0,37,255,241,0,197,0,38,255,241,0,197,0,39,255,241,0,197,0,40,255,244,0,197,0,41,255,241,0,197,0,42,255,241,0,197,0,43,255,241,0,197,0,44,255,241,0,197,0,45,255,241,0,197,0,46,255,245,0,197,0,47,255,241,0,197,0,48,255,244,0,197,0,49,255,241,0,197,0,50,255,244,0,197,0,51,255,241,0,197,0,52,255,248,0,197,0,53,255,202,0,197,0,54,255,238,0,197,0,55,255,216,0,197,0,56,255,224,0,197,0,57,255,244,0,197,0,58,255,209,0,197,0,59,255,245,0,197,0,61,255,225,0,197,0,62,255,220,0,197,0,94,255,229,0,197,0,134,255,244,0,197,0,135,255,241,0,197,0,136,255,241,0,197,0,137,255,241,0,197,0,138,255,241,0,197,0,139,255,241,0,197,0,140,255,241,0,197,0,141,255,241,0,197,0,142,255,241,0,197,0,143,255,241,0,197,0,144,255,241,0,197,0,145,255,244,0,197,0,146,255,244,0,197,0,147,255,244,0,197,0,148,255,244,0,197,0,149,255,244,0,197,0,151,255,244,0,197,0,152,255,238,0,197,0,153,255,238,0,197,0,154,255,238,0,197,0,155,255,238,0,197,0,156,255,209,0,197,0,157,255,241,0,197,0,194,255,244,0,197,0,196,255,248,0,197,0,198,255,209,0,197,0,199,255,245,0,197,0,209,255,203,0,197,0,210,255,200,0,197,0,212,255,203,0,197,0,213,255,200,0,197,0,240,255,235,0,198,0,7,255,237,0,198,0,11,0,13,0,198,0,13,255,215,0,198,0,14,255,222,0,198,0,15,255,215,0,198,0,16,255,201,0,198,0,17,255,233,0,198,0,21,255,206,0,198,0,23,255,218,0,198,0,25,255,246,0,198,0,27,255,235,0,198,0,28,255,235,0,198,0,32,0,13,0,198,0,33,255,198,0,198,0,34,255,192,0,198,0,36,255,230,0,198,0,40,255,230,0,198,0,46,255,232,0,198,0,48,255,230,0,198,0,50,255,230,0,198,0,61,0,7,0,198,0,62,0,31,0,198,0,66,255,189,0,198,0,68,255,171,0,198,0,69,255,171,0,198,0,70,255,171,0,198,0,71,255,237,0,198,0,72,255,180,0,198,0,78,255,187,0,198,0,79,255,187,0,198,0,80,255,171,0,198,0,81,255,187,0,198,0,82,255,171,0,198,0,83,255,187,0,198,0,84,255,186,0,198,0,85,255,221,0,198,0,86,255,190,0,198,0,87,255,215,0,198,0,88,255,216,0,198,0,89,255,214,0,198,0,90,255,217,0,198,0,91,255,229,0,198,0,94,0,33,0,198,0,107,255,198,0,198,0,110,255,230,0,198,0,122,255,225,0,198,0,127,255,192,0,198,0,128,255,192,0,198,0,129,255,192,0,198,0,130,255,192,0,198,0,131,255,192,0,198,0,132,255,192,0,198,0,133,255,180,0,198,0,134,255,230,0,198,0,145,255,230,0,198,0,146,255,230,0,198,0,147,255,230,0,198,0,148,255,230,0,198,0,149,255,230,0,198,0,151,255,230,0,198,0,158,255,230,0,198,0,159,255,189,0,198,0,160,255,189,0,198,0,161,255,189,0,198,0,162,255,189,0,198,0,163,255,189,0,198,0,164,255,189,0,198,0,165,255,189,0,198,0,166,255,171,0,198,0,167,255,171,0,198,0,168,255,171,0,198,0,169,255,171,0,198,0,170,255,171,0,198,0,171,0,16,0,198,0,173,0,38,0,198,0,174,0,47,0,198,0,175,255,216,0,198,0,176,255,187,0,198,0,177,255,171,0,198,0,178,255,171,0,198,0,179,255,171,0,198,0,180,255,171,0,198,0,181,255,171,0,198,0,183,255,171,0,198,0,184,255,190,0,198,0,185,255,190,0,198,0,186,255,190,0,198,0,187,255,190,0,198,0,188,255,217,0,198,0,189,255,225,0,198,0,190,255,217,0,198,0,194,255,230,0,198,0,195,255,171,0,198,0,197,255,234,0,198,0,200,255,229,0,198,0,207,255,222,0,198,0,208,255,222,0,198,0,211,255,215,0,198,0,214,255,215,0,198,0,218,255,215,0,198,0,220,255,198,0,198,0,221,255,225,0,198,0,240,0,33,0,199,0,14,255,217,0,199,0,17,255,243,0,199,0,21,255,199,0,199,0,23,255,247,0,199,0,36,255,238,0,199,0,40,255,238,0,199,0,48,255,238,0,199,0,50,255,238,0,199,0,62,0,23,0,199,0,66,255,246,0,199,0,68,255,227,0,199,0,69,255,227,0,199,0,70,255,227,0,199,0,71,255,241,0,199,0,72,255,229,0,199,0,74,255,250,0,199,0,75,255,250,0,199,0,78,255,235,0,199,0,79,255,235,0,199,0,80,255,227,0,199,0,81,255,235,0,199,0,82,255,227,0,199,0,83,255,235,0,199,0,84,255,245,0,199,0,85,255,241,0,199,0,86,255,224,0,199,0,87,255,241,0,199,0,88,255,241,0,199,0,90,255,242,0,199,0,91,255,248,0,199,0,94,0,23,0,199,0,107,255,214,0,199,0,110,255,233,0,199,0,134,255,238,0,199,0,145,255,238,0,199,0,146,255,238,0,199,0,147,255,238,0,199,0,148,255,238,0,199,0,149,255,238,0,199,0,151,255,238,0,199,0,158,255,239,0,199,0,159,255,246,0,199,0,160,255,246,0,199,0,161,255,246,0,199,0,162,255,246,0,199,0,163,255,246,0,199,0,164,255,246,0,199,0,165,255,246,0,199,0,166,255,227,0,199,0,167,255,227,0,199,0,168,255,227,0,199,0,169,255,227,0,199,0,170,255,227,0,199,0,171,0,6,0,199,0,172,255,250,0,199,0,173,0,29,0,199,0,174,0,37,0,199,0,175,255,235,0,199,0,176,255,235,0,199,0,177,255,227,0,199,0,178,255,227,0,199,0,179,255,227,0,199,0,180,255,227,0,199,0,181,255,227,0,199,0,183,255,227,0,199,0,184,255,224,0,199,0,185,255,224,0,199,0,186,255,224,0,199,0,187,255,224,0,199,0,188,255,242,0,199,0,189,255,235,0,199,0,190,255,242,0,199,0,193,255,250,0,199,0,194,255,238,0,199,0,195,255,227,0,199,0,197,255,245,0,199,0,200,255,248,0,199,0,207,255,217,0,199,0,208,255,217,0,199,0,220,255,214,0,199,0,240,0,24,0,200,0,7,255,245,0,200,0,10,255,246,0,200,0,14,255,240,0,200,0,21,255,225,0,200,0,24,255,244,0,200,0,32,255,221,0,200,0,35,255,242,0,200,0,36,255,244,0,200,0,37,255,242,0,200,0,38,255,242,0,200,0,39,255,242,0,200,0,40,255,244,0,200,0,41,255,242,0,200,0,42,255,242,0,200,0,43,255,242,0,200,0,44,255,242,0,200,0,45,255,242,0,200,0,46,255,245,0,200,0,47,255,242,0,200,0,48,255,244,0,200,0,49,255,242,0,200,0,50,255,244,0,200,0,51,255,242,0,200,0,53,255,203,0,200,0,54,255,239,0,200,0,55,255,240,0,200,0,56,255,243,0,200,0,58,255,227,0,200,0,61,255,242,0,200,0,62,255,222,0,200,0,68,255,245,0,200,0,69,255,245,0,200,0,70,255,245,0,200,0,72,255,251,0,200,0,80,255,245,0,200,0,82,255,245,0,200,0,94,255,232,0,200,0,107,255,232,0,200,0,134,255,244,0,200,0,135,255,242,0,200,0,136,255,242,0,200,0,137,255,242,0,200,0,138,255,242,0,200,0,139,255,242,0,200,0,140,255,242,0,200,0,141,255,242,0,200,0,142,255,242,0,200,0,143,255,242,0,200,0,144,255,242,0,200,0,145,255,244,0,200,0,146,255,244,0,200,0,147,255,244,0,200,0,148,255,244,0,200,0,149,255,244,0,200,0,151,255,244,0,200,0,152,255,239,0,200,0,153,255,239,0,200,0,154,255,239,0,200,0,155,255,239,0,200,0,156,255,227,0,200,0,157,255,242,0,200,0,166,255,245,0,200,0,167,255,245,0,200,0,168,255,245,0,200,0,169,255,245,0,200,0,170,255,245,0,200,0,175,255,247,0,200,0,177,255,245,0,200,0,178,255,245,0,200,0,179,255,245,0,200,0,180,255,245,0,200,0,181,255,245,0,200,0,183,255,245,0,200,0,194,255,244,0,200,0,195,255,245,0,200,0,198,255,227,0,200,0,207,255,240,0,200,0,208,255,240,0,200,0,209,255,219,0,200,0,210,255,216,0,200,0,212,255,219,0,200,0,213,255,216,0,200,0,220,255,232,0,200,0,240,255,242,0,207,0,3,255,234,0,207,0,8,255,234,0,207,0,52,255,243,0,207,0,53,255,216,0,207,0,55,255,238,0,207,0,56,255,248,0,207,0,57,255,242,0,207,0,58,255,222,0,207,0,59,255,237,0,207,0,71,255,247,0,207,0,85,255,248,0,207,0,89,255,247,0,207,0,91,255,231,0,207,0,156,255,222,0,207,0,158,255,248,0,207,0,196,255,243,0,207,0,198,255,222,0,207,0,199,255,237,0,207,0,200,255,231,0,207,0,210,255,193,0,207,0,213,255,193,0,208,0,3,255,234,0,208,0,8,255,234,0,208,0,52,255,243,0,208,0,53,255,216,0,208,0,55,255,238,0,208,0,56,255,248,0,208,0,57,255,242,0,208,0,58,255,222,0,208,0,59,255,237,0,208,0,71,255,247,0,208,0,85,255,248,0,208,0,89,255,247,0,208,0,91,255,231,0,208,0,156,255,222,0,208,0,158,255,248,0,208,0,196,255,243,0,208,0,198,255,222,0,208,0,199,255,237,0,208,0,200,255,231,0,208,0,210,255,193,0,208,0,213,255,193,0,209,0,13,255,123,0,209,0,15,255,124,0,209,0,34,255,205,0,209,0,46,255,236,0,209,0,66,255,194,0,209,0,68,255,182,0,209,0,69,255,182,0,209,0,70,255,182,0,209,0,71,255,243,0,209,0,72,255,189,0,209,0,78,255,211,0,209,0,79,255,211,0,209,0,80,255,182,0,209,0,81,255,211,0,209,0,82,255,182,0,209,0,83,255,211,0,209,0,84,255,193,0,209,0,85,255,248,0,209,0,86,255,213,0,209,0,87,255,226,0,209,0,88,255,227,0,209,0,89,255,225,0,209,0,90,255,227,0,209,0,91,255,217,0,209,0,127,255,205,0,209,0,128,255,205,0,209,0,129,255,205,0,209,0,130,255,205,0,209,0,131,255,205,0,209,0,132,255,205,0,209,0,133,255,190,0,209,0,158,255,245,0,209,0,159,255,194,0,209,0,160,255,194,0,209,0,161,255,194,0,209,0,162,255,194,0,209,0,163,255,194,0,209,0,164,255,194,0,209,0,165,255,194,0,209,0,166,255,182,0,209,0,167,255,182,0,209,0,168,255,182,0,209,0,169,255,182,0,209,0,170,255,182,0,209,0,173,0,37,0,209,0,175,255,235,0,209,0,176,255,211,0,209,0,177,255,182,0,209,0,178,255,182,0,209,0,179,255,182,0,209,0,180,255,182,0,209,0,181,255,182,0,209,0,183,255,182,0,209,0,184,255,213,0,209,0,185,255,213,0,209,0,186,255,213,0,209,0,187,255,213,0,209,0,188,255,227,0,209,0,189,255,211,0,209,0,190,255,227,0,209,0,195,255,182,0,209,0,197,255,193,0,209,0,200,255,217,0,209,0,218,255,124,0,210,0,7,255,239,0,210,0,11,0,5,0,210,0,13,255,110,0,210,0,14,255,181,0,210,0,15,255,110,0,210,0,16,255,209,0,210,0,33,255,210,0,210,0,34,255,200,0,210,0,36,255,234,0,210,0,40,255,234,0,210,0,46,255,234,0,210,0,48,255,234,0,210,0,50,255,234,0,210,0,58,0,6,0,210,0,66,255,179,0,210,0,68,255,167,0,210,0,69,255,167,0,210,0,70,255,167,0,210,0,71,255,243,0,210,0,72,255,174,0,210,0,78,255,198,0,210,0,79,255,198,0,210,0,80,255,167,0,210,0,81,255,198,0,210,0,82,255,167,0,210,0,83,255,198,0,210,0,84,255,178,0,210,0,85,255,244,0,210,0,86,255,200,0,210,0,87,255,214,0,210,0,88,255,215,0,210,0,89,255,213,0,210,0,90,255,215,0,210,0,91,255,204,0,210,0,107,255,192,0,210,0,110,255,245,0,210,0,122,255,220,0,210,0,127,255,200,0,210,0,128,255,200,0,210,0,129,255,200,0,210,0,130,255,200,0,210,0,131,255,200,0,210,0,132,255,200,0,210,0,133,255,184,0,210,0,134,255,234,0,210,0,145,255,234,0,210,0,146,255,234,0,210,0,147,255,234,0,210,0,148,255,234,0,210,0,149,255,234,0,210,0,151,255,234,0,210,0,156,0,6,0,210,0,158,255,241,0,210,0,159,255,179,0,210,0,160,255,179,0,210,0,161,255,187,0,210,0,162,255,179,0,210,0,163,255,179,0,210,0,164,255,179,0,210,0,165,255,179,0,210,0,166,255,167,0,210,0,167,255,167,0,210,0,168,255,167,0,210,0,169,255,174,0,210,0,170,255,167,0,210,0,173,0,44,0,210,0,174,0,28,0,210,0,175,255,237,0,210,0,176,255,198,0,210,0,177,255,167,0,210,0,178,255,167,0,210,0,179,255,167,0,210,0,180,255,167,0,210,0,181,255,167,0,210,0,183,255,167,0,210,0,184,255,200,0,210,0,185,255,200,0,210,0,186,255,200,0,210,0,187,255,200,0,210,0,188,255,215,0,210,0,189,255,224,0,210,0,190,255,215,0,210,0,194,255,234,0,210,0,195,255,167,0,210,0,197,255,232,0,210,0,198,0,6,0,210,0,200,255,204,0,210,0,207,255,181,0,210,0,208,255,181,0,210,0,211,255,110,0,210,0,214,255,110,0,210,0,218,255,110,0,210,0,220,255,192,0,210,0,221,255,220,0,210,0,240,0,9,0,211,0,3,255,146,0,211,0,8,255,146,0,211,0,36,255,242,0,211,0,40,255,242,0,211,0,48,255,242,0,211,0,50,255,242,0,211,0,53,255,214,0,211,0,54,255,243,0,211,0,55,255,213,0,211,0,56,255,226,0,211,0,58,255,215,0,211,0,71,255,241,0,211,0,85,255,239,0,211,0,87,255,227,0,211,0,88,255,236,0,211,0,90,255,222,0,211,0,134,255,242,0,211,0,145,255,242,0,211,0,146,255,242,0,211,0,147,255,242,0,211,0,148,255,242,0,211,0,149,255,242,0,211,0,151,255,242,0,211,0,152,255,243,0,211,0,153,255,243,0,211,0,154,255,243,0,211,0,155,255,243,0,211,0,156,255,215,0,211,0,158,255,242,0,211,0,188,255,222,0,211,0,190,255,222,0,211,0,194,255,242,0,211,0,198,255,215,0,211,0,210,255,121,0,211,0,213,255,121,0,212,0,13,255,123,0,212,0,15,255,124,0,212,0,34,255,205,0,212,0,46,255,236,0,212,0,66,255,194,0,212,0,68,255,182,0,212,0,69,255,182,0,212,0,70,255,182,0,212,0,71,255,243,0,212,0,72,255,189,0,212,0,78,255,211,0,212,0,79,255,211,0,212,0,80,255,182,0,212,0,81,255,211,0,212,0,82,255,182,0,212,0,83,255,211,0,212,0,84,255,193,0,212,0,85,255,248,0,212,0,86,255,213,0,212,0,87,255,226,0,212,0,88,255,227,0,212,0,89,255,225,0,212,0,90,255,227,0,212,0,91,255,217,0,212,0,127,255,205,0,212,0,128,255,205,0,212,0,129,255,205,0,212,0,130,255,205,0,212,0,131,255,205,0,212,0,132,255,205,0,212,0,133,255,190,0,212,0,158,255,245,0,212,0,159,255,194,0,212,0,160,255,194,0,212,0,161,255,194,0,212,0,162,255,194,0,212,0,163,255,194,0,212,0,164,255,194,0,212,0,165,255,194,0,212,0,166,255,182,0,212,0,167,255,182,0,212,0,168,255,182,0,212,0,169,255,182,0,212,0,170,255,182,0,212,0,173,0,37,0,212,0,175,255,235,0,212,0,176,255,211,0,212,0,177,255,182,0,212,0,178,255,182,0,212,0,179,255,182,0,212,0,180,255,182,0,212,0,181,255,182,0,212,0,183,255,182,0,212,0,184,255,213,0,212,0,185,255,213,0,212,0,186,255,213,0,212,0,187,255,213,0,212,0,188,255,227,0,212,0,189,255,211,0,212,0,190,255,227,0,212,0,195,255,182,0,212,0,197,255,193,0,212,0,200,255,217,0,212,0,218,255,124,0,213,0,7,255,239,0,213,0,11,0,5,0,213,0,13,255,110,0,213,0,14,255,181,0,213,0,15,255,110,0,213,0,16,255,209,0,213,0,33,255,210,0,213,0,34,255,200,0,213,0,36,255,234,0,213,0,40,255,234,0,213,0,46,255,234,0,213,0,48,255,234,0,213,0,50,255,234,0,213,0,58,0,6,0,213,0,66,255,179,0,213,0,68,255,167,0,213,0,69,255,167,0,213,0,70,255,167,0,213,0,71,255,243,0,213,0,72,255,174,0,213,0,78,255,198,0,213,0,79,255,198,0,213,0,80,255,167,0,213,0,81,255,198,0,213,0,82,255,167,0,213,0,83,255,198,0,213,0,84,255,178,0,213,0,85,255,244,0,213,0,86,255,200,0,213,0,87,255,214,0,213,0,88,255,215,0,213,0,89,255,213,0,213,0,90,255,215,0,213,0,91,255,204,0,213,0,107,255,192,0,213,0,110,255,245,0,213,0,122,255,220,0,213,0,127,255,200,0,213,0,128,255,200,0,213,0,129,255,200,0,213,0,130,255,200,0,213,0,131,255,200,0,213,0,132,255,200,0,213,0,133,255,184,0,213,0,134,255,234,0,213,0,145,255,234,0,213,0,146,255,234,0,213,0,147,255,234,0,213,0,148,255,234,0,213,0,149,255,234,0,213,0,151,255,234,0,213,0,156,0,6,0,213,0,158,255,241,0,213,0,159,255,179,0,213,0,160,255,179,0,213,0,161,255,187,0,213,0,162,255,179,0,213,0,163,255,179,0,213,0,164,255,179,0,213,0,165,255,179,0,213,0,166,255,167,0,213,0,167,255,167,0,213,0,168,255,167,0,213,0,169,255,174,0,213,0,170,255,167,0,213,0,173,0,44,0,213,0,174,0,28,0,213,0,175,255,237,0,213,0,176,255,198,0,213,0,177,255,167,0,213,0,178,255,167,0,213,0,179,255,167,0,213,0,180,255,167,0,213,0,181,255,167,0,213,0,183,255,167,0,213,0,184,255,200,0,213,0,185,255,200,0,213,0,186,255,200,0,213,0,187,255,200,0,213,0,188,255,215,0,213,0,189,255,224,0,213,0,190,255,215,0,213,0,194,255,234,0,213,0,195,255,167,0,213,0,197,255,232,0,213,0,198,0,6,0,213,0,200,255,204,0,213,0,207,255,181,0,213,0,208,255,181,0,213,0,211,255,110,0,213,0,214,255,110,0,213,0,218,255,110,0,213,0,220,255,192,0,213,0,221,255,220,0,213,0,240,0,9,0,214,0,3,255,146,0,214,0,8,255,146,0,214,0,36,255,242,0,214,0,40,255,242,0,214,0,48,255,242,0,214,0,50,255,242,0,214,0,53,255,214,0,214,0,54,255,243,0,214,0,55,255,213,0,214,0,56,255,226,0,214,0,58,255,215,0,214,0,71,255,241,0,214,0,85,255,239,0,214,0,87,255,227,0,214,0,88,255,236,0,214,0,90,255,222,0,214,0,134,255,242,0,214,0,145,255,242,0,214,0,146,255,242,0,214,0,147,255,242,0,214,0,148,255,242,0,214,0,149,255,242,0,214,0,151,255,242,0,214,0,152,255,243,0,214,0,153,255,243,0,214,0,154,255,243,0,214,0,155,255,243,0,214,0,156,255,215,0,214,0,158,255,242,0,214,0,188,255,222,0,214,0,190,255,222,0,214,0,194,255,242,0,214,0,198,255,215,0,214,0,210,255,121,0,214,0,213,255,121,0,220,0,53,255,197,0,220,0,55,255,245,0,220,0,58,255,226,0,220,0,68,255,247,0,220,0,69,255,247,0,220,0,70,255,247,0,220,0,80,255,247,0,220,0,82,255,247,0,220,0,156,255,226,0,220,0,166,255,247,0,220,0,167,255,247,0,220,0,168,255,247,0,220,0,169,255,247,0,220,0,170,255,247,0,220,0,177,255,247,0,220,0,178,255,247,0,220,0,179,255,247,0,220,0,180,255,247,0,220,0,181,255,247,0,220,0,183,255,247,0,220,0,195,255,247,0,220,0,198,255,226,0,220,0,210,255,229,0,220,0,213,255,229,0,221,0,3,255,241,0,221,0,8,255,241,0,221,0,34,255,247,0,221,0,52,255,234,0,221,0,53,255,195,0,221,0,55,255,220,0,221,0,56,255,230,0,221,0,57,255,224,0,221,0,58,255,198,0,221,0,59,255,223,0,221,0,85,255,247,0,221,0,89,255,236,0,221,0,90,255,248,0,221,0,91,255,233,0,221,0,127,255,247,0,221,0,128,255,247,0,221,0,129,255,247,0,221,0,130,255,247,0,221,0,131,255,247,0,221,0,132,255,247,0,221,0,133,255,243,0,221,0,143,0,6,0,221,0,156,255,198,0,221,0,158,255,248,0,221,0,188,255,248,0,221,0,190,255,248,0,221,0,196,255,234,0,221,0,198,255,198,0,221,0,199,255,223,0,221,0,200,255,233,0,221,0,210,255,204,0,221,0,213,255,204,0,240,0,34,255,232,0,240,0,127,255,232,0,240,0,128,255,232,0,240,0,129,255,232,0,240,0,130,255,232,0,240,0,131,255,232,0,240,0,132,255,232,0,240,0,133,255,228,0,240,0,143,0,10,0,240,0,173,0,11,0,0,0,26,0,26,0,128,0,180,1,222,3,150,5,20,7,18,7,50,7,152,7,254,8,126,8,236,9,44,9,76,9,118,9,164,10,242,11,84,12,94,13,186,14,88,15,116,16,222,17,80,18,196,20,20,20,90,20,182,20,234,21,28,21,86,22,64,23,106,24,52,25,156,26,174,27,122,27,230,28,78,29,42,29,170,29,242,30,62,30,238,31,56,32,156,33,74,34,90,35,34,36,114,37,108,39,118,39,180,40,192,41,132,42,144,43,146,44,30,45,24,45,82,45,126,45,186,45,250,46,40,46,116,47,190,48,152,49,132,50,84,51,134,52,34,54,126,55,48,55,150,56,32,56,246,57,70,58,122,59,70,60,44,61,44,62,12,62,124,63,222,64,108,65,32,65,192,66,202,67,216,68,110,69,122,70,22,70,62,70,222,71,82,71,82,71,186,72,170,73,160,74,142,75,104,75,162,77,148,77,202,79,230,80,216,81,64,81,112,81,162,83,120,84,100,84,188,85,156,86,186,86,252,87,166,88,14,88,64,88,106,88,216,89,124,89,248,90,38,90,82,90,128,91,94,91,142,91,180,91,214,91,248,92,44,92,104,93,92,93,104,93,154,93,198,93,226,94,12,94,68,94,88,94,126,94,170,95,162,95,188,95,216,95,254,96,28,96,56,96,100,96,180,98,188,98,230,99,12,99,46,99,92,99,132,100,86,101,182,101,210,101,238,102,6,102,34,102,78,102,110,104,160,104,182,104,206,104,230,105,4,105,26,105,66,105,106,105,134,105,174,107,26,107,44,107,68,107,106,107,134,107,158,107,184,107,248,109,120,109,152,109,194,109,234,110,14,110,32,111,30,111,56,111,86,111,108,111,180,113,68,115,64,115,96,115,124,115,172,115,202,115,232,116,178,117,30,117,112,117,194,118,158,119,90,119,114,119,142,119,188,119,234,120,26,120,112,120,200,121,40,121,166,122,108,122,152,122,236,125,28,125,154,126,18,127,134,127,238,128,186,129,228,130,64,131,176,132,150,132,172,132,192,132,212,132,232,132,254,133,18,133,40,133,60,133,86,133,108,134,206,135,148,136,128,137,136,138,34,138,132,138,236,139,180,140,10,140,76,140,156,141,52,142,108,143,160,144,190,146,12,146,232,147,174,149,108,150,84,152,6,152,82,153,10,153,184,155,6,155,248,156,152,157,86,158,238,159,60,0,1,0,0,1,13,0,106,0,7,0,71,0,4,0,1,0,0,0,0,0,10,0,0,2,0,4,21,0,3,0,1,0,0,0,31,1,122,0,1,0,0,0,0,0,0,0,106,0,0,0,1,0,0,0,0,0,1,0,5,0,106,0,1,0,0,0,0,0,2,0,7,0,111,0,1,0,0,0,0,0,3,0,75,0,118,0,1,0,0,0,0,0,4,0,13,0,193,0,1,0,0,0,0,0,5,0,13,0,206,0,1,0,0,0,0,0,6,0,13,0,219,0,1,0,0,0,0,0,7,0,95,0,232,0,1,0,0,0,0,0,8,0,62,1,71,0,1,0,0,0,0,0,9,0,15,1,133,0,1,0,0,0,0,0,10,0,127,1,148,0,1,0,0,0,0,0,11,0,17,2,19,0,1,0,0,0,0,0,12,0,17,2,36,0,1,0,0,0,0,0,13,0,255,2,53,0,1,0,0,0,0,0,14,0,26,3,52,0,1,0,0,0,0,0,18,0,13,3,78,0,3,0,1,4,9,0,0,0,212,3,91,0,3,0,1,4,9,0,1,0,10,4,47,0,3,0,1,4,9,0,2,0,14,4,57,0,3,0,1,4,9,0,3,0,150,4,71,0,3,0,1,4,9,0,4,0,26,4,221,0,3,0,1,4,9,0,5,0,26,4,247,0,3,0,1,4,9,0,6,0,26,5,17,0,3,0,1,4,9,0,7,0,190,5,43,0,3,0,1,4,9,0,8,0,124,5,233,0,3,0,1,4,9,0,9,0,30,6,101,0,3,0,1,4,9,0,10,0,254,6,131,0,3,0,1,4,9,0,11,0,34,7,129,0,3,0,1,4,9,0,12,0,34,7,163,0,3,0,1,4,9,0,13,1,254,7,197,0,3,0,1,4,9,0,14,0,52,9,195,67,111,112,121,114,105,103,104,116,32,40,99,41,32,50,48,49,49,32,98,121,32,80,97,98,108,111,32,73,109,112,97,108,108,97,114,105,46,32,119,119,119,46,105,109,112,97,108,108,97,114,105,46,99,111,109,32,73,103,105,110,111,32,77,97,114,105,110,105,46,32,119,119,119,46,105,107,101,114,110,46,99,111,109,46,32,65,108,108,32,114,105,103,104,116,115,32,114,101,115,101,114,118,101,100,46,67,97,98,105,110,82,101,103,117,108,97,114,80,97,98,108,111,73,109,112,97,108,108,97,114,105,46,119,119,119,46,105,109,112,97,108,108,97,114,105,46,99,111,109,73,103,105,110,111,77,97,114,105,110,105,46,119,119,119,46,105,107,101,114,110,46,99,111,109,58,32,67,97,98,105,110,32,66,111,108,100,58,32,50,48,49,48,67,97,98,105,110,32,82,101,103,117,108,97,114,86,101,114,115,105,111,110,32,49,46,48,48,53,67,97,98,105,110,45,82,101,103,117,108,97,114,67,97,98,105,110,32,82,101,103,117,108,97,114,32,105,115,32,97,32,116,114,97,100,101,109,97,114,107,32,111,102,32,80,97,98,108,111,32,73,109,112,97,108,108,97,114,105,46,32,119,119,119,46,105,109,112,97,108,108,97,114,105,46,99,111,109,32,73,103,105,110,111,32,77,97,114,105,110,105,46,32,119,119,119,46,105,107,101,114,110,46,99,111,109,46,80,97,98,108,111,32,73,109,112,97,108,108,97,114,105,46,32,119,119,119,46,105,109,112,97,108,108,97,114,105,46,99,111,109,32,73,103,105,110,111,32,77,97,114,105,110,105,46,32,119,119,119,46,105,107,101,114,110,46,99,111,109,80,97,98,108,111,32,73,109,112,97,108,108,97,114,105,67,111,112,121,114,105,103,104,116,32,40,99,41,32,50,48,49,49,32,98,121,32,80,97,98,108,111,32,73,109,112,97,108,108,97,114,105,46,32,119,119,119,46,105,109,112,97,108,108,97,114,105,46,99,111,109,32,67,111,112,121,114,105,103,104,116,32,40,99,41,32,50,48,49,49,32,98,121,32,73,103,105,110,111,32,77,97,114,105,110,105,46,32,119,119,119,46,105,107,101,114,110,46,99,111,109,32,65,108,108,32,114,105,103,104,116,115,32,114,101,115,101,114,118,101,100,46,119,119,119,46,105,109,112,97,108,108,97,114,105,46,99,111,109,119,119,119,46,105,109,112,97,108,108,97,114,105,46,99,111,109,67,111,112,121,114,105,103,104,116,32,40,99,41,32,50,48,49,48,44,32,80,97,98,108,111,32,73,109,112,97,108,108,97,114,105,32,40,119,119,119,46,105,109,112,97,108,108,97,114,105,46,99,111,109,124,105,109,112,97,108,108,97,114,105,64,103,109,97,105,108,46,99,111,109,41,44,13,10,119,105,116,104,32,82,101,115,101,114,118,101,100,32,70,111,110,116,32,78,97,109,101,32,67,97,98,105,110,46,13,10,84,104,105,115,32,70,111,110,116,32,83,111,102,116,119,97,114,101,32,105,115,32,108,105,99,101,110,115,101,100,32,117,110,100,101,114,32,116,104,101,32,83,73,76,32,79,112,101,110,32,70,111,110,116,32,76,105,99,101,110,115,101,44,32,86,101,114,115,105,111,110,32,49,46,49,46,13,10,84,104,105,115,32,108,105,99,101,110,115,101,32,105,115,32,97,118,97,105,108,97,98,108,101,32,119,105,116,104,32,97,32,70,65,81,32,97,116,58,32,104,116,116,112,58,47,47,115,99,114,105,112,116,115,46,115,105,108,46,111,114,103,47,79,70,76,104,116,116,112,58,47,47,115,99,114,105,112,116,115,46,115,105,108,46,111,114,103,47,79,70,76,67,97,98,105,110,32,82,101,103,117,108,97,114,0,67,0,111,0,112,0,121,0,114,0,105,0,103,0,104,0,116,0,32,0,40,0,99,0,41,0,32,0,50,0,48,0,49,0,49,0,32,0,98,0,121,0,32,0,80,0,97,0,98,0,108,0,111,0,32,0,73,0,109,0,112,0,97,0,108,0,108,0,97,0,114,0,105,0,46,0,32,0,119,0,119,0,119,0,46,0,105,0,109,0,112,0,97,0,108,0,108,0,97,0,114,0,105,0,46,0,99,0,111,0,109,0,32,0,73,0,103,0,105,0,110,0,111,0,32,0,77,0,97,0,114,0,105,0,110,0,105,0,46,0,32,0,119,0,119,0,119,0,46,0,105,0,107,0,101,0,114,0,110,0,46,0,99,0,111,0,109,0,46,0,32,0,65,0,108,0,108,0,32,0,114,0,105,0,103,0,104,0,116,0,115,0,32,0,114,0,101,0,115,0,101,0,114,0,118,0,101,0,100,0,46,0,67,0,97,0,98,0,105,0,110,0,82,0,101,0,103,0,117,0,108,0,97,0,114,0,80,0,97,0,98,0,108,0,111,0,73,0,109,0,112,0,97,0,108,0,108,0,97,0,114,0,105,0,46,0,119,0,119,0,119,0,46,0,105,0,109,0,112,0,97,0,108,0,108,0,97,0,114,0,105,0,46,0,99,0,111,0,109,0,73,0,103,0,105,0,110,0,111,0,77,0,97,0,114,0,105,0,110,0,105,0,46,0,119,0,119,0,119,0,46,0,105,0,107,0,101,0,114,0,110,0,46,0,99,0,111,0,109,0,58,0,32,0,67,0,97,0,98,0,105,0,110,0,32,0,66,0,111,0,108,0,100,0,58,0,32,0,50,0,48,0,49,0,48,0,67,0,97,0,98,0,105,0,110,0,32,0,82,0,101,0,103,0,117,0,108,0,97,0,114,0,86,0,101,0,114,0,115,0,105,0,111,0,110,0,32,0,49,0,46,0,48,0,48,0,53,0,67,0,97,0,98,0,105,0,110,0,45,0,82,0,101,0,103,0,117,0,108,0,97,0,114,0,67,0,97,0,98,0,105,0,110,0,32,0,82,0,101,0,103,0,117,0,108,0,97,0,114,0,32,0,105,0,115,0,32,0,97,0,32,0,116,0,114,0,97,0,100,0,101,0,109,0,97,0,114,0,107,0,32,0,111,0,102,0,32,0,80,0,97,0,98,0,108,0,111,0,32,0,73,0,109,0,112,0,97,0,108,0,108,0,97,0,114,0,105,0,46,0,32,0,119,0,119,0,119,0,46,0,105,0,109,0,112,0,97,0,108,0,108,0,97,0,114,0,105,0,46,0,99,0,111,0,109,0,32,0,73,0,103,0,105,0,110,0,111,0,32,0,77,0,97,0,114,0,105,0,110,0,105,0,46,0,32,0,119,0,119,0,119,0,46,0,105,0,107,0,101,0,114,0,110,0,46,0,99,0,111,0,109,0,46,0,80,0,97,0,98,0,108,0,111,0,32,0,73,0,109,0,112,0,97,0,108,0,108,0,97,0,114,0,105,0,46,0,32,0,119,0,119,0,119,0,46,0,105,0,109,0,112,0,97,0,108,0,108,0,97,0,114,0,105,0,46,0,99,0,111,0,109,0,32,0,73,0,103,0,105,0,110,0,111,0,32,0,77,0,97,0,114,0,105,0,110,0,105,0,46,0,32,0,119,0,119,0,119,0,46,0,105,0,107,0,101,0,114,0,110,0,46,0,99,0,111,0,109,0,80,0,97,0,98,0,108,0,111,0,32,0,73,0,109,0,112,0,97,0,108,0,108,0,97,0,114,0,105,0,67,0,111,0,112,0,121,0,114,0,105,0,103,0,104,0,116,0,32,0,40,0,99,0,41,0,32,0,50,0,48,0,49,0,49,0,32,0,98,0,121,0,32,0,80,0,97,0,98,0,108,0,111,0,32,0,73,0,109,0,112,0,97,0,108,0,108,0,97,0,114,0,105,0,46,0,32,0,119,0,119,0,119,0,46,0,105,0,109,0,112,0,97,0,108,0,108,0,97,0,114,0,105,0,46,0,99,0,111,0,109,0,32,0,67,0,111,0,112,0,121,0,114,0,105,0,103,0,104,0,116,0,32,0,40,0,99,0,41,0,32,0,50,0,48,0,49,0,49,0,32,0,98,0,121,0,32,0,73,0,103,0,105,0,110,0,111,0,32,0,77,0,97,0,114,0,105,0,110,0,105,0,46,0,32,0,119,0,119,0,119,0,46,0,105,0,107,0,101,0,114,0,110,0,46,0,99,0,111,0,109,0,32,0,65,0,108,0,108,0,32,0,114,0,105,0,103,0,104,0,116,0,115,0,32,0,114,0,101,0,115,0,101,0,114,0,118,0,101,0,100,0,46,0,119,0,119,0,119,0,46,0,105,0,109,0,112,0,97,0,108,0,108,0,97,0,114,0,105,0,46,0,99,0,111,0,109,0,119,0,119,0,119,0,46,0,105,0,109,0,112,0,97,0,108,0,108,0,97,0,114,0,105,0,46,0,99,0,111,0,109,0,67,0,111,0,112,0,121,0,114,0,105,0,103,0,104,0,116,0,32,0,40,0,99,0,41,0,32,0,50,0,48,0,49,0,48,0,44,0,32,0,80,0,97,0,98,0,108,0,111,0,32,0,73,0,109,0,112,0,97,0,108,0,108,0,97,0,114,0,105,0,32,0,40,0,119,0,119,0,119,0,46,0,105,0,109,0,112,0,97,0,108,0,108,0,97,0,114,0,105,0,46,0,99,0,111,0,109,0,124,0,105,0,109,0,112,0,97,0,108,0,108,0,97,0,114,0,105,0,64,0,103,0,109,0,97,0,105,0,108,0,46,0,99,0,111,0,109,0,41,0,44,0,13,0,10,0,119,0,105,0,116,0,104,0,32,0,82,0,101,0,115,0,101,0,114,0,118,0,101,0,100,0,32,0,70,0,111,0,110,0,116,0,32,0,78,0,97,0,109,0,101,0,32,0,67,0,97,0,98,0,105,0,110,0,46,0,13,0,10,0,84,0,104,0,105,0,115,0,32,0,70,0,111,0,110,0,116,0,32,0,83,0,111,0,102,0,116,0,119,0,97,0,114,0,101,0,32,0,105,0,115,0,32,0,108,0,105,0,99,0,101,0,110,0,115,0,101,0,100,0,32,0,117,0,110,0,100,0,101,0,114,0,32,0,116,0,104,0,101,0,32,0,83,0,73,0,76,0,32,0,79,0,112,0,101,0,110,0,32,0,70,0,111,0,110,0,116,0,32,0,76,0,105,0,99,0,101,0,110,0,115,0,101,0,44,0,32,0,86,0,101,0,114,0,115,0,105,0,111,0,110,0,32,0,49,0,46,0,49,0,46,0,13,0,10,0,84,0,104,0,105,0,115,0,32,0,108,0,105,0,99,0,101,0,110,0,115,0,101,0,32,0,105,0,115,0,32,0,97,0,118,0,97,0,105,0,108,0,97,0,98,0,108,0,101,0,32,0,119,0,105,0,116,0,104,0,32,0,97,0,32,0,70,0,65,0,81,0,32,0,97,0,116,0,58,0,32,0,104,0,116,0,116,0,112,0,58,0,47,0,47,0,115,0,99,0,114,0,105,0,112,0,116,0,115,0,46,0,115,0,105,0,108,0,46,0,111,0,114,0,103,0,47,0,79,0,70,0,76,0,104,0,116,0,116,0,112,0,58,0,47,0,47,0,115,0,99,0,114,0,105,0,112,0,116,0,115,0,46,0,115,0,105,0,108,0,46,0,111,0,114,0,103,0,47,0,79,0,70,0,76,0,0,0,0,2,0,0,0,0,0,0,255,181,0,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,13,0,0,0,3,0,4,0,5,0,6,0,7,0,8,0,9,0,10,0,11,0,12,0,13,0,14,0,15,0,16,0,17,0,18,0,19,0,20,0,21,0,22,0,23,0,24,0,25,0,26,0,27,0,28,0,29,0,30,0,31,0,32,0,33,0,34,0,35,0,36,0,37,0,38,0,39,0,40,0,41,0,42,0,43,0,44,0,45,0,46,0,47,0,48,0,49,0,50,0,51,0,52,0,53,0,54,0,55,0,56,0,57,0,58,0,59,0,60,0,61,0,62,0,63,0,64,0,65,0,66,0,67,0,68,0,69,0,70,0,71,0,72,0,73,0,74,0,75,0,76,0,77,0,78,0,79,0,80,0,81,0,82,0,83,0,84,0,85,0,86,0,87,0,88,0,89,0,90,0,91,0,92,0,93,0,94,0,95,0,96,0,97,1,2,0,163,0,132,0,133,0,189,0,150,0,232,0,134,0,142,0,139,0,157,0,169,0,164,1,3,0,138,0,131,0,147,1,4,1,5,0,141,1,6,0,136,1,7,0,222,1,8,0,158,0,170,0,245,0,244,0,246,0,162,0,173,0,201,0,199,0,174,0,98,0,99,0,144,0,100,0,203,0,101,0,200,0,202,0,207,0,204,0,205,0,206,0,233,0,102,0,211,0,208,0,209,0,175,0,103,0,240,0,145,0,214,0,212,0,213,0,104,0,235,0,237,0,137,0,106,0,105,0,107,0,109,0,108,0,110,0,160,0,111,0,113,0,112,0,114,0,115,0,117,0,116,0,118,0,119,0,234,0,120,0,122,0,121,0,123,0,125,0,124,0,184,0,161,0,127,0,126,0,128,0,129,0,236,0,238,0,186,0,255,1,0,0,215,0,176,0,177,0,228,0,229,0,187,0,230,0,231,0,166,1,9,0,216,0,225,0,221,0,217,0,178,0,179,0,182,0,183,0,196,0,180,0,181,0,197,0,130,0,194,0,135,0,171,0,198,0,190,0,191,1,10,1,11,1,12,1,13,1,14,1,15,1,16,1,17,1,18,1,19,1,20,1,21,1,22,1,23,1,24,1,25,1,26,1,27,0,140,1,28,1,29,1,30,1,31,1,32,1,33,1,34,1,35,1,36,1,37,1,38,1,39,1,40,1,41,1,42,1,43,1,44,1,45,1,46,1,47,1,48,1,49,1,50,1,51,1,52,1,53,1,54,1,55,7,117,110,105,48,48,65,48,7,117,110,105,48,48,65,68,7,117,110,105,48,48,66,50,7,117,110,105,48,48,66,51,7,117,110,105,48,48,66,53,14,112,101,114,105,111,100,99,101,110,116,101,114,101,100,7,117,110,105,48,48,66,57,7,117,110,105,48,50,51,55,7,117,110,105,50,48,55,48,7,117,110,105,50,48,55,52,7,117,110,105,50,48,55,53,7,117,110,105,50,48,55,54,7,117,110,105,50,48,55,55,7,117,110,105,50,48,55,56,7,117,110,105,50,48,55,57,7,117,110,105,50,48,56,48,7,117,110,105,50,48,56,49,7,117,110,105,50,48,56,50,7,117,110,105,50,48,56,51,7,117,110,105,50,48,56,52,7,117,110,105,50,48,56,53,7,117,110,105,50,48,56,54,7,117,110,105,50,48,56,55,7,117,110,105,50,48,56,56,7,117,110,105,50,48,56,57,4,69,117,114,111,4,66,46,115,99,4,67,46,115,99,4,68,46,115,99,4,69,46,115,99,4,70,46,115,99,4,71,46,115,99,4,72,46,115,99,4,73,46,115,99,4,74,46,115,99,4,75,46,115,99,4,65,46,115,99,4,77,46,115,99,4,78,46,115,99,4,79,46,115,99,5,65,69,46,115,99,4,80,46,115,99,4,81,46,115,99,4,82,46,115,99,4,83,46,115,99,4,84,46,115,99,4,85,46,115,99,4,86,46,115,99,4,87,46,115,99,4,88,46,115,99,4,89,46,115,99,4,90,46,115,99,5,79,69,46,115,99,4,76,46,115,99,0,0,184,0,0,43,0,186,0,1,0,3,0,2,43,1,186,0,4,0,2,0,2,43,1,191,0,4,0,58,0,47,0,37,0,28,0,18,0,0,0,8,43,191,0,5,0,77,0,63,0,50,0,34,0,18,0,0,0,8,43,0,191,0,1,0,79,0,65,0,50,0,34,0,18,0,0,0,8,43,191,0,2,0,66,0,54,0,42,0,32,0,18,0,0,0,8,43,191,0,3,0,95,0,78,0,61,0,44,0,22,0,0,0,8,43,0,186,0,6,0,7,0,7,43,184,0,0,32,69,125,105,24,68,186,0,16,0,8,0,1,115,186,0,144,0,8,0,1,115,186,0,208,0,8,0,1,115,186,0,144,0,10,0,1,115,186,0,240,0,10,0,1,115,186,0,32,0,10,0,1,116,186,0,80,0,10,0,1,116,186,0,127,0,10,0,1,116,186,0,32,0,10,0,1,115,186,0,207,0,12,0,1,115,186,0,239,0,12,0,1,115,186,0,79,0,14,0,1,116,186,0,63,0,14,0,1,115,186,0,175,0,14,0,1,115,186,0,223,0,14,0,1,115,186,0,31,0,14,0,1,116,186,0,127,0,14,0,1,116,186,0,223,0,16,0,1,115,186,0,255,0,16,0,1,115,186,0,111,0,16,0,1,116,186,0,127,0,16,0,1,116,186,0,143,0,16,0,1,116,0,0,1,13,1,1,1,1,50,1,1,46,1,10,10,1,1,1,1,1,1,1,1,1,1,1,1,23,1,1,1,1,1,1,1,1,18,28,1,1,10,1,38,1,1,14,50,50,1,1,9,50,10,1,10,1,1,11,10,14,21,10,1,1,1,1,1,1,1,1,1,1,1,1,1,1,14,24,1,1,13,37,15,1,1,36,36,15,14,1,13,12,10,12,1,1,6,25,6,1,1,30,23,1,1,1,29,1,1,1,1,12,27,1,1,1,4,1,1,1,1,1,1,1,1,1,12,1,25,1,1,1,1,1,1,1,1,1,10,38,38,38,38,50,50,50,50,1,50,10,10,10,10,10,1,10,1,1,1,1,1,1,36,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,39,18,13,13,13,13,1,18,1,10,1,1,8,25,1,14,1,1,1,48,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,40,1,30,1,1,1,50,1,1,1,1,40,33,1,45,28,32,1,1,19,1,1,10,1,45,34,1,15,1,1,15,28,1,17,1,1,1,11,1,12,20,1,0,0,0,0,0,0,42,0,0,1,16,9,11,2,2,2,4,6,5,8,6,2,3,3,4,4,2,4,2,5,6,3,5,5,5,5,5,5,5,5,2,2,4,5,4,4,7,6,5,5,7,5,5,6,6,2,2,5,5,7,6,6,5,6,5,5,5,6,6,9,6,5,5,3,5,3,5,5,3,4,5,4,5,5,3,4,5,2,2,4,2,8,5,5,5,5,3,4,3,5,4,6,4,5,4,3,2,3,4,2,2,4,5,6,6,2,4,4,6,3,5,5,4,6,3,4,3,3,3,5,6,2,3,2,3,5,6,7,8,4,6,6,6,6,6,6,8,5,5,5,5,5,2,2,2,2,7,6,6,6,6,6,6,4,6,7,7,7,7,5,5,5,4,4,4,4,4,4,7,4,5,5,5,5,2,2,2,2,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,4,2,10,8,5,4,5,5,4,3,2,4,4,3,5,5,5,2,2,2,4,3,4,4,4,3,6,11,3,3,4,3,3,3,3,3,3,4,2,3,3,3,3,3,3,3,3,6,7,5,5,6,4,4,5,6,2,3,5,5,6,6,6,7,5,6,5,5,5,6,5,8,5,5,4,8,4,0,10,12,3,2,2,4,7,5,8,6,2,3,3,4,5,2,4,2,5,7,4,5,5,6,5,6,5,6,6,2,2,4,5,4,4,7,6,6,6,7,6,5,7,7,3,3,6,5,8,7,8,6,8,6,6,6,7,6,10,6,6,5,3,5,3,5,6,3,5,6,5,6,5,3,5,6,2,2,5,3,9,6,6,6,6,3,5,3,6,5,7,5,5,5,3,2,3,5,2,2,5,5,6,7,2,5,4,7,3,6,6,4,7,3,5,3,3,3,6,6,2,3,2,4,6,7,7,9,4,6,6,6,6,6,6,9,6,6,6,6,6,3,3,3,3,7,7,8,8,8,8,8,4,8,7,7,7,7,6,6,6,5,5,5,5,5,5,8,5,5,5,5,5,2,2,2,2,5,6,6,6,6,6,6,6,6,6,6,6,6,5,6,5,6,5,2,11,9,6,5,6,5,5,4,2,4,4,3,5,5,6,2,2,2,4,4,4,4,5,3,7,12,3,3,4,3,3,3,3,3,3,4,2,3,3,4,3,3,3,4,3,7,7,5,5,6,5,5,6,6,2,2,5,6,7,6,7,7,5,7,5,5,5,6,6,8,6,5,5,9,4,0,11,13,3,2,3,4,8,6,9,7,2,3,3,5,5,2,5,2,6,8,4,6,6,6,6,6,6,7,6,2,2,4,6,4,5,8,7,7,7,8,6,6,7,8,3,3,6,6,9,8,8,6,8,7,6,6,8,7,11,7,6,6,4,6,4,6,6,3,5,6,5,6,6,4,5,6,2,2,5,3,10,6,6,6,6,4,5,4,6,6,8,6,6,5,3,3,3,5,2,2,5,6,7,7,3,5,5,8,4,7,7,5,8,4,5,3,3,3,7,7,3,3,2,4,7,8,8,10,5,7,7,7,7,7,7,10,7,6,6,6,6,3,3,3,3,8,8,8,8,8,8,8,5,8,8,8,8,8,6,6,6,5,5,5,5,5,5,9,5,6,6,6,6,2,2,2,2,6,6,6,6,6,6,6,7,6,6,6,6,6,6,6,6,7,5,2,12,10,6,5,6,6,5,4,2,5,5,3,6,6,7,2,2,2,4,4,5,5,5,3,7,13,4,4,4,4,3,4,3,4,4,5,3,4,4,4,4,4,4,4,4,8,8,6,6,7,5,5,6,7,3,3,6,6,8,7,8,8,6,8,6,6,5,7,6,9,6,6,6,10,5,0,12,14,3,3,3,5,8,6,10,7,2,3,3,5,6,3,5,2,6,9,4,6,7,7,6,7,6,7,7,2,3,5,6,5,5,9,7,7,7,9,7,6,8,9,3,3,7,6,10,8,9,7,9,7,7,6,9,8,12,7,7,7,4,6,4,6,7,4,6,7,5,7,6,4,6,7,3,3,6,3,11,7,7,7,7,4,5,4,7,6,9,6,6,6,4,3,4,5,3,3,6,6,8,8,3,5,5,9,4,7,7,5,9,4,6,4,4,4,7,7,3,4,3,4,7,9,9,11,5,7,7,7,7,7,7,10,7,7,7,7,7,3,3,3,3,9,8,9,9,9,9,9,5,9,9,9,9,9,7,7,7,6,6,6,6,6,6,10,5,6,6,6,6,3,3,3,3,6,7,7,7,7,7,7,7,7,7,7,7,7,6,7,6,7,5,3,13,11,7,5,7,7,6,4,3,5,5,4,6,6,7,2,2,3,5,5,5,5,6,4,8,14,4,4,5,4,4,4,3,4,4,5,3,4,4,4,4,4,4,4,4,8,9,6,6,8,6,6,7,8,3,3,6,7,9,7,8,9,6,8,6,6,6,8,7,10,6,6,6,11,5,0,13,16,3,3,3,5,9,7,11,8,2,3,3,6,6,3,6,3,7,9,5,7,7,7,7,7,7,8,7,3,3,5,7,5,6,9,8,8,8,9,7,7,9,9,3,3,8,7,11,9,10,7,10,8,8,7,9,9,13,8,7,7,4,7,4,7,7,4,6,7,6,7,7,4,7,7,3,3,6,3,11,7,7,7,7,4,6,4,7,6,9,6,7,6,4,3,4,6,3,3,6,7,8,9,3,6,5,9,5,7,8,6,9,4,6,4,4,4,8,8,3,4,3,5,7,9,9,12,6,8,8,8,8,8,8,11,8,7,7,7,7,3,3,3,3,9,9,10,10,10,10,10,6,10,9,9,9,9,7,7,7,6,6,6,6,6,6,10,6,7,7,7,7,3,3,3,3,7,7,7,7,7,7,7,8,7,7,7,7,7,7,7,7,8,6,3,14,11,8,6,7,7,6,5,3,6,6,4,7,7,8,2,2,3,5,5,6,6,6,4,9,16,4,4,5,4,4,4,4,5,4,6,3,4,4,5,4,5,4,5,5,9,9,7,7,8,6,6,8,8,3,3,7,7,9,8,9,10,7,9,7,7,6,8,7,11,7,7,6,12,6,0,14,17,4,3,3,6,10,7,12,9,3,4,4,6,6,3,6,3,7,10,5,7,8,8,8,8,7,9,8,3,3,6,7,6,6,10,9,8,9,10,8,7,9,10,3,4,8,7,11,10,11,8,11,8,8,7,10,9,14,8,8,8,5,7,5,7,8,4,7,8,6,8,7,5,7,8,3,3,6,3,13,8,8,8,8,5,6,5,7,7,10,7,7,7,4,3,4,6,3,3,7,7,9,9,3,6,6,10,5,8,8,6,10,5,7,4,4,4,8,9,3,4,3,5,8,10,10,12,6,9,9,9,9,9,9,12,9,8,8,8,8,3,3,3,3,10,10,11,11,11,11,11,6,11,10,10,10,10,8,8,8,7,7,7,7,7,7,11,6,7,7,7,7,3,3,3,3,7,8,8,8,8,8,8,8,8,7,7,7,7,7,8,7,9,6,3,15,13,8,6,8,8,7,5,3,6,6,4,7,7,8,3,2,3,6,5,6,6,6,4,9,17,5,5,6,5,4,5,4,5,5,6,3,5,5,5,5,5,5,5,5,10,10,7,8,9,7,6,8,9,3,3,7,7,10,9,10,10,7,10,8,7,7,9,8,12,8,7,7,13,6,0,15,18,4,3,4,6,11,8,13,9,3,4,4,6,7,3,6,3,8,11,5,8,8,8,8,9,8,9,9,3,3,6,8,6,7,11,9,9,9,11,8,8,10,11,4,4,9,8,12,11,12,9,12,9,9,8,11,10,15,9,9,8,5,8,5,8,8,5,7,8,7,8,8,5,7,8,3,3,7,4,13,8,8,8,8,5,6,5,8,7,11,7,8,7,4,3,4,7,3,3,7,8,9,10,3,7,6,11,5,8,9,6,11,5,7,5,5,5,9,9,4,5,3,6,8,11,11,13,7,9,9,9,9,9,9,13,9,8,8,8,8,4,4,4,4,11,11,12,12,12,12,12,7,12,11,11,11,11,9,9,8,7,7,7,7,7,7,12,7,8,8,8,8,3,3,3,3,8,8,8,8,8,8,8,9,9,8,8,8,8,8,8,8,9,7,3,16,13,9,6,9,8,7,5,3,7,7,4,8,8,9,3,3,3,6,6,7,6,7,5,10,18,5,5,6,5,5,5,4,5,5,6,4,5,5,5,5,5,5,6,5,11,11,8,8,9,7,7,9,10,4,4,8,8,11,9,10,11,8,10,8,8,7,9,8,13,8,8,7,14,7,0,16,19,4,4,4,6,11,8,13,10,3,4,4,7,7,3,7,3,9,11,6,8,9,9,9,9,8,10,9,3,3,6,8,6,7,12,10,10,10,12,9,8,11,12,4,4,9,8,13,11,12,9,12,10,9,9,12,10,16,10,9,9,5,8,5,8,9,5,8,9,7,9,8,5,8,9,3,3,7,4,14,9,9,9,9,5,7,5,8,8,12,8,8,8,5,4,5,7,4,4,8,8,10,11,4,7,7,12,6,9,10,7,12,5,8,5,5,5,9,10,4,5,3,6,9,11,12,14,7,10,10,10,10,10,10,14,10,9,9,9,9,4,4,4,4,12,11,12,12,12,12,12,7,12,12,12,12,12,9,9,9,8,8,8,8,8,8,13,7,8,8,8,8,3,3,3,3,8,9,9,9,9,9,9,9,9,8,8,8,8,8,9,8,10,7,3,17,14,9,7,9,9,8,6,3,7,7,5,8,8,10,3,3,3,6,6,7,7,7,5,11,19,5,5,7,5,5,5,5,6,5,7,4,5,5,6,5,6,5,6,6,11,12,9,9,10,8,7,9,10,4,4,8,9,11,10,11,12,8,11,9,8,7,10,9,13,9,8,8,15,7,0,17,20,4,4,4,7,12,9,14,10,3,4,4,7,8,4,7,3,9,12,6,9,9,10,9,10,9,10,10,3,4,7,9,7,8,12,10,10,10,12,9,9,11,13,4,4,10,9,14,12,13,10,13,10,10,9,12,11,17,10,10,9,6,9,6,9,10,5,8,9,8,9,9,6,8,10,4,4,8,4,15,10,9,9,9,5,7,6,9,8,12,8,9,8,5,4,5,8,4,4,8,9,11,11,4,8,7,12,6,10,10,7,12,6,8,5,5,5,10,11,4,5,4,6,10,12,12,15,8,10,10,10,10,10,10,15,10,9,9,9,9,4,4,4,4,12,12,13,13,13,13,13,7,13,12,12,12,12,10,10,9,8,8,8,8,8,8,14,8,9,9,9,9,4,4,4,4,9,10,9,9,9,9,9,10,9,9,9,9,9,9,9,9,10,8,4,18,15,10,7,10,9,8,6,4,8,8,5,9,9,10,3,3,4,7,6,8,7,8,5,11,20,5,5,7,6,5,5,5,6,6,7,4,6,6,6,6,6,6,6,6,12,12,9,9,11,8,8,10,11,4,4,9,9,12,10,11,13,9,11,9,9,8,11,10,14,9,9,8,16,7,0,18,22,5,4,4,7,13,9,15,11,3,5,5,8,8,4,8,4,10,13,6,9,10,10,10,10,9,11,10,4,4,7,9,7,8,13,11,11,11,13,10,9,12,13,5,5,10,9,15,13,14,10,14,11,11,10,13,12,18,11,10,10,6,9,6,9,10,5,9,10,8,10,9,6,9,10,4,4,8,4,16,10,10,10,10,6,7,6,9,9,13,9,9,8,5,4,5,8,4,4,9,9,11,12,4,8,8,13,6,10,11,8,13,6,9,5,6,5,11,11,4,5,4,7,10,13,13,16,8,11,11,11,11,11,11,16,11,10,10,10,10,5,5,5,5,13,13,14,14,14,14,14,8,14,13,13,13,13,10,10,10,9,9,9,9,9,9,14,8,9,9,9,9,4,4,4,4,9,10,10,10,10,10,10,11,10,9,9,9,9,9,10,9,11,8,4,19,16,11,7,10,10,8,6,4,8,8,5,10,9,11,3,3,4,7,7,8,8,8,6,12,22,6,6,7,6,6,6,5,6,6,8,4,6,6,6,6,6,6,7,6,13,13,10,10,11,9,8,11,12,4,4,9,10,13,11,12,13,9,12,10,9,8,11,10,15,10,9,9,17,8,0,19,23,5,4,5,8,13,10,16,12,3,5,5,8,9,4,8,4,10,14,7,10,10,11,10,11,10,12,11,4,4,8,10,8,8,14,12,11,12,14,11,10,13,14,5,5,11,10,15,13,15,11,15,11,11,10,14,12,18,11,11,10,6,10,6,10,11,6,9,11,9,11,10,6,9,11,4,4,9,5,17,11,10,11,11,6,8,6,10,9,14,9,10,9,6,4,6,9,4,4,9,10,12,13,4,9,8,14,7,11,11,8,14,6,9,6,6,6,11,12,5,6,4,7,11,14,14,17,9,12,12,12,12,12,12,16,12,11,11,11,11,5,5,5,5,14,13,15,15,15,15,15,8,15,14,14,14,14,11,11,11,9,9,9,9,9,9,15,9,10,10,10,10,4,4,4,4,10,11,10,10,10,10,10,11,11,10,10,10,10,10,11,10,12,9,4,20,17,11,8,11,10,9,7,4,8,8,6,10,10,11,4,3,4,8,7,8,8,9,6,13,23,6,6,8,6,6,6,6,7,6,8,5,6,6,7,6,7,6,7,7,13,14,10,10,12,9,9,11,12,5,5,10,10,14,12,13,14,10,13,10,10,9,12,11,16,10,10,9,18,8,0,20,24,5,5,5,8,14,10,17,12,4,5,5,9,9,4,8,4,11,14,7,10,11,11,11,11,10,12,11,4,4,8,10,8,9,14,12,12,12,15,11,10,13,15,5,5,12,10,16,14,15,11,15,12,12,11,14,13,20,12,11,11,7,11,7,10,11,6,10,11,9,11,10,7,10,11,4,4,9,5,18,11,11,11,11,6,8,7,10,10,15,9,10,9,6,5,6,9,5,4,10,10,13,13,5,9,8,14,7,11,12,8,14,7,10,6,6,6,12,12,5,6,4,7,11,14,15,18,9,12,12,12,12,12,12,17,12,11,11,11,11,5,5,5,5,15,14,15,15,15,15,15,9,15,15,15,15,15,11,11,11,10,10,10,10,10,10,16,9,10,10,10,10,4,4,4,4,10,11,11,11,11,11,11,12,11,10,10,10,10,10,12,10,12,9,4,21,18,12,8,11,11,9,7,4,9,9,6,11,10,12,4,3,4,8,8,9,8,9,6,14,24,6,6,8,7,6,6,6,7,6,9,5,7,7,7,7,7,7,7,7,14,15,11,11,13,10,9,12,13,5,5,11,11,14,12,13,15,10,13,11,10,9,13,11,17,11,10,10,18,9,0,21,25,5,5,5,8,15,11,18,13,4,5,5,9,10,5,9,4,11,15,7,11,11,12,11,12,11,13,12,4,5,9,11,8,9,15,13,13,13,15,12,11,14,16,5,5,12,11,17,15,16,12,16,13,12,11,15,14,20,13,12,12,7,11,7,11,12,6,10,12,10,12,11,7,10,12,4,4,9,5,18,12,12,12,12,7,9,7,11,10,15,10,11,10,6,5,6,10,5,5,10,11,13,14,5,10,9,15,7,12,13,9,15,7,10,6,7,6,12,13,5,6,5,8,12,15,15,19,9,13,13,13,13,13,13,18,13,12,12,12,12,5,5,5,5,15,15,16,16,16,16,16,9,16,15,15,15,15,12,12,12,10,10,10,10,10,10,17,10,11,11,11,11,4,4,4,4,11,12,12,12,12,12,12,12,12,11,11,11,11,11,12,11,13,10,4,22,19,12,9,12,12,10,7,4,9,9,6,11,11,12,4,4,5,8,8,9,9,10,6,14,25,7,7,9,7,6,7,6,7,7,9,5,7,7,8,7,7,7,8,7,15,15,11,11,13,10,10,12,14,5,5,11,11,15,13,14,16,11,14,11,11,10,13,12,18,11,11,10,19,9,0,22,26,6,5,5,9,15,11,18,13,4,6,6,9,10,5,9,4,12,16,8,12,12,12,12,13,11,13,13,4,5,9,11,9,10,16,14,13,14,16,12,12,15,16,6,6,13,11,18,15,17,13,17,13,13,12,16,14,21,13,12,12,7,12,7,11,12,7,11,12,10,12,11,7,11,12,5,5,10,5,19,12,12,12,12,7,9,7,12,11,16,10,11,10,7,5,7,10,5,5,11,11,14,15,5,10,9,16,8,12,13,9,16,7,11,7,7,7,13,14,5,7,5,8,12,16,16,19,10,14,14,14,14,14,14,19,14,12,12,12,12,6,6,6,6,16,15,17,17,17,17,17,10,17,16,16,16,16,12,13,12,11,11,11,11,11,11,18,10,11,11,11,11,5,5,5,5,11,12,12,12,12,12,12,13,13,12,12,12,12,11,13,11,14,10,5,24,20,13,9,12,12,10,8,5,10,10,6,12,11,13,4,4,5,9,8,10,9,10,7,15,26,7,7,9,7,7,7,6,8,7,9,5,7,7,8,7,8,7,8,8,15,16,12,12,14,11,10,13,14,5,5,12,12,16,14,15,16,11,15,12,11,10,14,12,18,12,11,11,20,10,0,23,28,6,5,6,9,16,12,19,14,4,6,6,10,11,5,10,5,12,16,8,12,13,13,12,13,12,14,13,5,5,9,12,9,10,17,14,14,14,17,13,12,15,17,6,6,13,12,19,16,18,13,18,14,13,12,17,15,22,14,13,13,8,12,8,12,13,7,11,13,10,13,12,8,11,13,5,5,10,5,20,13,13,13,13,7,10,8,12,11,17,11,12,11,7,5,7,10,5,5,11,12,14,16,5,10,10,17,8,13,14,10,17,8,11,7,7,7,14,14,5,7,5,9,13,16,17,20,10,14,14,14,14,14,14,20,14,13,13,13,13,6,6,6,6,17,16,18,18,18,18,18,10,18,17,17,17,17,13,13,13,11,11,11,11,11,11,18,10,12,12,12,12,5,5,5,5,12,13,13,13,13,13,13,14,13,12,12,12,12,12,13,12,14,10,5,25,21,13,10,13,13,11,8,5,10,10,7,12,12,14,4,4,5,9,9,10,10,11,7,16,28,7,7,9,8,7,7,7,8,7,10,5,8,8,8,8,8,8,9,8,16,17,12,12,14,11,11,13,15,6,6,12,12,16,14,15,17,12,15,12,12,11,14,13,19,12,12,11,21,10,0,24,29,6,5,6,10,17,12,20,15,4,6,6,10,11,5,10,5,13,17,9,13,13,13,13,14,12,15,14,5,5,10,12,10,11,17,15,14,15,17,13,13,16,18,6,6,14,12,19,17,18,14,18,14,14,13,17,15,23,14,14,13,8,13,8,12,14,7,12,13,11,13,12,8,12,13,5,5,11,6,21,13,13,13,13,8,10,8,13,12,17,11,12,11,7,6,7,11,5,5,11,12,15,16,6,11,10,17,8,14,14,10,17,8,12,7,7,7,14,15,6,7,5,9,14,17,18,21,11,15,15,15,15,15,15,21,15,13,13,13,13,6,6,6,6,17,17,18,18,18,18,18,11,18,17,17,17,17,14,14,13,12,12,12,12,12,12,19,11,12,12,12,12,5,5,5,5,12,13,13,13,13,13,13,14,14,13,13,13,13,12,14,12,15,11,5,26,21,14,10,14,13,11,8,5,11,11,7,13,12,14,4,4,5,10,9,11,10,11,7,16,29,8,8,10,8,7,8,7,8,8,10,6,8,8,9,8,8,8,9,8,17,17,13,13,15,12,11,14,16,6,6,13,13,17,15,16,18,12,16,13,12,11,15,13,20,13,12,12,22,11,0,25,30,6,6,6,10,18,13,21,15,5,7,7,11,12,5,11,5,13,18,9,13,14,14,14,14,13,15,14,5,5,10,13,10,11,18,15,15,15,18,14,13,17,19,6,6,14,13,20,18,19,14,19,15,15,13,18,16,24,15,14,14,8,13,8,13,14,8,12,14,11,14,13,8,12,14,5,5,11,6,22,14,14,14,14,8,10,8,13,12,18,12,13,12,7,6,7,11,6,6,12,13,16,17,6,11,11,18,9,14,15,11,18,8,12,8,8,8,15,16,6,8,5,9,14,18,18,22,11,15,15,15,15,15,15,22,15,14,14,14,14,6,6,6,6,18,18,19,19,19,19,19,11,19,18,18,18,18,14,14,14,12,12,12,12,12,12,20,11,13,13,13,13,5,5,5,5,13,14,14,14,14,14,14,15,14,13,13,13,13,13,15,13,15,11,5,27,23,15,10,14,14,12,9,5,11,11,7,13,13,15,5,4,5,10,9,11,11,12,8,17,30,8,8,10,8,8,8,7,9,8,11,6,8,8,9,8,9,8,9,9,18,18,13,13,16,12,11,15,16,6,6,13,13,18,15,17,19,13,17,13,13,12,16,14,21,14,13,12,23,11,0,26,31,7,6,6,10,18,13,22,16,5,7,7,11,12,6,11,5,14,19,9,14,14,15,14,15,13,16,15,5,6,11,13,11,11,19,16,16,16,19,14,14,17,19,7,7,15,13,21,18,20,15,20,16,15,14,19,17,25,16,15,14,9,14,9,13,15,8,12,14,12,14,13,9,13,14,6,6,12,6,23,15,14,14,14,8,11,9,14,13,19,12,13,12,8,6,8,12,6,6,12,13,16,18,6,12,11,19,9,15,16,11,19,9,13,8,8,8,15,16,6,8,6,10,15,19,19,23,12,16,16,16,16,16,16,22,16,14,14,14,14,7,7,7,7,19,18,20,20,20,20,20,11,20,19,19,19,19,15,15,14,12,12,12,12,12,12,21,12,13,13,13,13,6,6,6,6,13,15,14,14,14,14,14,15,15,14,14,14,14,13,15,13,16,12,6,28,23,15,11,15,14,12,9,6,12,12,8,14,13,15,5,4,6,10,10,12,11,12,8,18,31,8,8,11,9,8,8,8,9,8,11,6,9,9,9,9,9,9,10,9,18,19,14,14,16,13,12,15,17,6,6,14,14,19,16,17,19,13,17,14,13,12,16,15,22,14,13,13,24,11,0,27,32,7,6,7,11,19,14,23,17,5,7,7,12,13,6,11,6,14,19,10,14,15,15,15,15,14,16,15,6,6,11,14,11,12,20,17,16,17,20,15,14,18,20,7,7,16,14,22,19,21,15,21,16,16,14,20,17,26,16,15,15,9,14,9,14,15,8,13,15,12,15,14,9,13,15,6,6,12,6,24,15,15,15,15,9,11,9,14,13,20,13,14,13,8,6,8,12,6,6,13,14,17,18,6,12,11,19,9,15,16,11,19,9,13,8,8,8,16,17,6,8,6,10,15,19,20,24,12,17,17,17,17,17,17,23,17,15,15,15,15,7,7,7,7,20,19,21,21,21,21,21,12,21,20,20,20,20,15,15,15,13,13,13,13,13,13,22,12,14,14,14,14,6,6,6,6,14,15,15,15,15,15,15,16,15,14,14,14,14,14,16,14,17,12,6,29,24,16,11,15,15,13,9,6,12,12,8,14,14,16,5,5,6,11,10,12,11,12,8,18,32,9,9,11,9,8,9,8,9,9,12,6,9,9,10,9,9,9,10,9,19,20,14,15,17,13,12,16,17,7,7,14,14,19,17,18,20,14,18,15,14,13,17,15,23,15,14,13,25,12,0,28,34,7,6,7,11,20,14,24,17,5,7,7,12,13,6,12,6,15,20,10,15,15,16,15,16,14,17,16,6,6,11,14,11,12,20,17,17,17,20,16,15,19,21,7,7,16,14,23,20,22,16,22,17,16,15,20,18,27,17,16,15,9,15,9,14,16,8,13,16,13,16,14,9,14,15,6,6,13,7,25,16,15,16,16,9,12,9,15,14,20,13,14,13,8,6,8,13,6,6,13,14,18,19,7,13,12,20,10,16,17,12,20,9,14,9,9,8,17,17,7,8,6,10,16,20,20,25,13,17,17,17,17,17,17,24,17,16,16,16,16,7,7,7,7,20,20,22,22,22,22,22,12,22,20,20,20,20,16,16,16,13,13,13,13,13,13,22,13,14,14,14,14,6,6,6,6,14,16,15,15,15,15,15,17,16,15,15,15,15,14,16,14,17,13,6,30,25,16,12,16,15,13,10,6,12,12,8,15,14,17,5,5,6,11,11,12,12,13,9,19,34,9,9,11,9,9,9,8,10,9,12,7,9,9,10,9,10,9,10,10,20,20,15,15,18,14,13,16,18,7,7,15,15,20,17,19,21,14,19,15,14,13,18,16,23,15,14,14,26,12,0,29,35,7,7,7,12,20,15,24,18,5,8,8,12,13,6,12,6,15,21,10,15,16,16,16,16,15,18,17,6,6,12,15,12,13,21,18,17,18,21,16,15,19,22,7,7,17,15,24,20,22,17,22,17,17,15,21,19,28,17,16,16,9,15,9,15,16,9,14,16,13,16,15,10,14,16,6,6,13,7,25,16,16,16,16,9,12,10,15,14,21,14,15,14,9,7,9,13,7,7,14,15,18,20,7,13,12,21,10,16,17,12,21,10,14,9,9,9,17,18,7,9,6,11,16,21,21,26,13,18,18,18,18,18,18,25,18,16,16,16,16,7,7,7,7,21,20,22,22,22,22,22,13,22,21,21,21,21,16,17,16,14,14,14,14,14,14,23,13,15,15,15,15,6,6,6,6,15,16,16,16,16,16,16,17,17,15,15,15,15,15,17,15,18,13,6,31,26,17,12,16,16,14,10,6,13,13,8,15,15,17,5,5,6,11,11,13,12,13,9,20,35,9,9,12,10,9,9,8,10,9,13,7,10,10,10,10,10,10,11,10,20,21,16,16,18,14,13,17,19,7,7,15,15,21,18,19,22,15,19,16,15,14,18,16,24,16,15,14,27,13,0,30,36,8,7,7,12,21,15,25,18,5,8,8,13,14,6,13,6,16,21,11,16,16,17,16,17,15,18,17,6,6,12,15,12,13,22,18,18,18,22,17,16,20,22,8,8,17,15,24,21,23,17,23,18,18,16,22,19,29,18,17,16,10,16,10,15,17,9,14,17,14,17,15,10,15,16,6,6,13,7,26,17,17,17,17,10,12,10,16,15,22,14,15,14,9,7,9,14,7,7,14,15,19,20,7,14,13,22,10,17,18,13,22,10,15,9,9,9,18,19,7,9,6,11,17,22,22,27,13,18,18,18,18,18,18,26,18,17,17,17,17,8,8,8,8,22,21,23,23,23,23,23,13,23,22,22,22,22,17,17,17,14,14,14,14,14,14,24,14,15,15,15,15,6,6,6,6,16,17,17,17,17,17,17,18,17,16,16,16,16,15,17,15,18,14,6,32,27,18,12,17,16,14,11,6,13,13,9,16,15,18,6,5,6,12,11,13,13,14,9,20,36,10,10,12,10,9,10,9,10,10,13,7,10,10,11,10,10,10,11,10,21,22,16,16,19,15,14,17,19,7,7,16,16,21,18,20,22,15,20,16,15,14,19,17,25,16,15,14,28,13,0,31,37,8,7,8,12,22,16,26,19,6,8,8,13,14,7,13,6,16,22,11,16,17,17,17,18,16,19,18,6,7,13,16,13,14,22,19,19,19,23,17,16,21,23,8,8,18,16,25,22,24,18,24,19,18,17,22,20,30,19,18,17,10,16,10,16,18,9,15,17,14,17,16,10,15,17,7,7,14,7,27,17,17,17,17,10,13,10,16,15,22,15,16,15,9,7,9,14,7,7,15,16,19,21,7,14,13,22,11,17,18,13,22,10,15,9,10,9,18,19,7,9,7,11,17,22,23,27,14,19,19,19,19,19,19,27,19,17,17,17,17,8,8,8,8,23,22,24,24,24,24,24,14,24,23,23,23,23,18,18,17,15,15,15,15,15,15,25,14,16,16,16,16,7,7,7,7,16,17,17,17,17,17,17,18,18,16,16,16,16,16,18,16,19,14,7,33,28,18,13,18,17,15,11,7,14,14,9,16,16,18,6,5,7,12,12,14,13,14,9,21,37,10,10,13,10,10,10,9,11,10,13,7,10,10,11,10,11,10,12,11,22,23,17,17,20,15,14,18,20,7,7,16,17,22,19,21,23,16,21,17,16,15,19,17,26,17,16,15,29,14,0,32,38,8,7,8,13,23,16,27,20,6,8,8,14,15,7,14,7,17,23,11,17,18,18,17,18,16,19,18,7,7,13,16,13,14,23,20,19,20,23,18,17,22,24,8,8,18,16,26,23,25,18,25,19,19,17,23,21,31,19,18,18,10,17,10,16,18,10,15,18,15,18,16,11,16,17,7,7,14,8,28,18,18,18,18,10,13,11,17,16,23,15,16,15,10,7,10,15,7,7,15,16,20,22,7,15,14,23,11,18,19,14,23,11,16,10,10,10,19,20,8,10,7,12,18,23,23,28,14,20,20,20,20,20,20,28,20,18,18,18,18,8,8,8,8,23,23,25,25,25,25,25,14,25,23,23,23,23,18,18,18,15,15,15,15,15,15,26,15,16,16,16,16,7,7,7,7,17,18,18,18,18,18,18,19,18,17,17,17,17,16,19,16,20,15,7,34,29,19,13,18,18,15,11,7,14,14,9,17,16,19,6,5,7,13,12,14,14,15,10,22,38,10,10,13,11,10,10,9,11,10,14,8,11,11,11,11,11,11,12,11,23,23,17,17,20,16,15,19,21,8,8,17,17,23,20,21,24,16,21,17,16,15,20,18,27,17,16,15,29,14,0,33,40,8,7,8,13,23,17,28,20,6,9,9,14,15,7,14,7,18,24,12,17,18,18,18,19,17,20,19,7,7,13,17,13,15,24,20,20,20,24,18,17,22,25,8,8,19,17,27,23,25,19,25,20,19,18,24,21,32,20,19,18,11,17,11,17,19,10,16,18,15,18,17,11,16,18,7,7,15,8,29,18,18,18,18,11,14,11,17,16,24,16,17,16,10,8,10,15,7,7,16,17,21,22,8,15,14,24,12,19,20,14,24,11,16,10,10,10,20,21,8,10,7,12,19,24,24,29,15,20,20,20,20,20,20,29,20,18,18,18,18,8,8,8,8,24,23,25,25,25,25,25,14,25,24,24,24,24,19,19,18,16,16,16,16,16,16,26,15,17,17,17,17,7,7,7,7,17,18,18,18,18,18,18,20,19,17,17,17,17,17,19,17,20,15,7,35,30,19,14,19,18,16,12,7,15,15,10,17,17,20,6,6,7,13,13,15,14,15,10,22,40,11,11,13,11,10,11,10,11,11,14,8,11,11,12,11,11,11,12,11,23,24,18,18,21,16,15,19,21,8,8,17,18,24,20,22,24,17,22,18,17,16,21,19,28,18,17,16,30,15,0,34,41,9,8,8,14,24,17,29,21,6,9,9,14,16,7,14,7,18,24,12,18,19,19,18,19,17,21,19,7,7,14,17,14,15,25,21,20,21,25,19,18,23,25,9,9,20,17,28,24,26,19,26,21,20,18,25,22,33,20,19,19,11,18,11,17,19,10,16,19,15,19,17,11,17,18,7,7,15,8,30,19,19,19,19,11,14,11,18,17,25,16,17,16,10,8,10,15,8,8,16,17,21,23,8,16,14,24,12,19,20,14,24,11,17,10,11,10,20,21,8,10,7,13,19,24,25,30,15,21,21,21,21,21,21,29,21,19,19,19,19,9,9,9,9,25,24,26,26,26,26,26,15,26,25,25,25,25,19,19,19,16,16,16,16,16,16,27,15,17,17,17,17,7,7,7,7,18,19,19,19,19,19,19,20,19,18,18,18,18,17,20,17,21,15,7,36,31,20,14,19,19,16,12,7,15,15,10,18,17,20,6,6,7,13,13,15,14,16,10,23,41,11,11,14,11,10,11,10,12,11,15,8,11,11,12,11,12,11,13,12,24,25,18,18,21,17,16,20,22,8,8,18,18,24,21,23,25,17,23,18,17,16,21,19,28,18,17,16,31,15,0,35,42,9,8,8,14,25,18,29,21,6,9,9,15,16,8,15,7,19,25,12,18,19,20,19,20,18,21,20,7,8,14,18,14,15,25,22,21,22,25,19,18,24,26,9,9,20,18,28,25,27,20,27,21,20,19,25,23,34,21,20,19,11,18,11,18,20,11,17,19,16,19,18,12,17,19,7,7,16,8,31,20,19,20,20,11,14,12,18,17,25,17,18,16,10,8,10,16,8,8,17,18,22,24,8,16,15,25,12,20,21,15,25,12,17,11,11,11,21,22,8,11,8,13,20,25,26,31,16,22,22,22,22,22,22,30,22,19,19,19,19,9,9,9,9,25,25,27,27,27,27,27,15,27,25,25,25,25,20,20,20,17,17,17,17,17,17,28,16,18,18,18,18,7,7,7,7,18,20,19,19,19,19,19,21,20,18,18,18,18,18,20,18,22,16,7,37,32,20,14,20,19,16,12,7,16,16,10,18,18,21,7,6,8,14,13,16,15,16,11,24,42,11,11,14,12,11,11,10,12,11,15,8,12,12,13,12,12,12,13,12,25,25,19,19,22,17,16,20,23,8,8,18,19,25,21,23,26,18,23,19,18,16,22,20,29,19,18,17,32,15,0,36,43,9,8,9,14,25,19,30,22,7,9,9,15,17,8,15,7,19,26,13,19,20,20,19,20,18,22,21,7,8,15,18,15,16,26,22,21,22,26,20,19,24,27,9,9,21,18,29,25,28,21,28,22,21,19,26,23,35,22,20,20,12,19,12,18,20,11,17,20,16,20,18,12,18,20,8,8,16,9,32,20,20,20,20,12,15,12,19,18,26,17,18,17,11,8,11,16,8,8,17,18,23,24,8,16,15,26,13,20,21,15,26,12,18,11,11,11,21,22,9,11,8,13,20,26,26,32,16,22,22,22,22,22,22,31,22,20,20,20,20,9,9,9,9,26,25,28,28,28,28,28,16,28,26,26,26,26,20,21,20,17,17,17,17,17,17,29,16,18,18,18,18,8,8,8,8,19,20,20,20,20,20,20,21,21,19,19,19,19,18,21,18,22,16,8,39,32,21,15,20,20,17,13,8,16,16,11,19,18,21,7,6,8,14,14,16,15,17,11,24,43,12,12,15,12,11,12,10,12,12,16,9,12,12,13,12,12,12,13,12,25,26,19,19,23,18,17,21,23,9,9,19,19,26,22,24,27,18,24,19,18,17,23,20,30,19,18,17,33,16,0,37,44,9,8,9,15,26,19,31,23,7,10,10,16,17,8,16,8,20,26,13,19,20,21,20,21,19,23,21,8,8,15,19,15,16,27,23,22,23,27,21,19,25,28,9,9,21,19,30,26,28,21,28,22,22,20,27,24,36,22,21,20,12,19,12,19,21,11,18,21,17,21,19,12,18,20,8,8,17,9,32,21,20,21,21,12,15,12,19,18,27,18,19,17,11,8,11,17,8,8,18,19,23,25,9,17,16,27,13,21,22,16,27,12,18,11,11,11,22,23,9,11,8,14,21,27,27,33,17,23,23,23,23,23,23,32,23,21,21,21,21,9,9,9,9,27,26,28,28,28,28,28,16,28,27,27,27,27,21,21,21,18,18,18,18,18,18,30,17,19,19,19,19,8,8,8,8,19,21,20,20,20,20,20,22,21,19,19,19,19,19,21,19,23,17,8,40,33,22,15,21,20,17,13,8,17,17,11,20,19,22,7,6,8,15,14,17,16,17,11,25,44,12,12,15,12,11,12,11,13,12,16,9,12,12,13,12,13,12,14,13,26,27,20,20,23,18,17,22,24,9,9,19,20,26,23,25,27,19,25,20,19,17,23,21,31,20,19,18,34,16,0,38,46,10,9,9,15,27,20,32,23,7,10,10,16,18,8,16,8,20,27,13,20,21,21,21,22,19,23,22,8,8,15,19,15,17,27,23,23,23,28,21,20,26,28,10,10,22,19,31,27,29,22,29,23,22,20,28,24,37,23,22,21,12,20,12,19,22,12,18,21,17,21,19,13,19,21,8,8,17,9,33,21,21,21,21,12,16,13,20,19,28,18,19,18,11,9,11,17,9,9,18,19,24,26,9,17,16,27,13,21,23,16,27,13,19,12,12,12,22,24,9,12,8,14,21,27,28,34,17,23,23,23,23,23,23,33,23,21,21,21,21,10,10,10,10,28,27,29,29,29,29,29,17,29,28,28,28,28,22,22,21,18,18,18,18,18,18,30,17,19,19,19,19,8,8,8,8,20,21,21,21,21,21,21,23,22,20,20,20,20,19,22,19,23,17,8,41,34,22,16,22,21,18,13,8,17,17,11,20,19,23,7,6,8,15,14,17,16,17,12,26,46,12,12,15,13,12,12,11,13,12,16,9,13,13,14,13,13,13,14,13,27,28,20,20,24,19,17,22,25,9,9,20,20,27,23,25,28,19,25,20,19,18,24,21,32,21,19,18,35,17,0,39,47,10,9,9,16,27,20,33,24,7,10,10,17,18,8,17,8,21,28,14,20,21,22,21,22,20,24,22,8,8,16,20,16,17,28,24,23,24,28,22,20,26,29,10,10,23,20,32,27,30,22,30,24,23,21,28,25,38,23,22,21,13,20,13,20,22,12,19,22,18,22,20,13,19,21,8,8,17,9,34,22,21,22,22,13,16,13,20,19,28,18,20,18,12,9,12,18,9,9,19,20,24,26,9,18,16,28,14,22,23,17,28,13,19,12,12,12,23,24,9,12,8,14,22,28,28,35,18,24,24,24,24,24,24,34,24,22,22,22,22,10,10,10,10,28,27,30,30,30,30,30,17,30,28,28,28,28,22,22,22,19,19,19,19,19,19,31,18,20,20,20,20,8,8,8,8,20,22,21,21,21,21,21,23,22,20,20,20,20,20,23,20,24,18,8,42,35,23,16,22,21,18,14,8,17,17,11,21,20,23,7,7,8,15,15,17,17,18,12,26,47,13,13,16,13,12,13,11,14,13,17,9,13,13,14,13,14,13,15,14,27,28,21,21,25,19,18,23,25,9,9,20,21,28,24,26,29,20,26,21,20,18,24,22,33,21,20,19,36,17,0,40,48,10,9,10,16,28,21,34,24,7,10,10,17,19,9,17,8,21,29,14,21,22,22,22,23,20,24,23,8,9,16,20,16,18,29,25,24,25,29,22,21,27,30,10,10,23,20,32,28,31,23,31,24,23,21,29,26,39,24,23,22,13,21,13,20,23,12,19,22,18,22,20,13,20,22,8,8,18,9,35,22,22,22,22,13,17,13,21,20,29,19,20,19,12,9,12,18,9,9,19,20,25,27,9,18,17,29,14,23,24,17,29,13,20,12,12,12,24,25,10,12,9,15,23,29,29,35,18,25,25,25,25,25,25,35,25,22,22,22,22,10,10,10,10,29,28,31,31,31,31,31,18,31,29,29,29,29,23,23,22,19,19,19,19,19,19,32,18,20,20,20,20,8,8,8,8,21,22,22,22,22,22,22,24,23,21,21,21,21,20,23,20,25,18,8,43,36,23,17,23,22,19,14,8,18,18,12,21,20,24,7,7,9,16,15,18,17,18,12,27,48,13,13,16,13,12,13,12,14,13,17,9,13,13,14,13,14,13,15,14,28,29,21,21,25,20,18,23,26,10,10,21,21,28,25,27,30,20,27,21,20,19,25,22,33,22,20,19,37,18,0,41,49,10,9,10,16,29,21,34,25,7,11,11,17,19,9,17,8,22,29,15,21,22,23,22,23,21,25,23,8,9,17,21,17,18,30,25,24,25,30,23,21,28,31,10,10,24,21,33,29,31,23,31,25,24,22,30,26,40,25,23,23,13,22,13,21,23,12,20,23,19,23,21,14,20,22,9,9,18,10,36,23,23,23,23,13,17,14,21,20,30,19,21,19,12,9,12,19,9,9,20,21,26,28,10,19,17,30,14,23,24,17,30,14,20,12,13,12,24,26,10,12,9,15,23,29,30,36,18,25,25,25,25,25,25,35,25,23,23,23,23,10,10,10,10,30,29,31,31,31,31,31,18,31,30,30,30,30,23,23,23,20,20,20,20,20,20,33,19,21,21,21,21,9,9,9,9,21,23,23,23,23,23,23,24,23,21,21,21,21,21,24,21,25,19,9,44,37,24,17,23,23,19,14,9,18,18,12,22,21,24,8,7,9,16,16,18,17,19,13,28,49,13,13,17,14,13,13,12,14,13,18,10,14,14,15,14,14,14,15,14,29,30,22,22,26,20,19,24,26,10,10,22,22,29,25,27,30,21,27,22,21,19,26,23,34,22,21,20,38,18,0,42,50,11,9,10,17,30,22,35,26,8,11,11,18,19,9,18,9,22,30,15,22,23,23,23,24,21,26,24,9,9,17,21,17,19,30,26,25,26,31,23,22,28,31,11,11,24,21,34,30,32,24,32,25,25,22,30,27,41,25,24,23,14,22,14,21,24,13,20,23,19,23,22,14,21,23,9,9,19,10,37,23,23,23,23,13,17,14,22,21,30,20,21,20,13,10,13,19,9,9,20,21,26,28,10,19,18,30,15,24,25,18,30,14,21,13,13,13,25,26,10,13,9,16,24,30,31,37,19,26,26,26,26,26,26,36,26,23,23,23,23,11,11,11,11,31,30,32,32,32,32,32,18,32,30,30,30,30,24,24,23,20,20,20,20,20,20,34,19,22,22,22,22,9,9,9,9,22,23,23,23,23,23,23,25,24,22,22,22,22,21,24,21,26,19,9,45,38,25,17,24,23,20,15,9,19,19,12,22,21,25,8,7,9,17,16,19,18,19,13,28,50,14,14,17,14,13,14,12,15,14,18,10,14,14,15,14,15,14,16,15,30,31,22,23,26,21,19,24,27,10,10,22,22,30,26,28,31,21,28,23,21,20,26,24,35,23,21,20,39,18,0,43,52,11,10,10,17,30,22,36,26,8,11,11,18,20,9,18,9,23,31,15,23,24,24,23,24,22,26,25,9,9,17,22,17,19,31,26,26,26,31,24,22,29,32,11,11,25,22,35,30,33,25,33,26,25,23,31,28,42,26,24,24,14,23,14,22,24,13,21,24,20,24,22,14,21,23,9,9,19,10,38,24,24,24,24,14,18,14,23,21,31,20,22,20,13,10,13,20,10,10,21,22,27,29,10,20,18,31,15,24,26,18,31,14,21,13,13,13,25,27,10,13,9,16,24,31,31,38,19,26,26,26,26,26,26,37,26,24,24,24,24,11,11,11,11,31,30,33,33,33,33,33,19,33,31,31,31,31,24,25,24,21,21,21,21,21,21,34,20,22,22,22,22,9,9,9,9,22,24,24,24,24,24,24,25,25,23,23,23,23,22,25,22,26,20,9,46,39,25,18,24,24,20,15,9,19,19,13,23,22,26,8,7,9,17,16,19,18,20,13,29,52,14,14,18,14,13,14,12,15,14,19,10,14,14,15,14,15,14,16,15,30,31,23,23,27,21,20,25,28,10,10,23,23,31,26,29,32,22,29,23,22,20,27,24,36,23,22,21,40,19,0,44,53,11,10,11,18,31,23,37,27,8,11,11,19,20,10,19,9,23,31,16,23,24,25,24,25,22,27,25,9,10,18,22,18,19,32,27,26,27,32,24,23,30,33,11,11,25,22,36,31,34,25,34,27,26,23,32,28,43,26,25,24,14,23,14,22,25,13,21,24,20,24,23,15,22,24,9,9,20,10,39,25,24,25,25,14,18,15,23,22,32,21,22,21,13,10,13,20,10,10,21,22,28,30,10,20,19,32,15,25,26,19,32,15,22,13,14,13,26,27,10,13,10,16,25,32,32,39,20,27,27,27,27,27,27,38,27,24,24,24,24,11,11,11,11,32,31,34,34,34,34,34,19,34,32,32,32,32,25,25,25,21,21,21,21,21,21,35,20,23,23,23,23,9,9,9,9,23,25,24,24,24,24,24,26,25,23,23,23,23,22,26,22,27,20,9,47,40,26,18,25,24,21,15,9,20,20,13,23,22,26,8,7,10,17,17,20,19,20,13,30,53,14,14,18,15,14,14,13,15,14,19,10,15,15,16,15,15,15,16,15,31,32,24,24,28,22,20,26,28,11,11,23,24,31,27,29,33,22,29,24,22,21,28,25,37,24,22,21,41,19,0,45,54,11,10,11,18,32,23,38,28,8,12,12,19,21,10,19,9,24,32,16,24,25,25,24,26,23,27,26,9,10,18,23,18,20,32,28,27,28,33,25,24,30,34,11,11,26,23,37,32,35,26,35,27,26,24,33,29,44,27,26,25,15,24,15,23,25,14,22,25,20,25,23,15,22,24,10,10,20,11,39,25,25,25,25,14,19,15,24,22,33,21,23,21,13,10,13,20,10,10,21,23,28,30,10,21,19,32,16,25,27,19,32,15,22,14,14,14,27,28,11,14,10,17,25,32,33,40,20,28,28,28,28,28,28,39,28,25,25,25,25,11,11,11,11,33,32,35,35,35,35,35,20,35,33,33,33,33,26,26,25,22,22,22,22,22,22,36,20,23,23,23,23,10,10,10,10,23,25,25,25,25,25,25,27,26,24,24,24,24,23,26,23,28,20,10,48,41,26,19,26,25,21,16,10,20,20,13,24,23,27,8,8,10,18,17,20,19,21,14,30,54,14,15,18,15,14,14,13,16,15,19,11,15,15,16,15,16,15,17,16,32,33,24,24,28,22,21,26,29,11,11,24,24,32,28,30,33,23,30,24,23,21,28,25,38,24,23,22,41,20,0,46,55,12,10,11,18,32,24,39,28,8,12,12,20,21,10,20,9,24,33,16,24,25,26,25,26,23,28,26,9,10,19,23,19,20,33,28,27,28,33,25,24,31,34,12,12,27,23,37,32,35,26,35,28,27,25,33,30,45,28,26,25,15,24,15,24,26,14,22,26,21,26,24,15,23,25,10,10,21,11,40,26,25,26,26,15,19,16,24,23,33,22,23,22,14,11,14,21,10,10,22,23,29,31,11,21,19,33,16,26,27,20,33,15,23,14,14,14,27,29,11,14,10,17,26,33,34,41,21,28,28,28,28,28,28,40,28,25,25,25,25,12,12,12,12,33,32,35,35,35,35,35,20,35,33,33,33,33,26,26,26,22,22,22,22,22,22,37,21,24,24,24,24,10,10,10,10,24,26,25,25,25,25,25,27,26,24,24,24,24,23,27,23,28,21,10,49,41,27,19,26,25,22,16,10,21,21,13,24,23,27,9,8,10,18,17,21,20,21,14,31,55,15,15,19,15,14,15,13,16,15,20,11,15,16,16,15,16,15,17,16,32,33,25,25,29,23,21,27,30,11,11,24,25,33,28,31,34,23,31,25,24,22,29,26,38,25,23,22,42,20,0,47,56,12,11,11,19,33,24,39,29,9,12,12,20,22,10,20,10,25,34,17,25,26,26,25,27,24,29,27,10,10,19,24,19,21,34,29,28,29,34,26,25,32,35,12,12,27,24,38,33,36,27,36,28,27,25,34,30,46,28,27,26,15,25,15,24,27,14,23,26,21,26,24,16,23,25,10,10,21,11,41,26,26,26,26,15,19,16,25,23,34,22,24,22,14,11,14,21,11,11,22,24,29,32,11,21,20,34,16,26,28,20,34,16,23,14,15,14,28,29,11,14,10,17,26,34,34,42,21,29,29,29,29,29,29,41,29,26,26,26,26,12,12,12,12,34,33,36,36,36,36,36,21,36,34,34,34,34,27,27,26,23,23,23,23,23,23,38,21,24,24,24,24,10,10,10,10,24,26,26,26,26,26,26,28,27,25,25,25,25,24,27,24,29,21,10,50,42,27,19,27,26,22,17,10,21,21,14,25,24,28,9,8,10,19,18,21,20,22,14,32,56,15,15,19,16,14,15,14,16,15,20,11,16,16,17,16,16,16,17,16,33,34,25,25,30,23,22,27,30,11,11,25,25,33,29,31,35,24,31,25,24,22,29,26,39,25,24,23,43,21,0,48,58,12,11,12,19,34,25,40,29,9,13,13,20,22,10,20,10,26,34,17,25,26,27,26,27,24,29,27,10,10,19,24,19,21,35,30,29,30,35,27,25,32,36,12,12,28,24,39,34,37,27,37,29,28,26,35,31,47,29,27,26,16,25,16,25,27,15,23,27,22,27,25,16,24,26,10,10,22,11,42,27,26,27,27,15,20,16,25,24,35,23,24,23,14,11,14,22,11,11,23,24,30,32,11,22,20,35,17,27,29,20,35,16,24,15,15,15,28,30,11,15,10,18,27,34,35,42,22,30,30,30,30,30,30,42,30,27,27,27,27,12,12,12,12,35,34,37,37,37,37,37,21,37,35,35,35,35,27,27,27,23,23,23,23,23,23,38,22,25,25,25,25,10,10,10,10,25,27,26,26,26,26,26,28,27,25,25,25,25,24,28,24,30,22,10,51,43,28,20,27,26,23,17,10,21,21,14,25,24,29,9,8,10,19,18,21,20,22,15,32,58,15,16,20,16,15,15,14,17,16,21,11,16,16,17,16,17,16,18,17,34,35,26,26,30,24,22,28,31,12,12,25,26,34,29,32,36,24,32,26,25,23,30,27,40,26,24,23,44,21,0,49,59,12,11,12,20,35,25,41,30,9,13,13,21,23,11,21,10,26,35,17,26,27,27,27,28,25,30,28,10,11,20,25,20,22,35,30,29,30,36,27,26,33,37,13,13,28,25,40,35,38,28,38,30,29,26,35,32,48,29,28,27,16,26,16,25,28,15,24,27,22,27,25,16,24,27,10,10,22,12,43,27,27,27,27,16,20,17,26,24,36,23,25,23,15,11,15,22,11,11,23,25,31,33,11,22,21,35,17,28,29,21,35,16,24,15,15,15,29,30,12,15,11,18,28,35,36,43,22,30,30,30,30,30,30,42,30,27,27,27,27,13,13,13,13,36,35,38,38,38,38,38,22,38,36,36,36,36,28,28,27,24,24,24,24,24,24,39,22,25,25,25,25,10,10,10,10,25,27,27,27,27,27,27,29,28,26,26,26,26,25,28,25,30,22,10,52,44,29,20,28,27,23,17,10,22,22,14,26,25,29,9,8,11,19,19,22,21,23,15,33,59,16,16,20,16,15,16,14,17,16,21,12,16,17,18,16,17,16,18,17,34,36,26,26,31,24,22,29,32,12,12,26,26,35,30,33,36,25,33,26,25,23,31,27,41,26,25,24,45,22,0,50,60,13,11,12,20,35,26,42,31,9,13,13,21,23,11,21,10,27,36,18,26,27,28,27,28,25,30,29,10,11,20,25,20,22,36,31,30,31,36,28,26,34,37,13,13,29,25,41,35,38,29,38,30,29,27,36,32,49,30,28,27,16,26,16,26,28,15,24,28,23,28,26,17,25,27,11,11,22,12,44,28,28,28,28,16,21,17,26,25,36,24,25,24,15,11,15,23,11,11,24,25,31,34,12,23,21,36,17,28,30,21,36,17,25,15,16,15,30,31,12,15,11,19,28,36,36,44,22,31,31,31,31,31,31,43,31,28,28,28,28,13,13,13,13,36,35,38,38,38,38,38,22,38,36,36,36,36,28,29,28,24,24,24,24,24,24,40,23,26,26,26,26,11,11,11,11,26,28,28,28,28,28,28,30,29,26,26,26,26,25,29,25,31,23,11,54,45,29,21,28,27,24,18,11,22,22,15,26,25,30,9,8,11,20,19,22,21,23,15,34,60,16,16,20,17,15,16,15,17,16,22,12,17,17,18,17,17,17,19,17,35,36,27,27,31,25,23,29,32,12,12,26,27,36,31,33,37,26,33,27,26,24,31,28,42,27,25,24,46,22,0,0,1,0,2,0,2,1,1,1,1,1,0,0,0,0,18,5,230,0,248,8,255,0,8,0,8,255,254,0,9,0,9,255,253,0,10,0,10,255,253,0,11,0,11,255,253,0,12,0,12,255,253,0,13,0,13,255,253,0,14,0,14,255,253,0,15,0,15,255,252,0,16,0,16,255,252,0,17,0,17,255,252,0,18,0,18,255,251,0,19,0,19,255,251,0,20,0,20,255,251,0,21,0,21,255,251,0,22,0,22,255,250,0,23,0,22,255,250,0,24,0,23,255,250,0,25,0,25,255,250,0,26,0,25,255,250,0,27,0,26,255,249,0,28,0,27,255,249,0,29,0,28,255,249,0,30,0,29,255,249,0,31,0,30,255,248,0,32,0,31,255,248,0,33,0,32,255,248,0,34,0,33,255,248,0,35,0,33,255,248,0,36,0,35,255,247,0,37,0,36,255,247,0,38,0,37,255,247,0,39,0,38,255,247,0,40,0,38,255,246,0,41,0,40,255,246,0,42,0,41,255,246,0,43,0,42,255,246,0,44,0,42,255,245,0,45,0,43,255,245,0,46,0,45,255,245,0,47,0,45,255,245,0,48,0,47,255,244,0,49,0,47,255,244,0,50,0,48,255,243,0,51,0,49,255,243,0,52,0,50,255,243,0,53,0,51,255,243,0,54,0,52,255,242,0,55,0,54,255,242,0,56,0,54,255,242,0,57,0,55,255,242,0,58,0,55,255,241,0,59,0,57,255,241,0,60,0,59,255,241,0,61,0,59,255,241,0,62,0,60,255,240,0,63,0,60,255,240,0,64,0,61,255,240,0,65,0,63,255,240,0,66,0,64,255,239,0,67,0,65,255,239,0,68,0,65,255,239,0,69,0,66,255,239,0,70,0,68,255,238,0,71,0,69,255,238,0,72,0,69,255,238,0,73,0,70,255,238,0,74,0,71,255,237,0,75,0,72,255,237,0,76,0,74,255,237,0,77,0,74,255,237,0,78,0,75,255,236,0,79,0,77,255,236,0,80,0,77,255,236,0,81,0,79,255,236,0,82,0,79,255,235,0,83,0,80,255,235,0,84,0,81,255,235,0,85,0,82,255,235,0,86,0,83,255,234,0,87,0,84,255,234,0,88,0,85,255,234,0,89,0,86,255,234,0,90,0,87,255,233,0,91,0,87,255,233,0,92,0,88,255,233,0,93,0,90,255,233,0,94,0,91,255,232,0,95,0,92,255,232,0,96,0,92,255,232,0,97,0,93,255,232,0,98,0,94,255,231,0,99,0,96,255,231,0,100,0,97,255,231,0,101,0,97,255,231,0,102,0,98,255,230,0,103,0,99,255,230,0,104,0,101,255,230,0,105,0,101,255,230,0,106,0,102,255,229,0,107,0,103,255,229,0,108,0,104,255,229,0,109,0,106,255,229,0,110,0,106,255,228,0,111,0,107,255,228,0,112,0,108,255,228,0,113,0,109,255,228,0,114,0,110,255,227,0,115,0,111,255,227,0,116,0,112,255,227,0,117,0,112,255,227,0,118,0,114,255,226,0,119,0,115,255,226,0,120,0,115,255,226,0,121,0,117,255,226,0,122,0,118,255,225,0,123,0,119,255,225,0,124,0,119,255,225,0,125,0,120,255,225,0,126,0,122,255,224,0,127,0,123,255,224,0,128,0,124,255,224,0,129,0,124,255,224,0,130,0,125,255,223,0,131,0,125,255,223,0,132,0,128,255,223,0,133,0,129,255,223,0,134,0,129,255,222,0,135,0,130,255,222,0,136,0,130,255,222,0,137,0,133,255,222,0,138,0,133,255,221,0,139,0,134,255,221,0,140,0,135,255,221,0,141,0,135,255,221,0,142,0,137,255,220,0,143,0,138,255,220,0,144,0,139,255,220,0,145,0,140,255,220,0,146,0,141,255,219,0,147,0,142,255,219,0,148,0,142,255,219,0,149,0,144,255,219,0,150,0,144,255,218,0,151,0,146,255,218,0,152,0,147,255,218,0,153,0,147,255,218,0,154,0,149,255,217,0,155,0,149,255,217,0,156,0,151,255,217,0,157,0,151,255,217,0,158,0,152,255,216,0,159,0,153,255,216,0,160,0,154,255,216,0,161,0,156,255,216,0,162,0,156,255,215,0,163,0,157,255,215,0,164,0,157,255,215,0,165,0,159,255,215,0,166,0,161,255,214,0,167,0,161,255,214,0,168,0,162,255,214,0,169,0,162,255,214,0,170,0,164,255,213,0,171,0,166,255,213,0,172,0,166,255,213,0,173,0,167,255,213,0,174,0,167,255,212,0,175,0,169,255,212,0,176,0,170,255,212,0,177,0,171,255,212,0,178,0,172,255,211,0,179,0,172,255,211,0,180,0,174,255,211,0,181,0,174,255,211,0,182,0,176,255,210,0,183,0,176,255,210,0,184,0,177,255,210,0,185,0,179,255,210,0,186,0,179,255,209,0,187,0,180,255,209,0,188,0,181,255,209,0,189,0,183,255,209,0,190,0,183,255,208,0,191,0,184,255,208,0,192,0,185,255,208,0,193,0,186,255,208,0,194,0,188,255,207,0,195,0,188,255,207,0,196,0,189,255,207,0,197,0,189,255,207,0,198,0,190,255,206,0,199,0,193,255,206,0,200,0,193,255,206,0,201,0,194,255,206,0,202,0,194,255,205,0,203,0,195,255,205,0,204,0,198,255,205,0,205,0,198,255,205,0,206,0,199,255,204,0,207,0,199,255,204,0,208,0,200,255,204,0,209,0,201,255,204,0,210,0,203,255,203,0,211,0,204,255,203,0,212,0,204,255,203,0,213,0,206,255,203,0,214,0,206,255,202,0,215,0,207,255,202,0,216,0,208,255,202,0,217,0,209,255,202,0,218,0,211,255,201,0,219,0,211,255,201,0,220,0,212,255,201,0,221,0,213,255,201,0,222,0,214,255,200,0,223,0,215,255,200,0,224,0,216,255,200,0,225,0,217,255,200,0,226,0,217,255,199,0,227,0,219,255,199,0,228,0,220,255,199,0,229,0,221,255,199,0,230,0,221,255,198,0,231,0,222,255,198,0,232,0,224,255,198,0,233,0,225,255,198,0,234,0,226,255,197,0,235,0,226,255,197,0,236,0,227,255,197,0,237,0,229,255,197,0,238,0,230,255,196,0,239,0,231,255,196,0,240,0,231,255,196,0,241,0,232,255,196,0,242,0,233,255,195,0,243,0,235,255,195,0,244,0,236,255,195,0,245,0,236,255,195,0,246,0,237,255,194,0,247,0,238,255,194,0,248,0,239,255,194,0,249,0,240,255,194,0,250,0,241,255,193,0,251,0,242,255,193,0,252,0,243,255,193,0,253,0,244,255,193,0,254,0,244,255,192,0,255,0,246,255,192,0,248,8,255,0,8,0,8,255,254,0,9,0,9,255,253,0,10,0,10,255,253,0,11,0,11,255,253,0,12,0,12,255,253,0,13,0,13,255,253,0,14,0,14,255,253,0,15,0,15,255,252,0,16,0,16,255,252,0,17,0,17,255,252,0,18,0,18,255,251,0,19,0,19,255,251,0,20,0,20,255,251,0,21,0,21,255,251,0,22,0,22,255,250,0,23,0,22,255,250,0,24,0,23,255,250,0,25,0,25,255,250,0,26,0,25,255,250,0,27,0,26,255,249,0,28,0,27,255,249,0,29,0,28,255,249,0,30,0,29,255,249,0,31,0,30,255,248,0,32,0,31,255,248,0,33,0,32,255,248,0,34,0,33,255,248,0,35,0,33,255,248,0,36,0,35,255,247,0,37,0,36,255,247,0,38,0,37,255,247,0,39,0,38,255,247,0,40,0,38,255,246,0,41,0,40,255,246,0,42,0,41,255,246,0,43,0,42,255,246,0,44,0,42,255,245,0,45,0,43,255,245,0,46,0,45,255,245,0,47,0,45,255,245,0,48,0,47,255,244,0,49,0,47,255,244,0,50,0,48,255,243,0,51,0,49,255,243,0,52,0,50,255,243,0,53,0,51,255,243,0,54,0,52,255,242,0,55,0,54,255,242,0,56,0,54,255,242,0,57,0,55,255,242,0,58,0,55,255,241,0,59,0,57,255,241,0,60,0,59,255,241,0,61,0,59,255,241,0,62,0,60,255,240,0,63,0,60,255,240,0,64,0,61,255,240,0,65,0,63,255,240,0,66,0,64,255,239,0,67,0,65,255,239,0,68,0,65,255,239,0,69,0,66,255,239,0,70,0,68,255,238,0,71,0,69,255,238,0,72,0,69,255,238,0,73,0,70,255,238,0,74,0,71,255,237,0,75,0,72,255,237,0,76,0,74,255,237,0,77,0,74,255,237,0,78,0,75,255,236,0,79,0,77,255,236,0,80,0,77,255,236,0,81,0,79,255,236,0,82,0,79,255,235,0,83,0,80,255,235,0,84,0,81,255,235,0,85,0,82,255,235,0,86,0,83,255,234,0,87,0,84,255,234,0,88,0,85,255,234,0,89,0,86,255,234,0,90,0,87,255,233,0,91,0,87,255,233,0,92,0,88,255,233,0,93,0,90,255,233,0,94,0,91,255,232,0,95,0,92,255,232,0,96,0,92,255,232,0,97,0,93,255,232,0,98,0,94,255,231,0,99,0,96,255,231,0,100,0,97,255,231,0,101,0,97,255,231,0,102,0,98,255,230,0,103,0,99,255,230,0,104,0,101,255,230,0,105,0,101,255,230,0,106,0,102,255,229,0,107,0,103,255,229,0,108,0,104,255,229,0,109,0,106,255,229,0,110,0,106,255,228,0,111,0,107,255,228,0,112,0,108,255,228,0,113,0,109,255,228,0,114,0,110,255,227,0,115,0,111,255,227,0,116,0,112,255,227,0,117,0,112,255,227,0,118,0,114,255,226,0,119,0,115,255,226,0,120,0,115,255,226,0,121,0,117,255,226,0,122,0,118,255,225,0,123,0,119,255,225,0,124,0,119,255,225,0,125,0,120,255,225,0,126,0,122,255,224,0,127,0,123,255,224,0,128,0,124,255,224,0,129,0,124,255,224,0,130,0,125,255,223,0,131,0,125,255,223,0,132,0,128,255,223,0,133,0,129,255,223,0,134,0,129,255,222,0,135,0,130,255,222,0,136,0,130,255,222,0,137,0,133,255,222,0,138,0,133,255,221,0,139,0,134,255,221,0,140,0,135,255,221,0,141,0,135,255,221,0,142,0,137,255,220,0,143,0,138,255,220,0,144,0,139,255,220,0,145,0,140,255,220,0,146,0,141,255,219,0,147,0,142,255,219,0,148,0,142,255,219,0,149,0,144,255,219,0,150,0,144,255,218,0,151,0,146,255,218,0,152,0,147,255,218,0,153,0,147,255,218,0,154,0,149,255,217,0,155,0,149,255,217,0,156,0,151,255,217,0,157,0,151,255,217,0,158,0,152,255,216,0,159,0,153,255,216,0,160,0,154,255,216,0,161,0,156,255,216,0,162,0,156,255,215,0,163,0,157,255,215,0,164,0,157,255,215,0,165,0,159,255,215,0,166,0,161,255,214,0,167,0,161,255,214,0,168,0,162,255,214,0,169,0,162,255,214,0,170,0,164,255,213,0,171,0,166,255,213,0,172,0,166,255,213,0,173,0,167,255,213,0,174,0,167,255,212,0,175,0,169,255,212,0,176,0,170,255,212,0,177,0,171,255,212,0,178,0,172,255,211,0,179,0,172,255,211,0,180,0,174,255,211,0,181,0,174,255,211,0,182,0,176,255,210,0,183,0,176,255,210,0,184,0,177,255,210,0,185,0,179,255,210,0,186,0,179,255,209,0,187,0,180,255,209,0,188,0,181,255,209,0,189,0,183,255,209,0,190,0,183,255,208,0,191,0,184,255,208,0,192,0,185,255,208,0,193,0,186,255,208,0,194,0,188,255,207,0,195,0,188,255,207,0,196,0,189,255,207,0,197,0,189,255,207,0,198,0,190,255,206,0,199,0,193,255,206,0,200,0,193,255,206,0,201,0,194,255,206,0,202,0,194,255,205,0,203,0,195,255,205,0,204,0,198,255,205,0,205,0,198,255,205,0,206,0,199,255,204,0,207,0,199,255,204,0,208,0,200,255,204,0,209,0,201,255,204,0,210,0,203,255,203,0,211,0,204,255,203,0,212,0,204,255,203,0,213,0,206,255,203,0,214,0,206,255,202,0,215,0,207,255,202,0,216,0,208,255,202,0,217,0,209,255,202,0,218,0,211,255,201,0,219,0,211,255,201,0,220,0,212,255,201,0,221,0,213,255,201,0,222,0,214,255,200,0,223,0,215,255,200,0,224,0,216,255,200,0,225,0,217,255,200,0,226,0,217,255,199,0,227,0,219,255,199,0,228,0,220,255,199,0,229,0,221,255,199,0,230,0,221,255,198,0,231,0,222,255,198,0,232,0,224,255,198,0,233,0,225,255,198,0,234,0,226,255,197,0,235,0,226,255,197,0,236,0,227,255,197,0,237,0,229,255,197,0,238,0,230,255,196,0,239,0,231,255,196,0,240,0,231,255,196,0,241,0,232,255,196,0,242,0,233,255,195,0,243,0,235,255,195,0,244,0,236,255,195,0,245,0,236,255,195,0,246,0,237,255,194,0,247,0,238,255,194,0,248,0,239,255,194,0,249,0,240,255,194,0,250,0,241,255,193,0,251,0,242,255,193,0,252,0,243,255,193,0,253,0,244,255,193,0,254,0,244,255,192,0,255,0,246,255,192,0,0, \ No newline at end of file diff --git a/src/Nazara/Utility/SimpleTextDrawer.cpp b/src/Nazara/Utility/SimpleTextDrawer.cpp index 855a2ec0b..8e5577f48 100644 --- a/src/Nazara/Utility/SimpleTextDrawer.cpp +++ b/src/Nazara/Utility/SimpleTextDrawer.cpp @@ -6,13 +6,11 @@ #include #include -///TODO: Listener de font (cas où l'atlas a changé) - NzSimpleTextDrawer::NzSimpleTextDrawer() : m_color(NzColor::White), m_style(nzTextStyle_Regular) { - // SetFont(NzFont::GetDefault()); + SetFont(NzFont::GetDefault()); } NzSimpleTextDrawer::~NzSimpleTextDrawer() @@ -91,7 +89,6 @@ void NzSimpleTextDrawer::SetText(const NzString& str) NzSimpleTextDrawer NzSimpleTextDrawer::Draw(const NzString& str, unsigned int characterSize, nzUInt32 style, const NzColor& color) { - ///FIXME: Sans default font ça n'a aucun intérêt NzSimpleTextDrawer drawer; drawer.SetCharacterSize(characterSize); drawer.SetColor(color); From c2ac3281bf4558b65f0f669d129de7d9351468d9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 18 Jan 2015 12:12:32 +0100 Subject: [PATCH 188/233] Fixed text bounds Former-commit-id: 9339ed907125ecf5186a86e8c943bf3197e11571 --- src/Nazara/Graphics/TextSprite.cpp | 6 +++++- src/Nazara/Utility/SimpleTextDrawer.cpp | 21 ++++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index 356327d5d..622ed0298 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -380,7 +380,11 @@ void NzTextSprite::UpdateBoundingVolume() const NzVector3f down = m_scene->GetDown(); NzVector3f right = m_scene->GetRight(); - m_boundingVolume.Set(NzVector3f(0.f), static_cast(m_localBounds.width)*right + static_cast(m_localBounds.height)*down); + NzRectf bounds(m_localBounds); + NzVector2f max = bounds.GetMaximum(); + NzVector2f min = bounds.GetMinimum(); + + m_boundingVolume.Set(min.x*right + min.y*down, max.x*right + max.y*down); } if (!m_transformMatrixUpdated) diff --git a/src/Nazara/Utility/SimpleTextDrawer.cpp b/src/Nazara/Utility/SimpleTextDrawer.cpp index 8e5577f48..64ac5a3ad 100644 --- a/src/Nazara/Utility/SimpleTextDrawer.cpp +++ b/src/Nazara/Utility/SimpleTextDrawer.cpp @@ -213,7 +213,6 @@ void NzSimpleTextDrawer::UpdateGlyphs() const // "Curseur" de dessin NzVector2ui drawPos(0, m_characterSize); - NzVector2ui lastPos(0, 0); m_glyphs.reserve(size); nzUInt32 previousCharacter = 0; @@ -294,9 +293,25 @@ void NzSimpleTextDrawer::UpdateGlyphs() const m_glyphs.push_back(glyph); - lastPos = drawPos; drawPos.x += advance; } - m_bounds.ExtendTo(lastPos); + // Calcul des bornes + if (!m_glyphs.empty()) + { + for (unsigned int i = 0; i < m_glyphs.size(); ++i) + { + Glyph& glyph = m_glyphs[i]; + + for (unsigned int j = 0; j < 4; ++j) + { + NzVector2ui corner(std::ceil(glyph.corners[j].x), std::ceil(glyph.corners[j].y)); + + if (i == 0 && j == 0) + m_bounds.Set(corner.x, corner.y, 0, 0); + else + m_bounds.ExtendTo(corner); + } + } + } } From 81e38d1431e41e34bde5d56b0a728c7e8703d6d8 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 18 Jan 2015 12:19:05 +0100 Subject: [PATCH 189/233] Fixed comment Former-commit-id: 02e09bb9eac10da9693c07db00c837784a6edf4e --- include/Nazara/Renderer/Enums.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Renderer/Enums.hpp b/include/Nazara/Renderer/Enums.hpp index 0065f55b2..87fb7ce95 100644 --- a/include/Nazara/Renderer/Enums.hpp +++ b/include/Nazara/Renderer/Enums.hpp @@ -187,7 +187,7 @@ enum nzSamplerWrap enum nzShaderUniform { - ///FIXME: Virer EyePosition, SceneAmbient et TargetSize de l'énumération (ils n'ont rien à faire dans le module de rendu) + ///FIXME: Virer EyePosition et SceneAmbient de l'énumération (ils n'ont rien à faire dans le module de rendu) nzShaderUniform_EyePosition, nzShaderUniform_InvProjMatrix, nzShaderUniform_InvTargetSize, From 0b1f10bf723671f6daf0d44cfa1ce9e880858fa0 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 18 Jan 2015 12:20:32 +0100 Subject: [PATCH 190/233] Alphabetical commit Former-commit-id: a62b1812e59371e4ca7f1d77bf438859514e0ac7 --- include/Nazara/Renderer/Enums.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/Nazara/Renderer/Enums.hpp b/include/Nazara/Renderer/Enums.hpp index 87fb7ce95..7100d198e 100644 --- a/include/Nazara/Renderer/Enums.hpp +++ b/include/Nazara/Renderer/Enums.hpp @@ -35,11 +35,11 @@ enum nzBlendFunc enum nzFaceFilling { - nzFaceFilling_Point, - nzFaceFilling_Line, nzFaceFilling_Fill, + nzFaceFilling_Line, + nzFaceFilling_Point, - nzFaceFilling_Max = nzFaceFilling_Fill + nzFaceFilling_Max = nzFaceFilling_Point }; enum nzFaceSide From a6183fae69afb9ba1f3ced8f9d84ddc834548c70 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 18 Jan 2015 14:30:30 +0100 Subject: [PATCH 191/233] Added missing SkeletonRef typedef Former-commit-id: 7c6671664dcc28e2fc8f2a0beeacb76b80828f4f --- include/Nazara/Utility/Skeleton.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/Nazara/Utility/Skeleton.hpp b/include/Nazara/Utility/Skeleton.hpp index ca327b96c..7832c266d 100644 --- a/include/Nazara/Utility/Skeleton.hpp +++ b/include/Nazara/Utility/Skeleton.hpp @@ -9,10 +9,16 @@ #include #include +#include #include #include #include +class NzSkeleton; + +using NzSkeletonConstRef = NzResourceRef; +using NzSkeletonRef = NzResourceRef; + struct NzSkeletonImpl; class NAZARA_API NzSkeleton : public NzResource From 8f9ea9db170354855f813650e7546408bc178151 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 18 Jan 2015 23:59:01 +0100 Subject: [PATCH 192/233] Added ResourceListenerWrapper This class wraps the call to Resource::AddResourceListener/RemoveResourceListener using RAII and help a lot with some of the dependencies. Thanks to this, the render queues now handle their resources listening properly. Former-commit-id: 7f215ffa4ccadcc4f44f777656970e92ce01087a --- include/Nazara/Audio/SoundBuffer.hpp | 3 + .../Nazara/Core/ResourceListenerWrapper.hpp | 45 +++++ .../Nazara/Core/ResourceListenerWrapper.inl | 108 ++++++++++++ .../Nazara/Graphics/DeferredRenderQueue.hpp | 56 +++++-- .../Nazara/Graphics/ForwardRenderQueue.hpp | 88 ++++++++-- include/Nazara/Graphics/Material.hpp | 3 + include/Nazara/Renderer/Context.hpp | 3 + include/Nazara/Renderer/RenderBuffer.hpp | 3 + include/Nazara/Renderer/Shader.hpp | 3 + include/Nazara/Renderer/Texture.hpp | 3 + include/Nazara/Renderer/UberShader.hpp | 3 + include/Nazara/Utility/Animation.hpp | 6 +- include/Nazara/Utility/Buffer.hpp | 3 + include/Nazara/Utility/Font.hpp | 5 +- include/Nazara/Utility/Image.hpp | 3 + include/Nazara/Utility/IndexBuffer.hpp | 3 + include/Nazara/Utility/Mesh.hpp | 8 +- include/Nazara/Utility/SimpleTextDrawer.hpp | 3 +- include/Nazara/Utility/SkeletalMesh.hpp | 4 + include/Nazara/Utility/Skeleton.hpp | 3 + include/Nazara/Utility/StaticMesh.hpp | 3 + include/Nazara/Utility/SubMesh.hpp | 3 + include/Nazara/Utility/VertexBuffer.hpp | 3 + include/Nazara/Utility/VertexDeclaration.hpp | 3 + src/Nazara/Graphics/DeferredGeometryPass.cpp | 17 +- src/Nazara/Graphics/DeferredRenderQueue.cpp | 104 ++++-------- src/Nazara/Graphics/ForwardRenderQueue.cpp | 119 +++++--------- .../Graphics/ForwardRenderTechnique.cpp | 155 ++++++++++-------- src/Nazara/Graphics/SkinningManager.cpp | 36 ++-- src/Nazara/Renderer/RenderTexture.cpp | 65 ++++---- src/Nazara/Renderer/Renderer.cpp | 105 ++++++------ src/Nazara/Utility/Mesh.cpp | 31 +--- src/Nazara/Utility/SimpleTextDrawer.cpp | 13 +- 33 files changed, 602 insertions(+), 411 deletions(-) create mode 100644 include/Nazara/Core/ResourceListenerWrapper.hpp create mode 100644 include/Nazara/Core/ResourceListenerWrapper.inl diff --git a/include/Nazara/Audio/SoundBuffer.hpp b/include/Nazara/Audio/SoundBuffer.hpp index 346d26e68..7f5480cfd 100644 --- a/include/Nazara/Audio/SoundBuffer.hpp +++ b/include/Nazara/Audio/SoundBuffer.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -25,7 +26,9 @@ struct NzSoundBufferParams class NzSound; class NzSoundBuffer; +using NzSoundBufferConstListener = NzResourceListenerWrapper; using NzSoundBufferConstRef = NzResourceRef; +using NzSoundBufferListener = NzResourceListenerWrapper; using NzSoundBufferLoader = NzResourceLoader; using NzSoundBufferRef = NzResourceRef; diff --git a/include/Nazara/Core/ResourceListenerWrapper.hpp b/include/Nazara/Core/ResourceListenerWrapper.hpp new file mode 100644 index 000000000..fc60a2430 --- /dev/null +++ b/include/Nazara/Core/ResourceListenerWrapper.hpp @@ -0,0 +1,45 @@ +// 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 + +#pragma once + +#ifndef NAZARA_RESOURCELISTENERWRAPPER_HPP +#define NAZARA_RESOURCELISTENERWRAPPER_HPP + +#include +#include +#include +#include + +template +class NzResourceListenerWrapper +{ + static_assert(std::is_base_of::value, "ResourceRef should only be used with resource type"); + + public: + NzResourceListenerWrapper(NzResourceListener* listener, int index = 0, T* resource = nullptr); + NzResourceListenerWrapper(const NzResourceListenerWrapper& listener); + NzResourceListenerWrapper(NzResourceListenerWrapper&& listener); + ~NzResourceListenerWrapper(); + + bool IsValid() const; + void Reset(T* resource = nullptr); + + operator bool() const; + operator T*() const; + T* operator->() const; + + NzResourceListenerWrapper& operator=(T* resource); + NzResourceListenerWrapper& operator=(const NzResourceListenerWrapper& listener); + NzResourceListenerWrapper& operator=(NzResourceListenerWrapper&& listener); + + private: + T* m_resource; + NzResourceListener* m_listener; + int m_index; +}; + +#include + +#endif // NAZARA_RESOURCELISTENERWRAPPER_HPP diff --git a/include/Nazara/Core/ResourceListenerWrapper.inl b/include/Nazara/Core/ResourceListenerWrapper.inl new file mode 100644 index 000000000..4b88cf594 --- /dev/null +++ b/include/Nazara/Core/ResourceListenerWrapper.inl @@ -0,0 +1,108 @@ +// 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 + +template +NzResourceListenerWrapper::NzResourceListenerWrapper(NzResourceListener* listener, int index, T* resource) : +m_resource(nullptr), +m_listener(listener), +m_index(index) +{ + Reset(resource); +} + +template +NzResourceListenerWrapper::NzResourceListenerWrapper(const NzResourceListenerWrapper& listener) : +m_resource(nullptr), +m_listener(listener.m_listener), +m_index(listener.m_index) +{ + Reset(listener.m_resource); +} + +template +NzResourceListenerWrapper::NzResourceListenerWrapper(NzResourceListenerWrapper&& listener) : +m_resource(listener.m_resource), +m_listener(listener.m_listener), +m_index(listener.m_index) +{ + listener.m_resource = nullptr; +} + +template +NzResourceListenerWrapper::~NzResourceListenerWrapper() +{ + Reset(nullptr); +} + +template +bool NzResourceListenerWrapper::IsValid() const +{ + return m_resource != nullptr; +} + +template +void NzResourceListenerWrapper::Reset(T* resource) +{ + if (resource) + resource->AddResourceListener(m_listener, m_index); + + if (m_resource) + m_resource->RemoveResourceListener(m_listener); + + m_resource = resource; +} + +template +NzResourceListenerWrapper::operator bool() const +{ + return IsValid(); +} + +template +NzResourceListenerWrapper::operator T*() const +{ + return m_resource; +} + +template +T* NzResourceListenerWrapper::operator->() const +{ + return m_resource; +} + +template +NzResourceListenerWrapper& NzResourceListenerWrapper::operator=(T* resource) +{ + Reset(resource); + + return *this; +} + +template +NzResourceListenerWrapper& NzResourceListenerWrapper::operator=(const NzResourceListenerWrapper& listener) +{ + m_index = listener.m_index; + m_listener = listener.m_listener; + Reset(listener.m_resource); + + return *this; +} + +template +NzResourceListenerWrapper& NzResourceListenerWrapper::operator=(NzResourceListenerWrapper&& listener) +{ + Reset(); + + m_index = listener.m_index; + m_listener = listener.m_listener; + m_resource = listener.m_resource; + + listener.m_resource = nullptr; + + return *this; +} + +#include diff --git a/include/Nazara/Graphics/DeferredRenderQueue.hpp b/include/Nazara/Graphics/DeferredRenderQueue.hpp index 8ad147042..8f9d92ddc 100644 --- a/include/Nazara/Graphics/DeferredRenderQueue.hpp +++ b/include/Nazara/Graphics/DeferredRenderQueue.hpp @@ -11,22 +11,22 @@ #include #include #include +#include #include #include +#include #include +#include #include #include class NzForwardRenderQueue; -class NzMaterial; -class NzSkeletalMesh; -class NzStaticMesh; class NAZARA_API NzDeferredRenderQueue : public NzAbstractRenderQueue, NzResourceListener { public: NzDeferredRenderQueue(NzForwardRenderQueue* forwardQueue); - ~NzDeferredRenderQueue(); + ~NzDeferredRenderQueue() = default; void AddDrawable(const NzDrawable* drawable) override; void AddLight(const NzLight* light) override; @@ -35,28 +35,48 @@ class NAZARA_API NzDeferredRenderQueue : public NzAbstractRenderQueue, NzResourc void Clear(bool fully); - struct BatchedModelMaterialComparator - { - bool operator()(const NzMaterial* mat1, const NzMaterial* mat2); - }; - - struct BatchedSpriteMaterialComparator - { - bool operator()(const NzMaterial* mat1, const NzMaterial* mat2); - }; - struct MeshDataComparator { bool operator()(const NzMeshData& data1, const NzMeshData& data2); }; - typedef std::map, MeshDataComparator> MeshInstanceContainer; - typedef std::map, BatchedModelMaterialComparator> ModelBatches; - typedef std::map> BatchedSpriteContainer; + struct MeshInstanceEntry + { + MeshInstanceEntry(NzDeferredRenderQueue* listener, int indexBufferValue, int vertexBufferValue) : + indexBufferListener(listener, indexBufferValue), + vertexBufferListener(listener, vertexBufferValue) + { + } + + std::vector instances; + NzIndexBufferConstListener indexBufferListener; + NzVertexBufferConstListener vertexBufferListener; + }; + + typedef std::map MeshInstanceContainer; + + struct BatchedModelMaterialComparator + { + bool operator()(const NzMaterial* mat1, const NzMaterial* mat2); + }; + + struct BatchedModelEntry + { + BatchedModelEntry(NzDeferredRenderQueue* listener, int materialValue) : + materialListener(listener, materialValue) + { + } + + NzMaterialConstListener materialListener; + MeshInstanceContainer meshMap; + bool enabled = false; + bool instancingEnabled = false; + }; + + typedef std::map ModelBatches; typedef std::vector LightContainer; ModelBatches opaqueModels; - BatchedSpriteContainer sprites; LightContainer directionalLights; LightContainer pointLights; LightContainer spotLights; diff --git a/include/Nazara/Graphics/ForwardRenderQueue.hpp b/include/Nazara/Graphics/ForwardRenderQueue.hpp index a7571a848..2657bc973 100644 --- a/include/Nazara/Graphics/ForwardRenderQueue.hpp +++ b/include/Nazara/Graphics/ForwardRenderQueue.hpp @@ -11,16 +11,16 @@ #include #include #include +#include #include #include +#include #include +#include #include #include class NzAbstractViewer; -class NzMaterial; -class NzSkeletalMesh; -class NzStaticMesh; class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResourceListener { @@ -28,7 +28,7 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResource public: NzForwardRenderQueue() = default; - ~NzForwardRenderQueue(); + ~NzForwardRenderQueue() = default; void AddDrawable(const NzDrawable* drawable) override; void AddLight(const NzLight* light) override; @@ -49,17 +49,15 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResource unsigned int spriteCount; }; - struct TransparentModelData + struct BatchedSpriteEntry { - NzMatrix4f transformMatrix; - NzMeshData meshData; - NzSpheref boundingSphere; - const NzMaterial* material; - }; + BatchedSpriteEntry(NzForwardRenderQueue* listener, int textureValue) : + textureListener(listener, textureValue) + { + } - struct BatchedModelMaterialComparator - { - bool operator()(const NzMaterial* mat1, const NzMaterial* mat2); + std::vector spriteChains; + NzTextureConstListener textureListener; }; struct BatchedSpriteMaterialComparator @@ -67,15 +65,71 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResource bool operator()(const NzMaterial* mat1, const NzMaterial* mat2); }; + typedef std::map BasicSpriteOverlayContainer; + + struct BatchedBasicSpriteEntry + { + BatchedBasicSpriteEntry(NzForwardRenderQueue* listener, int materialValue) : + materialListener(listener, materialValue) + { + } + + NzMaterialConstListener materialListener; + BasicSpriteOverlayContainer overlayMap; + bool enabled = false; + }; + + typedef std::map BasicSpriteBatches; + struct MeshDataComparator { bool operator()(const NzMeshData& data1, const NzMeshData& data2); }; - typedef std::map>, MeshDataComparator> MeshInstanceContainer; - typedef std::map, BatchedModelMaterialComparator> ModelBatches; - typedef std::map> BasicSpriteOverlayContainer; - typedef std::map BasicSpriteBatches; + struct MeshInstanceEntry + { + MeshInstanceEntry(NzForwardRenderQueue* listener, int indexBufferValue, int vertexBufferValue) : + indexBufferListener(listener, indexBufferValue), + vertexBufferListener(listener, vertexBufferValue) + { + } + + std::vector instances; + NzIndexBufferConstListener indexBufferListener; + NzSpheref squaredBoundingSphere; + NzVertexBufferConstListener vertexBufferListener; + }; + + typedef std::map MeshInstanceContainer; + + struct BatchedModelMaterialComparator + { + bool operator()(const NzMaterial* mat1, const NzMaterial* mat2); + }; + + struct BatchedModelEntry + { + BatchedModelEntry(NzForwardRenderQueue* listener, int materialValue) : + materialListener(listener, materialValue) + { + } + + NzMaterialConstListener materialListener; + MeshInstanceContainer meshMap; + bool enabled = false; + bool instancingEnabled = false; + }; + + typedef std::map ModelBatches; + + struct TransparentModelData + { + NzMatrix4f transformMatrix; + NzMeshData meshData; + NzSpheref squaredBoundingSphere; + const NzMaterial* material; + }; + typedef std::vector LightContainer; typedef std::vector TransparentModelContainer; diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index ffe7f8217..e98232bbf 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -34,7 +35,9 @@ struct NAZARA_API NzMaterialParams class NzMaterial; +using NzMaterialConstListener = NzResourceListenerWrapper; using NzMaterialConstRef = NzResourceRef; +using NzMaterialListener = NzResourceListenerWrapper; using NzMaterialLoader = NzResourceLoader; using NzMaterialRef = NzResourceRef; diff --git a/include/Nazara/Renderer/Context.hpp b/include/Nazara/Renderer/Context.hpp index 217680934..99e722cba 100644 --- a/include/Nazara/Renderer/Context.hpp +++ b/include/Nazara/Renderer/Context.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -16,7 +17,9 @@ class NzContext; +using NzContextConstListener = NzResourceListenerWrapper; using NzContextConstRef = NzResourceRef; +using NzContextListener = NzResourceListenerWrapper; using NzContextRef = NzResourceRef; class NzContextImpl; diff --git a/include/Nazara/Renderer/RenderBuffer.hpp b/include/Nazara/Renderer/RenderBuffer.hpp index 0c4415068..d3a038e41 100644 --- a/include/Nazara/Renderer/RenderBuffer.hpp +++ b/include/Nazara/Renderer/RenderBuffer.hpp @@ -10,12 +10,15 @@ #include #include #include +#include #include #include class NzRenderBuffer; +using NzRenderBufferConstListener = NzResourceListenerWrapper; using NzRenderBufferConstRef = NzResourceRef; +using NzRenderBufferListener = NzResourceListenerWrapper; using NzRenderBufferRef = NzResourceRef; class NAZARA_API NzRenderBuffer : public NzResource, NzNonCopyable diff --git a/include/Nazara/Renderer/Shader.hpp b/include/Nazara/Renderer/Shader.hpp index 9c8f4e0dc..edf5f6582 100644 --- a/include/Nazara/Renderer/Shader.hpp +++ b/include/Nazara/Renderer/Shader.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -23,7 +24,9 @@ class NzShader; class NzShaderStage; +using NzShaderConstListener = NzResourceListenerWrapper; using NzShaderConstRef = NzResourceRef; +using NzShaderListener = NzResourceListenerWrapper; using NzShaderRef = NzResourceRef; class NAZARA_API NzShader : public NzResource, NzNonCopyable diff --git a/include/Nazara/Renderer/Texture.hpp b/include/Nazara/Renderer/Texture.hpp index 02a1a208f..fb23834bd 100644 --- a/include/Nazara/Renderer/Texture.hpp +++ b/include/Nazara/Renderer/Texture.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -18,7 +19,9 @@ class NzTexture; +using NzTextureConstListener = NzResourceListenerWrapper; using NzTextureConstRef = NzResourceRef; +using NzTextureListener = NzResourceListenerWrapper; using NzTextureRef = NzResourceRef; struct NzTextureImpl; diff --git a/include/Nazara/Renderer/UberShader.hpp b/include/Nazara/Renderer/UberShader.hpp index c01d512d6..2582b6b4f 100644 --- a/include/Nazara/Renderer/UberShader.hpp +++ b/include/Nazara/Renderer/UberShader.hpp @@ -10,13 +10,16 @@ #include #include #include +#include #include #include #include class NzUberShader; +using NzUberShaderConstListener = NzResourceListenerWrapper; using NzUberShaderConstRef = NzResourceRef; +using NzUberShaderListener = NzResourceListenerWrapper; using NzUberShaderRef = NzResourceRef; class NAZARA_API NzUberShader : public NzResource diff --git a/include/Nazara/Utility/Animation.hpp b/include/Nazara/Utility/Animation.hpp index ae642bcc6..72a78db98 100644 --- a/include/Nazara/Utility/Animation.hpp +++ b/include/Nazara/Utility/Animation.hpp @@ -9,16 +9,18 @@ #include #include +#include #include #include #include #include #include +#include struct NAZARA_API NzAnimationParams { // La frame de fin à charger - unsigned int endFrame = static_cast(-1); + unsigned int endFrame = std::numeric_limits::max(); // La frame de début à charger unsigned int startFrame = 0; @@ -28,7 +30,9 @@ struct NAZARA_API NzAnimationParams class NzAnimation; class NzSkeleton; +using NzAnimationConstListener = NzResourceListenerWrapper; using NzAnimationConstRef = NzResourceRef; +using NzAnimationListener = NzResourceListenerWrapper; using NzAnimationLoader = NzResourceLoader; using NzAnimationRef = NzResourceRef; diff --git a/include/Nazara/Utility/Buffer.hpp b/include/Nazara/Utility/Buffer.hpp index b7a81e094..def55d0c4 100644 --- a/include/Nazara/Utility/Buffer.hpp +++ b/include/Nazara/Utility/Buffer.hpp @@ -10,12 +10,15 @@ #include #include #include +#include #include #include class NzBuffer; +using NzBufferConstListener = NzResourceListenerWrapper; using NzBufferConstRef = NzResourceRef; +using NzBufferListener = NzResourceListenerWrapper; using NzBufferRef = NzResourceRef; class NzAbstractBuffer; diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index 6a87d71d2..1b01ad9f8 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -9,8 +9,9 @@ #include #include -#include +#include #include +#include #include #include #include @@ -25,7 +26,9 @@ class NzFontData; struct NzFontGlyph; +using NzFontConstListener = NzResourceListenerWrapper; using NzFontConstRef = NzResourceRef; +using NzFontListener = NzResourceListenerWrapper; using NzFontLoader = NzResourceLoader; using NzFontRef = NzResourceRef; diff --git a/include/Nazara/Utility/Image.hpp b/include/Nazara/Utility/Image.hpp index 57c188822..39a79ae89 100644 --- a/include/Nazara/Utility/Image.hpp +++ b/include/Nazara/Utility/Image.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -32,7 +33,9 @@ struct NAZARA_API NzImageParams class NzImage; +using NzImageConstListener = NzResourceListenerWrapper; using NzImageConstRef = NzResourceRef; +using NzImageListener = NzResourceListenerWrapper; using NzImageLoader = NzResourceLoader; using NzImageRef = NzResourceRef; diff --git a/include/Nazara/Utility/IndexBuffer.hpp b/include/Nazara/Utility/IndexBuffer.hpp index cd1860199..a25c47421 100644 --- a/include/Nazara/Utility/IndexBuffer.hpp +++ b/include/Nazara/Utility/IndexBuffer.hpp @@ -9,12 +9,15 @@ #include #include +#include #include #include class NzIndexBuffer; +using NzIndexBufferConstListener = NzResourceListenerWrapper; using NzIndexBufferConstRef = NzResourceRef; +using NzIndexBufferListener = NzResourceListenerWrapper; using NzIndexBufferRef = NzResourceRef; class NAZARA_API NzIndexBuffer : public NzResource diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp index 296d72f7c..1e2896e0e 100644 --- a/include/Nazara/Utility/Mesh.hpp +++ b/include/Nazara/Utility/Mesh.hpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include @@ -52,13 +52,15 @@ class NzPrimitiveList; typedef NzVertexStruct_XYZ_Normal_UV_Tangent NzMeshVertex; typedef NzVertexStruct_XYZ_Normal_UV_Tangent_Skinning NzSkeletalMeshVertex; +using NzMeshConstListener = NzResourceListenerWrapper; using NzMeshConstRef = NzResourceRef; +using NzMeshListener = NzResourceListenerWrapper; using NzMeshLoader = NzResourceLoader; using NzMeshRef = NzResourceRef; struct NzMeshImpl; -class NAZARA_API NzMesh : public NzResource, NzResourceListener +class NAZARA_API NzMesh : public NzResource { friend NzMeshLoader; @@ -121,8 +123,6 @@ class NAZARA_API NzMesh : public NzResource, NzResourceListener void Transform(const NzMatrix4f& matrix); private: - void OnResourceReleased(const NzResource* resource, int index) override; - NzMeshImpl* m_impl = nullptr; static NzMeshLoader::LoaderList s_loaders; diff --git a/include/Nazara/Utility/SimpleTextDrawer.hpp b/include/Nazara/Utility/SimpleTextDrawer.hpp index 47fa31517..4565b2a1e 100644 --- a/include/Nazara/Utility/SimpleTextDrawer.hpp +++ b/include/Nazara/Utility/SimpleTextDrawer.hpp @@ -19,7 +19,7 @@ class NAZARA_API NzSimpleTextDrawer : public NzAbstractTextDrawer, NzResourceLis { public: NzSimpleTextDrawer(); - virtual ~NzSimpleTextDrawer(); + virtual ~NzSimpleTextDrawer() = default; const NzRectui& GetBounds() const; unsigned int GetCharacterSize() const; @@ -49,6 +49,7 @@ class NAZARA_API NzSimpleTextDrawer : public NzAbstractTextDrawer, NzResourceLis mutable std::vector m_glyphs; NzColor m_color; NzFontRef m_font; + NzFontListener m_fontListener; // Doit se situer après le FontRef (pour être libéré avant) mutable NzRectui m_bounds; NzString m_text; nzUInt32 m_style; diff --git a/include/Nazara/Utility/SkeletalMesh.hpp b/include/Nazara/Utility/SkeletalMesh.hpp index 2ac55cd82..72a0567ba 100644 --- a/include/Nazara/Utility/SkeletalMesh.hpp +++ b/include/Nazara/Utility/SkeletalMesh.hpp @@ -8,12 +8,16 @@ #define NAZARA_SKELETALMESH_HPP #include +#include +#include #include #include class NzSkeletalMesh; +using NzSkeletalMeshConstListener = NzResourceListenerWrapper; using NzSkeletalMeshConstRef = NzResourceRef; +using NzSkeletalMeshListener = NzResourceListenerWrapper; using NzSkeletalMeshRef = NzResourceRef; class NAZARA_API NzSkeletalMesh final : public NzSubMesh diff --git a/include/Nazara/Utility/Skeleton.hpp b/include/Nazara/Utility/Skeleton.hpp index 7832c266d..12f088622 100644 --- a/include/Nazara/Utility/Skeleton.hpp +++ b/include/Nazara/Utility/Skeleton.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -16,7 +17,9 @@ class NzSkeleton; +using NzSkeletonConstListener = NzResourceListenerWrapper; using NzSkeletonConstRef = NzResourceRef; +using NzSkeletonListener = NzResourceListenerWrapper; using NzSkeletonRef = NzResourceRef; struct NzSkeletonImpl; diff --git a/include/Nazara/Utility/StaticMesh.hpp b/include/Nazara/Utility/StaticMesh.hpp index 4bd8b4bea..3af527155 100644 --- a/include/Nazara/Utility/StaticMesh.hpp +++ b/include/Nazara/Utility/StaticMesh.hpp @@ -9,11 +9,14 @@ #include #include +#include #include class NzStaticMesh; +using NzStaticMeshConstListener = NzResourceListenerWrapper; using NzStaticMeshConstRef = NzResourceRef; +using NzStaticMeshListener = NzResourceListenerWrapper; using NzStaticMeshRef = NzResourceRef; class NAZARA_API NzStaticMesh final : public NzSubMesh, NzResourceListener diff --git a/include/Nazara/Utility/SubMesh.hpp b/include/Nazara/Utility/SubMesh.hpp index f8a7be0f9..cfa031b22 100644 --- a/include/Nazara/Utility/SubMesh.hpp +++ b/include/Nazara/Utility/SubMesh.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -19,7 +20,9 @@ class NzMesh; class NzSubMesh; +using NzSubMeshConstListener = NzResourceListenerWrapper; using NzSubMeshConstRef = NzResourceRef; +using NzSubMeshListener = NzResourceListenerWrapper; using NzSubMeshRef = NzResourceRef; class NAZARA_API NzSubMesh : public NzResource diff --git a/include/Nazara/Utility/VertexBuffer.hpp b/include/Nazara/Utility/VertexBuffer.hpp index feb09ae16..51bbe75f0 100644 --- a/include/Nazara/Utility/VertexBuffer.hpp +++ b/include/Nazara/Utility/VertexBuffer.hpp @@ -9,13 +9,16 @@ #include #include +#include #include #include #include class NzVertexBuffer; +using NzVertexBufferConstListener = NzResourceListenerWrapper; using NzVertexBufferConstRef = NzResourceRef; +using NzVertexBufferListener = NzResourceListenerWrapper; using NzVertexBufferRef = NzResourceRef; class NAZARA_API NzVertexBuffer : public NzResource diff --git a/include/Nazara/Utility/VertexDeclaration.hpp b/include/Nazara/Utility/VertexDeclaration.hpp index 3dd5dc6c3..27f6a7aee 100644 --- a/include/Nazara/Utility/VertexDeclaration.hpp +++ b/include/Nazara/Utility/VertexDeclaration.hpp @@ -9,12 +9,15 @@ #include #include +#include #include #include class NzVertexDeclaration; +using NzVertexDeclarationConstListener = NzResourceListenerWrapper; using NzVertexDeclarationConstRef = NzResourceRef; +using NzVertexDeclarationListener = NzResourceListenerWrapper; using NzVertexDeclarationRef = NzResourceRef; class NAZARA_API NzVertexDeclaration : public NzResource diff --git a/src/Nazara/Graphics/DeferredGeometryPass.cpp b/src/Nazara/Graphics/DeferredGeometryPass.cpp index 4fe2b2905..228fdfe8c 100644 --- a/src/Nazara/Graphics/DeferredGeometryPass.cpp +++ b/src/Nazara/Graphics/DeferredGeometryPass.cpp @@ -54,17 +54,17 @@ bool NzDeferredGeometryPass::Process(const NzScene* scene, unsigned int firstWor for (auto& matIt : m_renderQueue->opaqueModels) { - bool& used = std::get<0>(matIt.second); - if (used) + auto& matEntry = matIt.second; + + if (matEntry.enabled) { - bool& renderQueueInstancing = std::get<1>(matIt.second); - NzDeferredRenderQueue::MeshInstanceContainer& meshInstances = std::get<2>(matIt.second); + NzDeferredRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; if (!meshInstances.empty()) { const NzMaterial* material = matIt.first; - bool useInstancing = instancingEnabled && renderQueueInstancing; + bool useInstancing = instancingEnabled && matEntry.instancingEnabled; // On commence par récupérer le programme du matériau nzUInt32 flags = nzShaderFlags_Deferred; @@ -88,8 +88,9 @@ bool NzDeferredGeometryPass::Process(const NzScene* scene, unsigned int firstWor for (auto& meshIt : meshInstances) { const NzMeshData& meshData = meshIt.first; - std::vector& instances = meshIt.second; + auto& meshEntry = meshIt.second; + std::vector& instances = meshEntry.instances; if (!instances.empty()) { const NzIndexBuffer* indexBuffer = meshData.indexBuffer; @@ -158,8 +159,8 @@ bool NzDeferredGeometryPass::Process(const NzScene* scene, unsigned int firstWor } // Et on remet à zéro les données - renderQueueInstancing = false; - used = false; + matEntry.enabled = false; + matEntry.instancingEnabled = false; } } diff --git a/src/Nazara/Graphics/DeferredRenderQueue.cpp b/src/Nazara/Graphics/DeferredRenderQueue.cpp index 821e92d86..44238f9c0 100644 --- a/src/Nazara/Graphics/DeferredRenderQueue.cpp +++ b/src/Nazara/Graphics/DeferredRenderQueue.cpp @@ -3,12 +3,9 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include +#include #include #include -#include -#include -#include #include namespace @@ -26,11 +23,6 @@ m_forwardQueue(forwardQueue) { } -NzDeferredRenderQueue::~NzDeferredRenderQueue() -{ - Clear(true); -} - void NzDeferredRenderQueue::AddDrawable(const NzDrawable* drawable) { m_forwardQueue->AddDrawable(drawable); @@ -46,6 +38,7 @@ void NzDeferredRenderQueue::AddLight(const NzLight* light) } #endif + // On trie la lumière (elles sont traitées différement selon leur type) switch (light->GetLightType()) { case nzLightType_Directional: @@ -61,56 +54,53 @@ void NzDeferredRenderQueue::AddLight(const NzLight* light) break; } + // On envoie également la lumière au forward-shading + ///TODO: Possibilité pour une lumière de se réserver au Deferred Shading m_forwardQueue->AddLight(light); } void NzDeferredRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) { if (material->IsEnabled(nzRendererParameter_Blend)) + // Un matériau transparent ? J'aime pas, va voir dans la forward queue si j'y suis m_forwardQueue->AddMesh(material, meshData, meshAABB, transformMatrix); else { - ModelBatches::iterator it = opaqueModels.find(material); + auto it = opaqueModels.find(material); if (it == opaqueModels.end()) { - it = opaqueModels.insert(std::make_pair(material, ModelBatches::mapped_type())).first; - material->AddResourceListener(this, ResourceType_Material); + BatchedModelEntry entry(this, ResourceType_Material); + entry.materialListener = material; + + it = opaqueModels.insert(std::make_pair(material, std::move(entry))).first; } - bool& used = std::get<0>(it->second); - bool& enableInstancing = std::get<1>(it->second); - MeshInstanceContainer& meshMap = std::get<2>(it->second); + BatchedModelEntry& entry = it->second; + entry.enabled = true; - used = true; + auto& meshMap = entry.meshMap; - MeshInstanceContainer::iterator it2 = meshMap.find(meshData); + auto it2 = meshMap.find(meshData); if (it2 == meshMap.end()) { - it2 = meshMap.insert(std::make_pair(meshData, MeshInstanceContainer::mapped_type())).first; + MeshInstanceEntry instanceEntry(this, ResourceType_IndexBuffer, ResourceType_VertexBuffer); + instanceEntry.indexBufferListener = meshData.indexBuffer; + instanceEntry.vertexBufferListener = meshData.vertexBuffer; - if (meshData.indexBuffer) - meshData.indexBuffer->AddResourceListener(this, ResourceType_IndexBuffer); - - meshData.vertexBuffer->AddResourceListener(this, ResourceType_VertexBuffer); + it2 = meshMap.insert(std::make_pair(meshData, std::move(instanceEntry))).first; } - std::vector& instances = it2->second; + std::vector& instances = it2->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) - enableInstancing = true; // Apparemment oui, activons l'instancing avec ce matériau + entry.instancingEnabled = true; // Apparemment oui, activons l'instancing avec ce matériau } } void NzDeferredRenderQueue::AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay) { - /*NzMaterial* material = sprite->GetMaterial(); - if (!material->IsLightingEnabled() || material->IsEnabled(nzRendererParameter_Blend)) - m_forwardQueue->AddSprite(sprite); - else - sprites[material].push_back(sprite);*/ - m_forwardQueue->AddSprites(material, vertices, spriteCount, overlay); } @@ -121,27 +111,7 @@ void NzDeferredRenderQueue::Clear(bool fully) spotLights.clear(); if (fully) - { - for (auto& matIt : opaqueModels) - { - const NzMaterial* material = matIt.first; - material->RemoveResourceListener(this); - - MeshInstanceContainer& instances = std::get<2>(matIt.second); - for (auto& instanceIt : instances) - { - const NzMeshData& renderData = instanceIt.first; - - if (renderData.indexBuffer) - renderData.indexBuffer->RemoveResourceListener(this); - - renderData.vertexBuffer->RemoveResourceListener(this); - } - } - opaqueModels.clear(); - sprites.clear(); - } m_forwardQueue->Clear(fully); } @@ -154,7 +124,7 @@ bool NzDeferredRenderQueue::OnResourceDestroy(const NzResource* resource, int in { for (auto& modelPair : opaqueModels) { - MeshInstanceContainer& meshes = std::get<2>(modelPair.second); + MeshInstanceContainer& meshes = modelPair.second.meshMap; for (auto it = meshes.begin(); it != meshes.end();) { const NzMeshData& renderData = it->first; @@ -168,14 +138,18 @@ bool NzDeferredRenderQueue::OnResourceDestroy(const NzResource* resource, int in } case ResourceType_Material: - opaqueModels.erase(static_cast(resource)); + { + const NzMaterial* material = static_cast(resource); + + opaqueModels.erase(material); break; + } case ResourceType_VertexBuffer: { for (auto& modelPair : opaqueModels) { - MeshInstanceContainer& meshes = std::get<2>(modelPair.second); + MeshInstanceContainer& meshes = modelPair.second.meshMap; for (auto it = meshes.begin(); it != meshes.end();) { const NzMeshData& renderData = it->first; @@ -203,7 +177,7 @@ void NzDeferredRenderQueue::OnResourceReleased(const NzResource* resource, int i { for (auto& modelPair : opaqueModels) { - MeshInstanceContainer& meshes = std::get<2>(modelPair.second); + MeshInstanceContainer& meshes = modelPair.second.meshMap; for (auto it = meshes.begin(); it != meshes.end();) { const NzMeshData& renderData = it->first; @@ -233,7 +207,7 @@ void NzDeferredRenderQueue::OnResourceReleased(const NzResource* resource, int i { for (auto& modelPair : opaqueModels) { - MeshInstanceContainer& meshes = std::get<2>(modelPair.second); + MeshInstanceContainer& meshes = modelPair.second.meshMap; for (auto it = meshes.begin(); it != meshes.end();) { const NzMeshData& renderData = it->first; @@ -268,26 +242,6 @@ bool NzDeferredRenderQueue::BatchedModelMaterialComparator::operator()(const NzM return mat1 < mat2; } -bool NzDeferredRenderQueue::BatchedSpriteMaterialComparator::operator()(const NzMaterial* mat1, const NzMaterial* mat2) -{ - const NzUberShader* uberShader1 = mat1->GetShader(); - const NzUberShader* uberShader2 = mat2->GetShader(); - if (uberShader1 != uberShader2) - return uberShader1 < uberShader2; - - const NzShader* shader1 = mat1->GetShaderInstance(nzShaderFlags_Deferred)->GetShader(); - const NzShader* shader2 = mat2->GetShaderInstance(nzShaderFlags_Deferred)->GetShader(); - if (shader1 != shader2) - return shader1 < shader2; - - const NzTexture* diffuseMap1 = mat1->GetDiffuseMap(); - const NzTexture* diffuseMap2 = mat2->GetDiffuseMap(); - if (diffuseMap1 != diffuseMap2) - return diffuseMap1 < diffuseMap2; - - return mat1 < mat2; -} - bool NzDeferredRenderQueue::MeshDataComparator::operator()(const NzMeshData& data1, const NzMeshData& data2) { const NzBuffer* buffer1; diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index c148d56f1..23a099335 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -5,15 +5,8 @@ #include #include #include -#include -#include -#include -#include -#include #include -///FIXME: Régler ce problème de dépendance aux ressources - namespace { enum ResourceType @@ -25,11 +18,6 @@ namespace }; } -NzForwardRenderQueue::~NzForwardRenderQueue() -{ - Clear(true); -} - void NzForwardRenderQueue::AddDrawable(const NzDrawable* drawable) { #if NAZARA_GRAPHICS_SAFE @@ -79,9 +67,9 @@ void NzForwardRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& transparentModelData.resize(index+1); TransparentModelData& data = transparentModelData.back(); - data.boundingSphere = NzSpheref(transformMatrix.GetTranslation() + meshAABB.GetCenter(), meshAABB.GetSquaredRadius()); data.material = material; data.meshData = meshData; + data.squaredBoundingSphere = NzSpheref(transformMatrix.GetTranslation() + meshAABB.GetCenter(), meshAABB.GetSquaredRadius()); data.transformMatrix = transformMatrix; transparentModels.push_back(index); @@ -91,36 +79,34 @@ void NzForwardRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& ModelBatches::iterator it = opaqueModels.find(material); if (it == opaqueModels.end()) { - it = opaqueModels.insert(std::make_pair(material, ModelBatches::mapped_type())).first; - material->AddResourceListener(this, ResourceType_Material); + BatchedModelEntry entry(this, ResourceType_Material); + entry.materialListener = material; + + it = opaqueModels.insert(std::make_pair(material, std::move(entry))).first; } - bool& used = std::get<0>(it->second); - bool& enableInstancing = std::get<1>(it->second); - MeshInstanceContainer& meshMap = std::get<2>(it->second); + BatchedModelEntry& entry = it->second; + entry.enabled = true; - used = true; + auto& meshMap = entry.meshMap; - MeshInstanceContainer::iterator it2 = meshMap.find(meshData); + auto it2 = meshMap.find(meshData); if (it2 == meshMap.end()) { - it2 = meshMap.insert(std::make_pair(meshData, MeshInstanceContainer::mapped_type())).first; + MeshInstanceEntry instanceEntry(this, ResourceType_IndexBuffer, ResourceType_VertexBuffer); + instanceEntry.indexBufferListener = meshData.indexBuffer; + instanceEntry.squaredBoundingSphere = meshAABB.GetSquaredBoundingSphere(); + instanceEntry.vertexBufferListener = meshData.vertexBuffer; - NzSpheref& squaredBoundingSphere = it2->second.first; - squaredBoundingSphere.Set(meshAABB.GetSquaredBoundingSphere()); - - if (meshData.indexBuffer) - meshData.indexBuffer->AddResourceListener(this, ResourceType_IndexBuffer); - - meshData.vertexBuffer->AddResourceListener(this, ResourceType_VertexBuffer); + it2 = meshMap.insert(std::make_pair(meshData, std::move(instanceEntry))).first; } - std::vector& instances = it2->second.second; + std::vector& instances = it2->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) - enableInstancing = true; // Apparemment oui, activons l'instancing avec ce matériau + entry.instancingEnabled = true; // Apparemment oui, activons l'instancing avec ce matériau } } @@ -129,20 +115,27 @@ void NzForwardRenderQueue::AddSprites(const NzMaterial* material, const NzVertex auto matIt = basicSprites.find(material); if (matIt == basicSprites.end()) { - matIt = basicSprites.insert(std::make_pair(material, BasicSpriteBatches::mapped_type())).first; - material->AddResourceListener(this, ResourceType_Material); + BatchedBasicSpriteEntry entry(this, ResourceType_Material); + entry.materialListener = material; + + matIt = basicSprites.insert(std::make_pair(material, std::move(entry))).first; } - auto& overlayMap = matIt->second; + BatchedBasicSpriteEntry& entry = matIt->second; + entry.enabled = true; + + auto& overlayMap = entry.overlayMap; + auto overlayIt = overlayMap.find(overlay); if (overlayIt == overlayMap.end()) { - overlayIt = overlayMap.insert(std::make_pair(overlay, BasicSpriteOverlayContainer::mapped_type())).first; - if (overlay) - overlay->AddResourceListener(this, ResourceType_Texture); + BatchedSpriteEntry overlayEntry(this, ResourceType_Texture); + overlayEntry.textureListener = overlay; + + overlayIt = overlayMap.insert(std::make_pair(overlay, std::move(overlayEntry))).first; } - auto& spriteVector = overlayIt->second; + auto& spriteVector = overlayIt->second.spriteChains; spriteVector.push_back(SpriteChain_XYZ_Color_UV({vertices, spriteCount})); } @@ -156,37 +149,7 @@ void NzForwardRenderQueue::Clear(bool fully) if (fully) { - for (auto& matPair : basicSprites) - { - const NzMaterial* material = matPair.first; - material->RemoveResourceListener(this); - - auto& overlayMap = matPair.second; - for (auto& overlayPair : overlayMap) - { - const NzTexture* overlay = overlayPair.first; - if (overlay) - overlay->RemoveResourceListener(this); - } - } basicSprites.clear(); - - for (auto& matPair : opaqueModels) - { - const NzMaterial* material = matPair.first; - material->RemoveResourceListener(this); - - MeshInstanceContainer& instances = std::get<2>(matPair.second); - for (auto& instanceIt : instances) - { - const NzMeshData& renderData = instanceIt.first; - - if (renderData.indexBuffer) - renderData.indexBuffer->RemoveResourceListener(this); - - renderData.vertexBuffer->RemoveResourceListener(this); - } - } opaqueModels.clear(); } } @@ -198,8 +161,8 @@ void NzForwardRenderQueue::Sort(const NzAbstractViewer* viewer) std::sort(transparentModels.begin(), transparentModels.end(), [this, &nearPlane, &viewerNormal](unsigned int index1, unsigned int index2) { - const NzSpheref& sphere1 = transparentModelData[index1].boundingSphere; - const NzSpheref& sphere2 = transparentModelData[index2].boundingSphere; + const NzSpheref& sphere1 = transparentModelData[index1].squaredBoundingSphere; + const NzSpheref& sphere2 = transparentModelData[index2].squaredBoundingSphere; NzVector3f position1 = sphere1.GetNegativeVertex(viewerNormal); NzVector3f position2 = sphere2.GetNegativeVertex(viewerNormal); @@ -216,7 +179,7 @@ bool NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int ind { for (auto& modelPair : opaqueModels) { - MeshInstanceContainer& meshes = std::get<2>(modelPair.second); + MeshInstanceContainer& meshes = modelPair.second.meshMap; for (auto it = meshes.begin(); it != meshes.end();) { const NzMeshData& renderData = it->first; @@ -230,15 +193,19 @@ bool NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int ind } case ResourceType_Material: - basicSprites.erase(static_cast(resource)); - opaqueModels.erase(static_cast(resource)); + { + const NzMaterial* material = static_cast(resource); + + basicSprites.erase(material); + opaqueModels.erase(material); break; + } case ResourceType_VertexBuffer: { for (auto& modelPair : opaqueModels) { - MeshInstanceContainer& meshes = std::get<2>(modelPair.second); + MeshInstanceContainer& meshes = modelPair.second.meshMap; for (auto it = meshes.begin(); it != meshes.end();) { const NzMeshData& renderData = it->first; @@ -266,7 +233,7 @@ void NzForwardRenderQueue::OnResourceReleased(const NzResource* resource, int in { for (auto& modelPair : opaqueModels) { - MeshInstanceContainer& meshes = std::get<2>(modelPair.second); + MeshInstanceContainer& meshes = modelPair.second.meshMap; for (auto it = meshes.begin(); it != meshes.end();) { const NzMeshData& renderData = it->first; @@ -306,7 +273,7 @@ void NzForwardRenderQueue::OnResourceReleased(const NzResource* resource, int in { for (auto matIt = basicSprites.begin(); matIt != basicSprites.end(); ++matIt) { - auto& overlayMap = matIt->second; + auto& overlayMap = matIt->second.overlayMap; for (auto overlayIt = overlayMap.begin(); overlayIt != overlayMap.end(); ++overlayIt) { if (overlayIt->first == resource) @@ -324,7 +291,7 @@ void NzForwardRenderQueue::OnResourceReleased(const NzResource* resource, int in { for (auto& modelPair : opaqueModels) { - MeshInstanceContainer& meshes = std::get<2>(modelPair.second); + MeshInstanceContainer& meshes = modelPair.second.meshMap; for (auto it = meshes.begin(); it != meshes.end();) { const NzMeshData& renderData = it->first; diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 0a73e8641..e7f6168de 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -175,86 +175,93 @@ void NzForwardRenderTechnique::DrawBasicSprites(const NzScene* scene) const for (auto& matIt : m_renderQueue.basicSprites) { const NzMaterial* material = matIt.first; - auto& overlayMap = matIt.second; + auto& matEntry = matIt.second; - for (auto& overlayIt : overlayMap) + if (matEntry.enabled) { - const NzTexture* overlay = overlayIt.first; - auto& spriteChainVector = overlayIt.second; - - unsigned int spriteChainCount = spriteChainVector.size(); - if (spriteChainCount > 0) + auto& overlayMap = matEntry.overlayMap; + for (auto& overlayIt : overlayMap) { - // On commence par appliquer du matériau (et récupérer le shader ainsi activé) - nzUInt32 flags = nzShaderFlags_VertexColor; - if (overlay) - flags |= nzShaderFlags_TextureOverlay; + const NzTexture* overlay = overlayIt.first; + auto& spriteChainVector = overlayIt.second.spriteChains; - nzUInt8 overlayUnit; - const NzShader* shader = material->Apply(flags, 0, &overlayUnit); - - if (overlay) + unsigned int spriteChainCount = spriteChainVector.size(); + if (spriteChainCount > 0) { - overlayUnit++; - NzRenderer::SetTexture(overlayUnit, overlay); - NzRenderer::SetTextureSampler(overlayUnit, material->GetDiffuseSampler()); - } + // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + nzUInt32 flags = nzShaderFlags_VertexColor; + if (overlay) + flags |= nzShaderFlags_TextureOverlay; - // 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); + nzUInt8 overlayUnit; + const NzShader* shader = material->Apply(flags, 0, &overlayUnit); - // Couleur ambiante de la scène - shader->SendColor(shader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); - // Overlay - shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); - // Position de la caméra - shader->SendVector(shader->GetUniformLocation(nzShaderUniform_EyePosition), viewer->GetEyePosition()); + if (overlay) + { + overlayUnit++; + NzRenderer::SetTexture(overlayUnit, overlay); + NzRenderer::SetTextureSampler(overlayUnit, material->GetDiffuseSampler()); + } - lastShader = shader; - } + // 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); - 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 + // Couleur ambiante de la scène + shader->SendColor(shader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); + // Overlay + shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); + // Position de la caméra + shader->SendVector(shader->GetUniformLocation(nzShaderUniform_EyePosition), viewer->GetEyePosition()); - do - { - // On ouvre le buffer en écriture - NzBufferMapper vertexMapper(m_spriteBuffer, nzBufferAccess_DiscardAndWrite); - NzVertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(vertexMapper.GetPointer()); + lastShader = shader; + } - unsigned int spriteCount = 0; + 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 { - NzForwardRenderQueue::SpriteChain_XYZ_Color_UV& currentChain = spriteChainVector[spriteChain]; - unsigned int count = std::min(s_maxSprites - spriteCount, currentChain.spriteCount - spriteChainOffset); + // On ouvre le buffer en écriture + NzBufferMapper vertexMapper(m_spriteBuffer, nzBufferAccess_DiscardAndWrite); + NzVertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(vertexMapper.GetPointer()); - std::memcpy(vertices, currentChain.vertices + spriteChainOffset*4, 4*count*sizeof(NzVertexStruct_XYZ_Color_UV)); - vertices += count*4; + unsigned int spriteCount = 0; - spriteCount += count; - spriteChainOffset += count; - - // Avons-nous traité la chaîne entière ? - if (spriteChainOffset == currentChain.spriteCount) + do { - spriteChain++; - spriteChainOffset = 0; + NzForwardRenderQueue::SpriteChain_XYZ_Color_UV& currentChain = spriteChainVector[spriteChain]; + unsigned int count = std::min(s_maxSprites - 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 < s_maxSprites && spriteChain < spriteChainCount); + + vertexMapper.Unmap(); + + NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, spriteCount*6); } - while (spriteCount < s_maxSprites && spriteChain < spriteChainCount); + while (spriteChain < spriteChainCount); - vertexMapper.Unmap(); - - NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, spriteCount*6); + spriteChainVector.clear(); } - while (spriteChain < spriteChainCount); - - spriteChainVector.clear(); } + + // On remet à zéro + matEntry.enabled = false; } } } @@ -267,11 +274,11 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const for (auto& matIt : m_renderQueue.opaqueModels) { - bool& used = std::get<0>(matIt.second); - if (used) + auto& matEntry = matIt.second; + + if (matEntry.enabled) { - bool& renderQueueInstancing = std::get<1>(matIt.second); - NzForwardRenderQueue::MeshInstanceContainer& meshInstances = std::get<2>(matIt.second); + NzForwardRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; if (!meshInstances.empty()) { @@ -280,7 +287,7 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const // 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 instancing = m_instancingEnabled && (!material->IsLightingEnabled() || m_lights.IsEmpty()) && renderQueueInstancing; + bool instancing = m_instancingEnabled && (!material->IsLightingEnabled() || m_lights.IsEmpty()) && 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); @@ -300,11 +307,13 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const } // Meshes - for (auto& subMeshIt : meshInstances) + for (auto& meshIt : meshInstances) { - const NzMeshData& meshData = subMeshIt.first; - const NzSpheref& boundingSphere = subMeshIt.second.first; - std::vector& instances = subMeshIt.second.second; + const NzMeshData& meshData = meshIt.first; + auto& meshEntry = meshIt.second; + + const NzSpheref& squaredBoundingSphere = meshEntry.squaredBoundingSphere; + std::vector& instances = meshEntry.instances; if (!instances.empty()) { @@ -400,7 +409,7 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const for (const NzMatrix4f& matrix : instances) { unsigned int directionalLightCount = m_directionalLights.GetLightCount(); - unsigned int otherLightCount = m_lights.ComputeClosestLights(matrix.GetTranslation() + boundingSphere.GetPosition(), boundingSphere.radius, m_maxLightPassPerObject*NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS - directionalLightCount); + unsigned int otherLightCount = m_lights.ComputeClosestLights(matrix.GetTranslation() + squaredBoundingSphere.GetPosition(), squaredBoundingSphere.radius, m_maxLightPassPerObject*NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS - directionalLightCount); unsigned int lightCount = directionalLightCount + otherLightCount; NzRenderer::SetMatrix(nzMatrixType_World, matrix); @@ -464,8 +473,8 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const } // Et on remet à zéro les données - used = false; - renderQueueInstancing = false; + matEntry.enabled = false; + matEntry.instancingEnabled = false; } } } @@ -534,7 +543,11 @@ void NzForwardRenderTechnique::DrawTransparentModels(const NzScene* scene) const // Calcul des lumières les plus proches if (lightCount < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS && !m_lights.IsEmpty()) { - unsigned int count = std::min(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS - lightCount, m_lights.ComputeClosestLights(matrix.GetTranslation() + modelData.boundingSphere.GetPosition(), modelData.boundingSphere.radius, NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS)); + NzVector3f position = matrix.GetTranslation() + modelData.squaredBoundingSphere.GetPosition(); + float radius = modelData.squaredBoundingSphere.radius; + unsigned int closestLightCount = m_lights.ComputeClosestLights(position, radius, NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS); + + unsigned int count = std::min(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS - lightCount, closestLightCount); for (unsigned int i = 0; i < count; ++i) m_lights.GetResult(i)->Enable(shader, shaderUniforms->lightUniforms, shaderUniforms->lightOffset*(lightCount++)); } diff --git a/src/Nazara/Graphics/SkinningManager.cpp b/src/Nazara/Graphics/SkinningManager.cpp index 2e47fc11e..a29fb882e 100644 --- a/src/Nazara/Graphics/SkinningManager.cpp +++ b/src/Nazara/Graphics/SkinningManager.cpp @@ -35,8 +35,8 @@ namespace NzVertexBuffer* buffer; }; - using MeshMap = std::unordered_map; - using SkeletonMap = std::unordered_map; + using MeshMap = std::unordered_map>; + using SkeletonMap = std::unordered_map>; SkeletonMap s_cache; std::vector s_skinningQueue; @@ -51,7 +51,7 @@ namespace { for (auto& pair : s_cache) { - MeshMap& meshMap = pair.second; + MeshMap& meshMap = pair.second.second; meshMap.erase(static_cast(resource)); } break; @@ -75,17 +75,19 @@ namespace { for (auto& pair : s_cache) { - MeshMap& meshMap = pair.second; + MeshMap& meshMap = pair.second.second; for (auto& pair2 : meshMap) - pair2.second.updated = false; + pair2.second.second.updated = false; } break; } case ResourceType_Skeleton: { - for (auto& pair : s_cache.at(static_cast(resource))) - pair.second.updated = false; + const NzSkeleton* skeleton = static_cast(resource); + for (auto& pair : s_cache.at(skeleton).second) + pair.second.second.updated = false; + break; } } @@ -161,14 +163,11 @@ NzVertexBuffer* NzSkinningManager::GetBuffer(const NzSkeletalMesh* mesh, const N SkeletonMap::iterator it = s_cache.find(skeleton); if (it == s_cache.end()) - { - it = s_cache.insert(std::make_pair(skeleton, SkeletonMap::mapped_type())).first; - skeleton->AddResourceListener(&listener, ResourceType_Skeleton); - } + it = s_cache.insert(std::make_pair(skeleton, std::make_pair(NzSkeletonConstListener(&listener, ResourceType_Skeleton, skeleton), MeshMap{}))).first; NzVertexBuffer* buffer; - MeshMap& meshMap = it->second; + MeshMap& meshMap = it->second.second; MeshMap::iterator it2 = meshMap.find(mesh); if (it2 == meshMap.end()) { @@ -177,9 +176,7 @@ NzVertexBuffer* NzSkinningManager::GetBuffer(const NzSkeletalMesh* mesh, const N vertexBuffer->Reset(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Normal_UV_Tangent), mesh->GetVertexCount(), nzDataStorage_Hardware, nzBufferUsage_Dynamic); BufferData data({vertexBuffer.get(), true}); - meshMap.insert(std::make_pair(mesh, data)); - - mesh->AddResourceListener(&listener, ResourceType_SkeletalMesh); + meshMap.insert(std::make_pair(mesh, std::make_pair(NzSkeletalMeshConstListener(&listener, ResourceType_SkeletalMesh, mesh), data))); s_skinningQueue.push_back(SkinningData{mesh, skeleton, vertexBuffer.get()}); @@ -187,7 +184,7 @@ NzVertexBuffer* NzSkinningManager::GetBuffer(const NzSkeletalMesh* mesh, const N } else { - BufferData& data = it2->second; + BufferData& data = it2->second.second; if (!data.updated) { s_skinningQueue.push_back(SkinningData{mesh, skeleton, data.buffer}); @@ -221,13 +218,6 @@ bool NzSkinningManager::Initialize() void NzSkinningManager::Uninitialize() { - for (auto& pair : s_cache) - { - pair.first->RemoveResourceListener(&listener); - MeshMap& meshMap = pair.second; - for (auto& pair2 : meshMap) - pair2.first->RemoveResourceListener(&listener); - } s_cache.clear(); s_skinningQueue.clear(); } diff --git a/src/Nazara/Renderer/RenderTexture.cpp b/src/Nazara/Renderer/RenderTexture.cpp index ee53e0ed0..c42d6c044 100644 --- a/src/Nazara/Renderer/RenderTexture.cpp +++ b/src/Nazara/Renderer/RenderTexture.cpp @@ -19,8 +19,17 @@ namespace { struct Attachment { + Attachment(NzResourceListener* listener, int bufferIndex = 0, int textureIndex = 0) : + bufferListener(listener, bufferIndex), + textureListener(listener, textureIndex) + { + } + NzRenderBufferRef buffer; NzTextureRef texture; + // Les listeners doivent se trouver après les références (pour être libérés avant elles) + NzRenderBufferListener bufferListener; + NzTextureListener textureListener; nzAttachmentPoint attachmentPoint; bool isBuffer; @@ -51,11 +60,16 @@ namespace struct NzRenderTextureImpl { + NzRenderTextureImpl(NzResourceListener* listener, int contextIndex = 0) : + context(listener, contextIndex) + { + } + GLuint fbo; std::vector attachments; std::vector colorTargets; mutable std::vector drawBuffers; - const NzContext* context; + NzContextConstListener context; bool checked = false; bool complete = false; bool userDefinedTargets = false; @@ -139,20 +153,23 @@ bool NzRenderTexture::AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 in Unlock(); - unsigned int attachIndex = attachmentIndex[attachmentPoint]+index; - if (m_impl->attachments.size() <= attachIndex) - m_impl->attachments.resize(attachIndex+1); + unsigned int attachIndex = attachmentIndex[attachmentPoint] + index; + // On créé les attachements si ça n'a pas déjà été fait + for (unsigned int i = m_impl->attachments.size(); i <= attachIndex; ++i) + { + Attachment attachment(this, attachIndex, attachIndex); + m_impl->attachments.emplace_back(std::move(attachment)); + } Attachment& attachment = m_impl->attachments[attachIndex]; attachment.attachmentPoint = attachmentPoint; attachment.buffer = buffer; + attachment.bufferListener = buffer; attachment.isBuffer = true; attachment.isUsed = true; attachment.height = buffer->GetHeight(); attachment.width = buffer->GetWidth(); - buffer->AddResourceListener(this, attachIndex); - m_impl->checked = false; if (attachmentPoint == nzAttachmentPoint_Color && !m_impl->userDefinedTargets) @@ -283,9 +300,14 @@ bool NzRenderTexture::AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 i Unlock(); - unsigned int attachIndex = attachmentIndex[attachmentPoint]+index; - if (m_impl->attachments.size() <= attachIndex) - m_impl->attachments.resize(attachIndex+1); + unsigned int attachIndex = attachmentIndex[attachmentPoint] + index; + + // On créé les attachements si ça n'a pas déjà été fait + for (unsigned int i = m_impl->attachments.size(); i <= attachIndex; ++i) + { + Attachment attachment(this, attachIndex, attachIndex); + m_impl->attachments.emplace_back(std::move(attachment)); + } Attachment& attachment = m_impl->attachments[attachIndex]; attachment.attachmentPoint = attachmentPoint; @@ -293,10 +315,9 @@ bool NzRenderTexture::AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 i attachment.isUsed = true; attachment.height = texture->GetHeight(); attachment.texture = texture; + attachment.textureListener = texture; attachment.width = texture->GetWidth(); - texture->AddResourceListener(this, attachIndex); - m_impl->checked = false; if (attachmentPoint == nzAttachmentPoint_Color && !m_impl->userDefinedTargets) @@ -327,7 +348,7 @@ bool NzRenderTexture::Create(bool lock) } #endif - std::unique_ptr impl(new NzRenderTextureImpl); + std::unique_ptr impl(new NzRenderTextureImpl(this)); impl->fbo = 0; glGenFramebuffers(1, &impl->fbo); @@ -340,7 +361,6 @@ bool NzRenderTexture::Create(bool lock) m_impl = impl.release(); m_impl->context = NzContext::GetCurrent(); - m_impl->context->AddResourceListener(this); if (lock) { @@ -372,19 +392,6 @@ void NzRenderTexture::Destroy() if (IsActive()) NzRenderer::SetTarget(nullptr); - m_impl->context->RemoveResourceListener(this); - - for (const Attachment& attachment : m_impl->attachments) - { - if (attachment.isUsed) - { - if (attachment.isBuffer) - attachment.buffer->RemoveResourceListener(this); - else - attachment.texture->RemoveResourceListener(this); - } - } - // Le FBO devant être supprimé dans son contexte d'origine, nous déléguons sa suppression à la classe OpenGL // Celle-ci va libérer le FBO dès que possible (la prochaine fois que son contexte d'origine sera actif) NzOpenGL::DeleteFrameBuffer(m_impl->context, m_impl->fbo); @@ -410,7 +417,7 @@ void NzRenderTexture::Detach(nzAttachmentPoint attachmentPoint, nzUInt8 index) } #endif - unsigned int attachIndex = attachmentIndex[attachmentPoint]+index; + unsigned int attachIndex = attachmentIndex[attachmentPoint] + index; if (attachIndex >= m_impl->attachments.size()) return; @@ -430,7 +437,7 @@ void NzRenderTexture::Detach(nzAttachmentPoint attachmentPoint, nzUInt8 index) { glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, GL_RENDERBUFFER, 0); - attachement.buffer->RemoveResourceListener(this); + attachement.bufferListener = nullptr; attachement.buffer = nullptr; } else @@ -440,7 +447,7 @@ void NzRenderTexture::Detach(nzAttachmentPoint attachmentPoint, nzUInt8 index) else glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, 0, 0, 0); - attachement.texture->RemoveResourceListener(this); + attachement.textureListener = nullptr; attachement.texture = nullptr; } diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index 0e5b42855..ec806b69c 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -66,10 +66,38 @@ namespace bool samplerUpdated = false; }; - using VAO_Key = std::tuple; - using VAO_Map = std::map; + struct VAO_Entry + { + VAO_Entry(NzResourceListener* listener, int indexBufferIndex, int vertexBufferIndex, int vertexDeclarationIndex, int instancingDeclarationIndex) : + indexBufferListener(listener, indexBufferIndex), + vertexBufferListener(listener, vertexBufferIndex), + instancingDeclarationListener(listener, instancingDeclarationIndex), + vertexDeclarationListener(listener, vertexDeclarationIndex) + { + } - using Context_Map = std::unordered_map; + GLuint vao; + NzIndexBufferConstListener indexBufferListener; + NzVertexBufferConstListener vertexBufferListener; + NzVertexDeclarationConstListener instancingDeclarationListener; + NzVertexDeclarationConstListener vertexDeclarationListener; + }; + + using VAO_Key = std::tuple; + using VAO_Map = std::map; + + struct Context_Entry + { + Context_Entry(NzResourceListener* listener, int index) : + contextListener(listener, index) + { + } + + NzContextConstListener contextListener; + VAO_Map vaoMap; + }; + + using Context_Map = std::unordered_map; Context_Map s_vaos; std::vector s_dirtyTextureUnits; @@ -116,7 +144,7 @@ namespace for (auto& pair : s_vaos) { const NzContext* context = pair.first; - VAO_Map& vaos = pair.second; + VAO_Map& vaos = pair.second.vaoMap; auto it = vaos.begin(); while (it != vaos.end()) @@ -131,7 +159,7 @@ namespace // son contexte d'origine est actif, sinon il faudra le mettre en file d'attente // Ceci est géré par la méthode OpenGL::DeleteVertexArray - NzOpenGL::DeleteVertexArray(context, it->second); + NzOpenGL::DeleteVertexArray(context, it->second.vao); vaos.erase(it++); } else @@ -147,7 +175,7 @@ namespace for (auto& pair : s_vaos) { const NzContext* context = pair.first; - VAO_Map& vaos = pair.second; + VAO_Map& vaos = pair.second.vaoMap; auto it = vaos.begin(); while (it != vaos.end()) @@ -162,7 +190,7 @@ namespace // son contexte d'origine est actif, sinon il faudra le mettre en file d'attente // Ceci est géré par la méthode OpenGL::DeleteVertexArray - NzOpenGL::DeleteVertexArray(context, it->second); + NzOpenGL::DeleteVertexArray(context, it->second.vao); vaos.erase(it++); } else @@ -178,7 +206,7 @@ namespace for (auto& pair : s_vaos) { const NzContext* context = pair.first; - VAO_Map& vaos = pair.second; + VAO_Map& vaos = pair.second.vaoMap; auto it = vaos.begin(); while (it != vaos.end()) @@ -194,7 +222,7 @@ namespace // son contexte d'origine est actif, sinon il faudra le mettre en file d'attente // Ceci est géré par la méthode OpenGL::DeleteVertexArray - NzOpenGL::DeleteVertexArray(context, it->second); + NzOpenGL::DeleteVertexArray(context, it->second.vao); vaos.erase(it++); } else @@ -1533,28 +1561,14 @@ void NzRenderer::Uninitialize() for (auto& pair : s_vaos) { const NzContext* context = pair.first; + const Context_Entry& contextEntry = pair.second; - for (auto& pair2 : pair.second) + for (auto& pair2 : contextEntry.vaoMap) { - const VAO_Key& key = pair2.first; - const NzIndexBuffer* indexBuffer = std::get<0>(key); - const NzVertexBuffer* vertexBuffer = std::get<1>(key); - const NzVertexDeclaration* vertexDeclaration = std::get<2>(key); - const NzVertexDeclaration* instancingDeclaration = std::get<3>(key); - - if (indexBuffer) - indexBuffer->RemoveResourceListener(&s_listener); - - vertexBuffer->RemoveResourceListener(&s_listener); - vertexDeclaration->RemoveResourceListener(&s_listener); - - if (instancingDeclaration) - instancingDeclaration->RemoveResourceListener(&s_listener); - - NzOpenGL::DeleteVertexArray(context, pair2.second); + const VAO_Entry& entry = pair2.second; + NzOpenGL::DeleteVertexArray(context, entry.vao); } } - s_vaos.clear(); NzOpenGL::Uninitialize(); @@ -1719,16 +1733,16 @@ bool NzRenderer::EnsureStateUpdate() // Note: Les VAOs ne sont pas partagés entre les contextes, nous avons donc un tableau de VAOs par contexte const NzContext* context = NzContext::GetCurrent(); - VAO_Map* vaos; auto it = s_vaos.find(context); if (it == s_vaos.end()) { - context->AddResourceListener(&s_listener, ResourceType_Context); - auto pair = s_vaos.insert(std::make_pair(context, Context_Map::mapped_type())); - vaos = &pair.first->second; + Context_Entry entry(&s_listener, ResourceType_Context); + entry.contextListener = context; + + it = s_vaos.insert(std::make_pair(context, std::move(entry))).first; } - else - vaos = &it->second; + + VAO_Map& vaoMap = it->second.vaoMap; // Notre clé est composée de ce qui définit un VAO const NzVertexDeclaration* vertexDeclaration = s_vertexBuffer->GetVertexDeclaration(); @@ -1736,23 +1750,22 @@ bool NzRenderer::EnsureStateUpdate() VAO_Key key(s_indexBuffer, s_vertexBuffer, vertexDeclaration, instancingDeclaration); // On recherche un VAO existant avec notre configuration - vaoIt = vaos->find(key); - if (vaoIt == vaos->end()) + vaoIt = vaoMap.find(key); + if (vaoIt == vaoMap.end()) { // On créé notre VAO glGenVertexArrays(1, &s_currentVAO); glBindVertexArray(s_currentVAO); // On l'ajoute à notre liste - vaoIt = vaos->insert(std::make_pair(key, s_currentVAO)).first; - if (s_indexBuffer) - s_indexBuffer->AddResourceListener(&s_listener, ResourceType_IndexBuffer); + VAO_Entry entry(&s_listener, ResourceType_IndexBuffer, ResourceType_VertexBuffer, ResourceType_VertexDeclaration, ResourceType_VertexDeclaration); + entry.indexBufferListener = std::get<0>(key); + entry.instancingDeclarationListener = std::get<3>(key); + entry.vertexBufferListener = std::get<1>(key); + entry.vertexDeclarationListener = std::get<2>(key); + entry.vao = s_currentVAO; - s_vertexBuffer->AddResourceListener(&s_listener, ResourceType_VertexBuffer); - vertexDeclaration->AddResourceListener(&s_listener, ResourceType_VertexDeclaration); - - if (instancingDeclaration) - instancingDeclaration->AddResourceListener(&s_listener, ResourceType_VertexDeclaration); + vaoIt = vaoMap.insert(std::make_pair(key, std::move(entry))).first; // Et on indique qu'on veut le programmer update = true; @@ -1760,7 +1773,7 @@ bool NzRenderer::EnsureStateUpdate() else { // Notre VAO existe déjà, il est donc inutile de le reprogrammer - s_currentVAO = vaoIt->second; + s_currentVAO = vaoIt->second.vao; update = false; } @@ -1911,8 +1924,8 @@ bool NzRenderer::EnsureStateUpdate() if (updateFailed) { // La création de notre VAO a échoué, libérons-le et marquons-le comme problématique - glDeleteVertexArrays(1, &vaoIt->second); - vaoIt->second = 0; + glDeleteVertexArrays(1, &vaoIt->second.vao); + vaoIt->second.vao = 0; s_currentVAO = 0; } else diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index ee6489dfc..031329ef4 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -55,7 +55,7 @@ struct NzMeshImpl std::unordered_map subMeshMap; std::vector materials; - std::vector subMeshes; + std::vector subMeshes; nzAnimationType animationType; NzBoxf aabb; NzSkeleton skeleton; // Uniquement pour les meshs squelettiques @@ -91,9 +91,6 @@ void NzMesh::AddSubMesh(NzSubMesh* subMesh) } #endif - subMesh->AddResourceListener(this, m_impl->subMeshes.size()); - subMesh->AddResourceReference(); - m_impl->aabbUpdated = false; // On invalide l'AABB m_impl->subMeshes.push_back(subMesh); } @@ -135,9 +132,6 @@ void NzMesh::AddSubMesh(const NzString& identifier, NzSubMesh* subMesh) int index = m_impl->subMeshes.size(); - subMesh->AddResourceListener(this, index); - subMesh->AddResourceReference(); - m_impl->aabbUpdated = false; // On invalide l'AABB m_impl->subMeshes.push_back(subMesh); m_impl->subMeshMap[identifier] = index; @@ -371,12 +365,6 @@ void NzMesh::Destroy() { NotifyDestroy(); - for (NzSubMesh* subMesh : m_impl->subMeshes) - { - subMesh->RemoveResourceListener(this); - subMesh->RemoveResourceReference(); - } - delete m_impl; m_impl = nullptr; } @@ -864,11 +852,6 @@ void NzMesh::RemoveSubMesh(const NzString& identifier) auto it2 = m_impl->subMeshes.begin(); std::advance(it2, index); - // On libère la ressource - NzSubMesh* subMesh = *it2; - subMesh->RemoveResourceListener(this); - subMesh->RemoveResourceReference(); - m_impl->subMeshes.erase(it2); m_impl->aabbUpdated = false; // On invalide l'AABB @@ -894,11 +877,6 @@ void NzMesh::RemoveSubMesh(unsigned int index) auto it = m_impl->subMeshes.begin(); std::advance(it, index); - // On libère la ressource - NzSubMesh* subMesh = *it; - subMesh->RemoveResourceListener(this); - subMesh->RemoveResourceReference(); - m_impl->subMeshes.erase(it); m_impl->aabbUpdated = false; // On invalide l'AABB @@ -1011,11 +989,4 @@ void NzMesh::Transform(const NzMatrix4f& matrix) m_impl->aabbUpdated = false; } -void NzMesh::OnResourceReleased(const NzResource* resource, int index) -{ - NazaraUnused(resource); - - RemoveSubMesh(index); -} - NzMeshLoader::LoaderList NzMesh::s_loaders; diff --git a/src/Nazara/Utility/SimpleTextDrawer.cpp b/src/Nazara/Utility/SimpleTextDrawer.cpp index 64ac5a3ad..a6477d23d 100644 --- a/src/Nazara/Utility/SimpleTextDrawer.cpp +++ b/src/Nazara/Utility/SimpleTextDrawer.cpp @@ -8,17 +8,12 @@ NzSimpleTextDrawer::NzSimpleTextDrawer() : m_color(NzColor::White), +m_fontListener(this), m_style(nzTextStyle_Regular) { SetFont(NzFont::GetDefault()); } -NzSimpleTextDrawer::~NzSimpleTextDrawer() -{ - if (m_font) - m_font->RemoveResourceListener(this); -} - const NzRectui& NzSimpleTextDrawer::GetBounds() const { if (!m_glyphUpdated) @@ -63,12 +58,8 @@ void NzSimpleTextDrawer::SetColor(const NzColor& color) void NzSimpleTextDrawer::SetFont(NzFont* font) { - if (m_font) - m_font->RemoveResourceListener(this); - m_font = font; - if (m_font) - m_font->AddResourceListener(this); + m_fontListener = font; m_glyphUpdated = false; } From 911babc283b12e1de1c52b022dbdbdca86eab89c Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 19 Jan 2015 00:00:54 +0100 Subject: [PATCH 193/233] Changed meaning of return value from resource events Returning false from a resource event will remove the listener from the resource, instead of decrementing it's counter Former-commit-id: ba47da0e8de5c0adb3d31f29af0ef7835beefd5a --- include/Nazara/Core/Resource.hpp | 2 -- src/Nazara/Core/Resource.cpp | 20 ++++++++------------ 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/include/Nazara/Core/Resource.hpp b/include/Nazara/Core/Resource.hpp index 2bc392734..61cbafd1a 100644 --- a/include/Nazara/Core/Resource.hpp +++ b/include/Nazara/Core/Resource.hpp @@ -50,8 +50,6 @@ class NAZARA_API NzResource private: using ResourceListenerMap = std::unordered_map>; - void RemoveResourceListenerIterator(ResourceListenerMap::iterator iterator) const; - NazaraMutexAttrib(m_mutex, mutable) // Je fais précéder le nom par 'resource' pour éviter les éventuels conflits de noms diff --git a/src/Nazara/Core/Resource.cpp b/src/Nazara/Core/Resource.cpp index 5610d9d13..d262b5e8b 100644 --- a/src/Nazara/Core/Resource.cpp +++ b/src/Nazara/Core/Resource.cpp @@ -71,7 +71,11 @@ void NzResource::RemoveResourceListener(NzResourceListener* listener) const { ResourceListenerMap::iterator it = m_resourceListeners.find(listener); if (it != m_resourceListeners.end()) - RemoveResourceListenerIterator(it); + { + unsigned int& referenceCount = it->second.second; + if (--referenceCount == 0) + m_resourceListeners.erase(it); + } } } @@ -119,7 +123,7 @@ void NzResource::NotifyCreated() while (it != m_resourceListeners.end()) { if (!it->first->OnResourceCreated(this, it->second.first)) - RemoveResourceListenerIterator(it++); + m_resourceListeners.erase(it++); else ++it; } @@ -137,7 +141,7 @@ void NzResource::NotifyDestroy() while (it != m_resourceListeners.end()) { if (!it->first->OnResourceDestroy(this, it->second.first)) - RemoveResourceListenerIterator(it++); + m_resourceListeners.erase(it++); else ++it; } @@ -155,7 +159,7 @@ void NzResource::NotifyModified(unsigned int code) while (it != m_resourceListeners.end()) { if (!it->first->OnResourceModified(this, it->second.first, code)) - RemoveResourceListenerIterator(it++); + m_resourceListeners.erase(it++); else ++it; } @@ -163,11 +167,3 @@ void NzResource::NotifyModified(unsigned int code) m_resourceListenersLocked = false; } -void NzResource::RemoveResourceListenerIterator(ResourceListenerMap::iterator iterator) const -{ - unsigned int& referenceCount = iterator->second.second; - if (referenceCount == 1) - m_resourceListeners.erase(iterator); - else - referenceCount--; -} From ffe101ff028a78755ebaaa3c988156fab910c66d Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 19 Jan 2015 00:01:06 +0100 Subject: [PATCH 194/233] Fixed crash Former-commit-id: 61b945a634b3de01c964e197175994896c7a5d01 --- src/Nazara/Utility/Font.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index 0ee48cb92..055ae5ee4 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -402,8 +402,11 @@ void NzFont::Uninitialize() s_defaultAtlas.reset(); // On rend la police non-persistente et on demande la vérification du compteur (pouvant entraîner la libération de la ressource) - s_defaultFont->SetPersistent(false, true); - s_defaultFont = nullptr; + if (s_defaultFont) + { + s_defaultFont->SetPersistent(false, true); + s_defaultFont = nullptr; + } } nzUInt64 NzFont::ComputeKey(unsigned int characterSize, nzUInt32 style) const From f5183112236236c5dcfc1af6a0bf14200aefabdb Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 19 Jan 2015 00:02:06 +0100 Subject: [PATCH 195/233] Fixed FreeType being freed before the destruction of all fonts Former-commit-id: a7b2653c94698671d7912675ee810be3b7ac10df --- .../Utility/Loaders/FreeType/Loader.cpp | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/src/Nazara/Utility/Loaders/FreeType/Loader.cpp b/src/Nazara/Utility/Loaders/FreeType/Loader.cpp index 435ec0023..28a32b4b1 100644 --- a/src/Nazara/Utility/Loaders/FreeType/Loader.cpp +++ b/src/Nazara/Utility/Loaders/FreeType/Loader.cpp @@ -19,7 +19,10 @@ namespace { - FT_Library s_library = nullptr; + class FreeTypeLibrary; + + FT_Library s_library; + std::shared_ptr s_libraryOwner; float s_invScaleFactor = 1.f / (1 << 6); // 1/64 extern "C" @@ -55,11 +58,26 @@ namespace NazaraUnused(stream); } + class FreeTypeLibrary + { + // Cette classe ne sert qu'à être utilisée avec un std::shared_ptr + // pour ne libérer FreeType que lorsque plus personne ne l'utilise + + public: + FreeTypeLibrary() = default; + ~FreeTypeLibrary() + { + FT_Done_FreeType(s_library); + s_library = nullptr; + } + }; + class FreeTypeStream : public NzFontData { public: FreeTypeStream() : m_face(nullptr), + m_library(s_libraryOwner), m_characterSize(0) { } @@ -312,6 +330,7 @@ namespace FT_Open_Args m_args; FT_Face m_face; FT_StreamRec m_stream; + std::shared_ptr m_library; std::unique_ptr m_ownedStream; mutable unsigned int m_characterSize; }; @@ -414,7 +433,10 @@ namespace void NzLoaders_FreeType_Register() { if (FT_Init_FreeType(&s_library) == 0) + { + s_libraryOwner.reset(new FreeTypeLibrary); NzFontLoader::RegisterLoader(IsSupported, Check, LoadStream, LoadFile, LoadMemory); + } else { s_library = nullptr; // On s'assure que le pointeur ne pointe pas sur n'importe quoi @@ -427,8 +449,6 @@ void NzLoaders_FreeType_Unregister() if (s_library) { NzFontLoader::UnregisterLoader(IsSupported, Check, LoadStream, LoadFile, LoadMemory); - - FT_Done_FreeType(s_library); - s_library = nullptr; + s_libraryOwner.reset(); } } From c18fc4cb1419bdacd70bd2b5408b81593c9ddacc Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 19 Jan 2015 00:15:01 +0100 Subject: [PATCH 196/233] Removed ShaderUniform_[EyePosition|SceneAmbient] Former-commit-id: 89dedaf78d86def598531f472a1a6ecd56fe8371 --- include/Nazara/Graphics/DeferredFogPass.hpp | 1 + .../Nazara/Graphics/DeferredGeometryPass.hpp | 12 ++++++++++ .../Graphics/DeferredPhongLightingPass.hpp | 4 ++++ .../Graphics/ForwardRenderTechnique.hpp | 2 ++ include/Nazara/Renderer/Enums.hpp | 3 --- src/Nazara/Graphics/DeferredFogPass.cpp | 3 ++- src/Nazara/Graphics/DeferredGeometryPass.cpp | 24 +++++++++++++++++-- .../Graphics/DeferredPhongLightingPass.cpp | 12 ++++++---- .../Graphics/ForwardRenderTechnique.cpp | 23 +++++++++--------- src/Nazara/Renderer/Shader.cpp | 2 -- 10 files changed, 63 insertions(+), 23 deletions(-) diff --git a/include/Nazara/Graphics/DeferredFogPass.hpp b/include/Nazara/Graphics/DeferredFogPass.hpp index b17e346b0..9a785b3e4 100644 --- a/include/Nazara/Graphics/DeferredFogPass.hpp +++ b/include/Nazara/Graphics/DeferredFogPass.hpp @@ -25,6 +25,7 @@ class NAZARA_API NzDeferredFogPass : public NzDeferredRenderPass NzRenderStates m_states; NzShaderRef m_shader; NzTextureSampler m_pointSampler; + int m_shaderEyePositionLocation; }; #endif // NAZARA_DEFERREDFOGPASS_HPP diff --git a/include/Nazara/Graphics/DeferredGeometryPass.hpp b/include/Nazara/Graphics/DeferredGeometryPass.hpp index 8bdc2703c..8f90f1609 100644 --- a/include/Nazara/Graphics/DeferredGeometryPass.hpp +++ b/include/Nazara/Graphics/DeferredGeometryPass.hpp @@ -22,6 +22,18 @@ class NAZARA_API NzDeferredGeometryPass : public NzDeferredRenderPass bool Resize(const NzVector2ui& dimensions); protected: + struct ShaderUniforms; + + const ShaderUniforms* GetShaderUniforms(const NzShader* shader) const; + + struct ShaderUniforms + { + int eyePosition; + int sceneAmbient; + int textureOverlay; + }; + + mutable std::unordered_map m_shaderUniforms; NzRenderStates m_clearStates; NzShaderRef m_clearShader; }; diff --git a/include/Nazara/Graphics/DeferredPhongLightingPass.hpp b/include/Nazara/Graphics/DeferredPhongLightingPass.hpp index 38c92be48..2b8f37ac1 100644 --- a/include/Nazara/Graphics/DeferredPhongLightingPass.hpp +++ b/include/Nazara/Graphics/DeferredPhongLightingPass.hpp @@ -39,7 +39,11 @@ class NAZARA_API NzDeferredPhongLightingPass : public NzDeferredRenderPass NzStaticMesh* m_coneMesh; NzStaticMesh* m_sphereMesh; bool m_lightMeshesDrawing; + int m_directionalLightShaderEyePositionLocation; + int m_directionalLightShaderSceneAmbientLocation; int m_pointSpotLightShaderDiscardLocation; + int m_pointSpotLightShaderEyePositionLocation; + int m_pointSpotLightShaderSceneAmbientLocation; }; #endif // NAZARA_DEFERREDPHONGLIGHTINGPASS_HPP diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.hpp b/include/Nazara/Graphics/ForwardRenderTechnique.hpp index 6aa2da571..d0c23292b 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.hpp +++ b/include/Nazara/Graphics/ForwardRenderTechnique.hpp @@ -49,6 +49,8 @@ class NAZARA_API NzForwardRenderTechnique : public NzAbstractRenderTechnique, Nz int lightOffset; // "Distance" entre Lights[0].type et Lights[1].type // Autre uniformes + int eyePosition; + int sceneAmbient; int textureOverlay; }; diff --git a/include/Nazara/Renderer/Enums.hpp b/include/Nazara/Renderer/Enums.hpp index 7100d198e..2a1959a46 100644 --- a/include/Nazara/Renderer/Enums.hpp +++ b/include/Nazara/Renderer/Enums.hpp @@ -187,8 +187,6 @@ enum nzSamplerWrap enum nzShaderUniform { - ///FIXME: Virer EyePosition et SceneAmbient de l'énumération (ils n'ont rien à faire dans le module de rendu) - nzShaderUniform_EyePosition, nzShaderUniform_InvProjMatrix, nzShaderUniform_InvTargetSize, nzShaderUniform_InvViewMatrix, @@ -197,7 +195,6 @@ enum nzShaderUniform nzShaderUniform_InvWorldViewMatrix, nzShaderUniform_InvWorldViewProjMatrix, nzShaderUniform_ProjMatrix, - nzShaderUniform_SceneAmbient, nzShaderUniform_TargetSize, nzShaderUniform_ViewMatrix, nzShaderUniform_ViewProjMatrix, diff --git a/src/Nazara/Graphics/DeferredFogPass.cpp b/src/Nazara/Graphics/DeferredFogPass.cpp index 1f2e23af4..abd439d23 100644 --- a/src/Nazara/Graphics/DeferredFogPass.cpp +++ b/src/Nazara/Graphics/DeferredFogPass.cpp @@ -125,6 +125,7 @@ NzDeferredFogPass::NzDeferredFogPass() m_pointSampler.SetWrapMode(nzSamplerWrap_Clamp); m_shader = BuildFogShader(); + m_shaderEyePositionLocation = m_shader->GetUniformLocation("EyePosition"); m_states.parameters[nzRendererParameter_DepthBuffer] = false; } @@ -138,7 +139,7 @@ bool NzDeferredFogPass::Process(const NzScene* scene, unsigned int firstWorkText NzRenderer::SetViewport(NzRecti(0, 0, m_dimensions.x, m_dimensions.y)); NzRenderer::SetShader(m_shader); - m_shader->SendVector(m_shader->GetUniformLocation(nzShaderUniform_EyePosition), scene->GetViewer()->GetEyePosition()); + m_shader->SendVector(m_shaderEyePositionLocation, scene->GetViewer()->GetEyePosition()); NzRenderer::SetRenderStates(m_states); NzRenderer::SetTexture(0, m_workTextures[secondWorkTexture]); diff --git a/src/Nazara/Graphics/DeferredGeometryPass.cpp b/src/Nazara/Graphics/DeferredGeometryPass.cpp index 228fdfe8c..a9b10f652 100644 --- a/src/Nazara/Graphics/DeferredGeometryPass.cpp +++ b/src/Nazara/Graphics/DeferredGeometryPass.cpp @@ -51,6 +51,7 @@ bool NzDeferredGeometryPass::Process(const NzScene* scene, unsigned int firstWor NzRenderer::SetMatrix(nzMatrixType_View, viewer->GetViewMatrix()); const NzShader* lastShader = nullptr; + const ShaderUniforms* shaderUniforms = nullptr; for (auto& matIt : m_renderQueue->opaqueModels) { @@ -76,10 +77,13 @@ bool NzDeferredGeometryPass::Process(const NzScene* scene, unsigned int firstWor // 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(shader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); + shader->SendColor(shaderUniforms->sceneAmbient, scene->GetAmbientColor()); // Position de la caméra - shader->SendVector(shader->GetUniformLocation(nzShaderUniform_EyePosition), viewer->GetEyePosition()); + shader->SendVector(shaderUniforms->eyePosition, viewer->GetEyePosition()); lastShader = shader; } @@ -230,3 +234,19 @@ bool NzDeferredGeometryPass::Resize(const NzVector2ui& dimensions) return false; } } + +const NzDeferredGeometryPass::ShaderUniforms* NzDeferredGeometryPass::GetShaderUniforms(const NzShader* shader) const +{ + auto it = m_shaderUniforms.find(shader); + if (it == m_shaderUniforms.end()) + { + ShaderUniforms uniforms; + uniforms.eyePosition = shader->GetUniformLocation("EyePosition"); + uniforms.sceneAmbient = shader->GetUniformLocation("SceneAmbient"); + uniforms.textureOverlay = shader->GetUniformLocation("TextureOverlay"); + + it = m_shaderUniforms.emplace(shader, uniforms).first; + } + + return &it->second; +} diff --git a/src/Nazara/Graphics/DeferredPhongLightingPass.cpp b/src/Nazara/Graphics/DeferredPhongLightingPass.cpp index 7068114cc..64b58ddb1 100644 --- a/src/Nazara/Graphics/DeferredPhongLightingPass.cpp +++ b/src/Nazara/Graphics/DeferredPhongLightingPass.cpp @@ -17,6 +17,8 @@ NzDeferredPhongLightingPass::NzDeferredPhongLightingPass() : m_lightMeshesDrawing(false) { m_directionalLightShader = NzShaderLibrary::Get("DeferredDirectionnalLight"); + m_directionalLightShaderEyePositionLocation = m_directionalLightShader->GetUniformLocation("EyePosition"); + m_directionalLightShaderSceneAmbientLocation = m_directionalLightShader->GetUniformLocation("SceneAmbient"); m_directionalLightUniforms.ubo = false; m_directionalLightUniforms.locations.type = -1; // Type déjà connu @@ -28,6 +30,8 @@ m_lightMeshesDrawing(false) m_pointSpotLightShader = NzShaderLibrary::Get("DeferredPointSpotLight"); m_pointSpotLightShaderDiscardLocation = m_pointSpotLightShader->GetUniformLocation("Discard"); + m_pointSpotLightShaderEyePositionLocation = m_pointSpotLightShader->GetUniformLocation("EyePosition"); + m_pointSpotLightShaderSceneAmbientLocation = m_pointSpotLightShader->GetUniformLocation("SceneAmbient"); m_pointSpotLightUniforms.ubo = false; m_pointSpotLightUniforms.locations.type = m_pointSpotLightShader->GetUniformLocation("LightType"); @@ -96,8 +100,8 @@ bool NzDeferredPhongLightingPass::Process(const NzScene* scene, unsigned int fir { NzRenderer::SetRenderStates(lightStates); NzRenderer::SetShader(m_directionalLightShader); - m_directionalLightShader->SendColor(m_directionalLightShader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); - m_directionalLightShader->SendVector(m_directionalLightShader->GetUniformLocation(nzShaderUniform_EyePosition), scene->GetViewer()->GetEyePosition()); + m_directionalLightShader->SendColor(m_directionalLightShaderSceneAmbientLocation, scene->GetAmbientColor()); + m_directionalLightShader->SendVector(m_directionalLightShaderEyePositionLocation, scene->GetViewer()->GetEyePosition()); for (const NzLight* light : m_renderQueue->directionalLights) { @@ -126,8 +130,8 @@ bool NzDeferredPhongLightingPass::Process(const NzScene* scene, unsigned int fir NzRenderer::SetRenderStates(lightStates); NzRenderer::SetShader(m_pointSpotLightShader); - m_pointSpotLightShader->SendColor(m_pointSpotLightShader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); - m_pointSpotLightShader->SendVector(m_pointSpotLightShader->GetUniformLocation(nzShaderUniform_EyePosition), scene->GetViewer()->GetEyePosition()); + m_pointSpotLightShader->SendColor(m_pointSpotLightShaderEyePositionLocation, scene->GetAmbientColor()); + m_pointSpotLightShader->SendVector(m_pointSpotLightShaderSceneAmbientLocation, scene->GetViewer()->GetEyePosition()); NzMatrix4f lightMatrix; lightMatrix.MakeIdentity(); diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index e7f6168de..39a9587dd 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -210,11 +210,11 @@ void NzForwardRenderTechnique::DrawBasicSprites(const NzScene* scene) const shaderUniforms = GetShaderUniforms(shader); // Couleur ambiante de la scène - shader->SendColor(shader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); + shader->SendColor(shaderUniforms->sceneAmbient, scene->GetAmbientColor()); // Overlay shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); // Position de la caméra - shader->SendVector(shader->GetUniformLocation(nzShaderUniform_EyePosition), viewer->GetEyePosition()); + shader->SendVector(shaderUniforms->eyePosition, viewer->GetEyePosition()); lastShader = shader; } @@ -299,9 +299,9 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const shaderUniforms = GetShaderUniforms(shader); // Couleur ambiante de la scène - shader->SendColor(shader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); + shader->SendColor(shaderUniforms->sceneAmbient, scene->GetAmbientColor()); // Position de la caméra - shader->SendVector(shader->GetUniformLocation(nzShaderUniform_EyePosition), viewer->GetEyePosition()); + shader->SendVector(shaderUniforms->eyePosition, viewer->GetEyePosition()); lastShader = shader; } @@ -503,9 +503,9 @@ void NzForwardRenderTechnique::DrawTransparentModels(const NzScene* scene) const shaderUniforms = GetShaderUniforms(shader); // Couleur ambiante de la scène - shader->SendColor(shader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); + shader->SendColor(shaderUniforms->sceneAmbient, scene->GetAmbientColor()); // Position de la caméra - shader->SendVector(shader->GetUniformLocation(nzShaderUniform_EyePosition), viewer->GetEyePosition()); + shader->SendVector(shaderUniforms->eyePosition, viewer->GetEyePosition()); // On envoie les lumières directionnelles s'il y a (Les mêmes pour tous) lightCount = std::min(m_directionalLights.GetLightCount(), NazaraSuffixMacro(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS, U)); @@ -563,11 +563,11 @@ void NzForwardRenderTechnique::DrawTransparentModels(const NzScene* scene) const const NzForwardRenderTechnique::ShaderUniforms* NzForwardRenderTechnique::GetShaderUniforms(const NzShader* shader) const { auto it = m_shaderUniforms.find(shader); - if (it != m_shaderUniforms.end()) - return &(it->second); - else + if (it == m_shaderUniforms.end()) { ShaderUniforms uniforms; + uniforms.eyePosition = shader->GetUniformLocation("EyePosition"); + uniforms.sceneAmbient = shader->GetUniformLocation("SceneAmbient"); uniforms.textureOverlay = shader->GetUniformLocation("TextureOverlay"); int type0Location = shader->GetUniformLocation("Lights[0].type"); @@ -588,7 +588,8 @@ const NzForwardRenderTechnique::ShaderUniforms* NzForwardRenderTechnique::GetSha else uniforms.hasLightUniforms = false; - auto pair = m_shaderUniforms.emplace(shader, uniforms); - return &(pair.first->second); + it = m_shaderUniforms.emplace(shader, uniforms).first; } + + return &it->second; } diff --git a/src/Nazara/Renderer/Shader.cpp b/src/Nazara/Renderer/Shader.cpp index 8d9239da2..e9c4fd968 100644 --- a/src/Nazara/Renderer/Shader.cpp +++ b/src/Nazara/Renderer/Shader.cpp @@ -789,7 +789,6 @@ bool NzShader::PostLinkage() // Pour éviter de se tromper entre le nom et la constante #define CacheUniform(name) m_uniformLocations[nzShaderUniform_##name] = glGetUniformLocation(m_program, #name) - CacheUniform(EyePosition); CacheUniform(InvProjMatrix); CacheUniform(InvTargetSize); CacheUniform(InvViewMatrix); @@ -798,7 +797,6 @@ bool NzShader::PostLinkage() CacheUniform(InvWorldViewMatrix); CacheUniform(InvWorldViewProjMatrix); CacheUniform(ProjMatrix); - CacheUniform(SceneAmbient); CacheUniform(TargetSize); CacheUniform(ViewMatrix); CacheUniform(ViewProjMatrix); From 61188d0b3ececfa54f080ee7c90f5bac0dbf9cd4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 19 Jan 2015 00:17:03 +0100 Subject: [PATCH 197/233] Added Cabin license (Oops) Former-commit-id: 0e53b826308c76063c5d463ab22ca82bb2ef3b8b --- License-Cabin.txt | 95 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 License-Cabin.txt diff --git a/License-Cabin.txt b/License-Cabin.txt new file mode 100644 index 000000000..ce98ff4b5 --- /dev/null +++ b/License-Cabin.txt @@ -0,0 +1,95 @@ +Copyright (c) 2011, Pablo Impallari (www.impallari.com|impallari@gmail.com), +Copyright (c) 2011, Igino Marini. (www.ikern.com|mail@iginomarini.com), +with Reserved Font Name Cabin. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. From 75ffa09792278a16700bba8d126e769d1a8eb535 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 19 Jan 2015 02:32:48 +0100 Subject: [PATCH 198/233] Fixed errors from last merge Former-commit-id: 850eadf5e233d0d6efad039b6bd943f05384df7d --- src/Nazara/Graphics/ForwardRenderQueue.cpp | 133 ++++++++++++++++----- 1 file changed, 105 insertions(+), 28 deletions(-) diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index 37d41cb5c..c12658a8d 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -85,11 +85,22 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in if (!alphaPtr) alphaPtr.Reset(&defaultAlpha, 0); // Pareil - std::vector& billboardVec = billboards[material]; - unsigned int prevSize = billboardVec.size(); - billboardVec.resize(prevSize + count); + auto it = billboards.find(material); + if (it == billboards.end()) + { + BatchedBillboardEntry entry(this, ResourceType_Material); + entry.materialListener = material; - BillboardData* billboardData = &billboardVec[prevSize]; + it = billboards.insert(std::make_pair(material, std::move(entry))).first; + } + + BatchedBillboardEntry& entry = it->second; + + auto& billboardVector = entry.billboards; + unsigned int prevSize = billboardVector.size(); + billboardVector.resize(prevSize + count); + + BillboardData* billboardData = &billboardVector[prevSize]; for (unsigned int i = 0; i < count; ++i) { billboardData->center = *positionPtr++; @@ -111,11 +122,22 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in if (!colorPtr) colorPtr.Reset(&NzColor::White, 0); // Pareil - std::vector& billboardVec = billboards[material]; - unsigned int prevSize = billboardVec.size(); - billboardVec.resize(prevSize + count); + auto it = billboards.find(material); + if (it == billboards.end()) + { + BatchedBillboardEntry entry(this, ResourceType_Material); + entry.materialListener = material; - BillboardData* billboardData = &billboardVec[prevSize]; + it = billboards.insert(std::make_pair(material, std::move(entry))).first; + } + + BatchedBillboardEntry& entry = it->second; + + auto& billboardVector = entry.billboards; + unsigned int prevSize = billboardVector.size(); + billboardVector.resize(prevSize + count); + + BillboardData* billboardData = &billboardVector[prevSize]; for (unsigned int i = 0; i < count; ++i) { float sin = std::sin(NzToRadians(*anglePtr)); @@ -143,11 +165,22 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in if (!alphaPtr) alphaPtr.Reset(&defaultAlpha, 0); // Pareil - std::vector& billboardVec = billboards[material]; - unsigned int prevSize = billboardVec.size(); - billboardVec.resize(prevSize + count); + auto it = billboards.find(material); + if (it == billboards.end()) + { + BatchedBillboardEntry entry(this, ResourceType_Material); + entry.materialListener = material; - BillboardData* billboardData = &billboardVec[prevSize]; + it = billboards.insert(std::make_pair(material, std::move(entry))).first; + } + + BatchedBillboardEntry& entry = it->second; + + auto& billboardVector = entry.billboards; + unsigned int prevSize = billboardVector.size(); + billboardVector.resize(prevSize + count); + + BillboardData* billboardData = &billboardVector[prevSize]; for (unsigned int i = 0; i < count; ++i) { float sin = std::sin(NzToRadians(*anglePtr)); @@ -173,11 +206,22 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in if (!colorPtr) colorPtr.Reset(&NzColor::White, 0); // Pareil - std::vector& billboardVec = billboards[material]; - unsigned int prevSize = billboardVec.size(); - billboardVec.resize(prevSize + count); + auto it = billboards.find(material); + if (it == billboards.end()) + { + BatchedBillboardEntry entry(this, ResourceType_Material); + entry.materialListener = material; - BillboardData* billboardData = &billboardVec[prevSize]; + it = billboards.insert(std::make_pair(material, std::move(entry))).first; + } + + BatchedBillboardEntry& entry = it->second; + + auto& billboardVector = entry.billboards; + unsigned int prevSize = billboardVector.size(); + billboardVector.resize(prevSize + count); + + BillboardData* billboardData = &billboardVector[prevSize]; for (unsigned int i = 0; i < count; ++i) { billboardData->center = *positionPtr++; @@ -201,11 +245,22 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in if (!alphaPtr) alphaPtr.Reset(&defaultAlpha, 0); // Pareil - std::vector& billboardVec = billboards[material]; - unsigned int prevSize = billboardVec.size(); - billboardVec.resize(prevSize + count); + auto it = billboards.find(material); + if (it == billboards.end()) + { + BatchedBillboardEntry entry(this, ResourceType_Material); + entry.materialListener = material; - BillboardData* billboardData = &billboardVec[prevSize]; + it = billboards.insert(std::make_pair(material, std::move(entry))).first; + } + + BatchedBillboardEntry& entry = it->second; + + auto& billboardVector = entry.billboards; + unsigned int prevSize = billboardVector.size(); + billboardVector.resize(prevSize + count); + + BillboardData* billboardData = &billboardVector[prevSize]; for (unsigned int i = 0; i < count; ++i) { billboardData->center = *positionPtr++; @@ -227,11 +282,22 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in if (!colorPtr) colorPtr.Reset(&NzColor::White, 0); // Pareil - std::vector& billboardVec = billboards[material]; - unsigned int prevSize = billboardVec.size(); - billboardVec.resize(prevSize + count); + auto it = billboards.find(material); + if (it == billboards.end()) + { + BatchedBillboardEntry entry(this, ResourceType_Material); + entry.materialListener = material; - BillboardData* billboardData = &billboardVec[prevSize]; + it = billboards.insert(std::make_pair(material, std::move(entry))).first; + } + + BatchedBillboardEntry& entry = it->second; + + auto& billboardVector = entry.billboards; + unsigned int prevSize = billboardVector.size(); + billboardVector.resize(prevSize + count); + + BillboardData* billboardData = &billboardVector[prevSize]; for (unsigned int i = 0; i < count; ++i) { float sin = std::sin(NzToRadians(*anglePtr)); @@ -259,11 +325,22 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in if (!alphaPtr) alphaPtr.Reset(&defaultAlpha, 0); // Pareil - std::vector& billboardVec = billboards[material]; - unsigned int prevSize = billboardVec.size(); - billboardVec.resize(prevSize + count); + auto it = billboards.find(material); + if (it == billboards.end()) + { + BatchedBillboardEntry entry(this, ResourceType_Material); + entry.materialListener = material; - BillboardData* billboardData = &billboardVec[prevSize]; + it = billboards.insert(std::make_pair(material, std::move(entry))).first; + } + + BatchedBillboardEntry& entry = it->second; + + auto& billboardVector = entry.billboards; + unsigned int prevSize = billboardVector.size(); + billboardVector.resize(prevSize + count); + + BillboardData* billboardData = &billboardVector[prevSize]; for (unsigned int i = 0; i < count; ++i) { float sin = std::sin(NzToRadians(*anglePtr)); From 5d16d7ab7effa54f837e2659bd3eb9ec0bc3e37f Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 19 Jan 2015 11:56:26 +0100 Subject: [PATCH 199/233] (Material) Fixed depth sorting not being copied Former-commit-id: ecd4e3c8e44c6027c0e662f7d9d235a69ca9dc3d --- src/Nazara/Graphics/Material.cpp | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 1933d0414..0f7d82b19 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -628,24 +628,25 @@ NzMaterial* NzMaterial::GetDefault() 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_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_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; - m_diffuseMap = material.m_diffuseMap; + 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_heightMap = material.m_heightMap; + m_normalMap = material.m_normalMap; m_specularMap = material.m_specularMap; // Copie de la référence vers l'Über-Shader From e2d4ba030ca988c9af46c56de78458b8c621977e Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 19 Jan 2015 11:57:19 +0100 Subject: [PATCH 200/233] Alphabetical commit Former-commit-id: bacf8ab447d3022b48aac5f5ca2d337bc1283f8c --- include/Nazara/Graphics/ParticleSystem.hpp | 2 +- src/Nazara/Graphics/ParticleSystem.cpp | 27 +++++++++++----------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/include/Nazara/Graphics/ParticleSystem.hpp b/include/Nazara/Graphics/ParticleSystem.hpp index 73192de4c..b5fc30c2b 100644 --- a/include/Nazara/Graphics/ParticleSystem.hpp +++ b/include/Nazara/Graphics/ParticleSystem.hpp @@ -69,8 +69,8 @@ class NAZARA_API NzParticleSystem : public NzSceneNode, NzUpdatable void Register() override; void ResizeBuffer(); void Unregister() override; - void UpdateBoundingVolume() const; void Update() override; + void UpdateBoundingVolume() const; std::set> m_dyingParticles; mutable std::vector m_buffer; diff --git a/src/Nazara/Graphics/ParticleSystem.cpp b/src/Nazara/Graphics/ParticleSystem.cpp index 0d95f63a4..fbc8cd908 100644 --- a/src/Nazara/Graphics/ParticleSystem.cpp +++ b/src/Nazara/Graphics/ParticleSystem.cpp @@ -295,18 +295,6 @@ void NzParticleSystem::Unregister() m_scene->UnregisterForUpdate(this); } -void NzParticleSystem::UpdateBoundingVolume() const -{ - if (m_boundingVolume.IsNull()) - GenerateAABB(); - - if (!m_transformMatrixUpdated) - UpdateTransformMatrix(); - - m_boundingVolume.Update(m_transformMatrix); - m_boundingVolumeUpdated = true; -} - void NzParticleSystem::Update() { float elapsedTime = m_scene->GetUpdateTime(); @@ -345,8 +333,7 @@ void NzParticleSystem::Update() controller->Apply(*this, mapper, 0, m_particleCount-1, elapsedTime); } - m_processing = false; - onExit.Reset(); + onExit.CallAndReset(); // On tue maintenant les particules mortes durant la mise à jour if (m_dyingParticles.size() < m_particleCount) @@ -363,3 +350,15 @@ void NzParticleSystem::Update() m_dyingParticles.clear(); } } + +void NzParticleSystem::UpdateBoundingVolume() const +{ + if (m_boundingVolume.IsNull()) + GenerateAABB(); + + if (!m_transformMatrixUpdated) + UpdateTransformMatrix(); + + m_boundingVolume.Update(m_transformMatrix); + m_boundingVolumeUpdated = true; +} From 47fa5dc7311f62e2cef79a879c06fadd09fd4266 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 19 Jan 2015 20:34:09 +0100 Subject: [PATCH 201/233] Moved resources includes to the top of the implementations Former-commit-id: 788a62f66aa47fe76e32ef0b76e9e962b1c5f2e6 --- .../Graphics/DeferredRenderTechnique.cpp | 70 +++++++++---------- src/Nazara/Graphics/Material.cpp | 43 ++++++------ src/Nazara/Graphics/ParticleSystem.cpp | 2 +- src/Nazara/Renderer/Renderer.cpp | 48 ++++++------- 4 files changed, 83 insertions(+), 80 deletions(-) diff --git a/src/Nazara/Graphics/DeferredRenderTechnique.cpp b/src/Nazara/Graphics/DeferredRenderTechnique.cpp index 042af5c81..d05b39fe7 100644 --- a/src/Nazara/Graphics/DeferredRenderTechnique.cpp +++ b/src/Nazara/Graphics/DeferredRenderTechnique.cpp @@ -35,6 +35,34 @@ namespace { + const nzUInt8 r_fragmentSource_BloomBright[] = { + #include + }; + + const nzUInt8 r_fragmentSource_BloomFinal[] = { + #include + }; + + const nzUInt8 r_fragmentSource_DirectionalLight[] = { + #include + }; + + const nzUInt8 r_fragmentSource_FXAA[] = { + #include + }; + + const nzUInt8 r_fragmentSource_GBufferClear[] = { + #include + }; + + const nzUInt8 r_fragmentSource_GaussianBlur[] = { + #include + }; + + const nzUInt8 r_fragmentSource_PointSpotLight[] = { + #include + }; + unsigned int RenderPassPriority[] = { 6, // nzRenderPassType_AA @@ -412,34 +440,6 @@ bool NzDeferredRenderTechnique::Resize(const NzVector2ui& dimensions) const bool NzDeferredRenderTechnique::Initialize() { - const nzUInt8 fragmentSource_BloomBright[] = { - #include - }; - - const nzUInt8 fragmentSource_BloomFinal[] = { - #include - }; - - const nzUInt8 fragmentSource_DirectionalLight[] = { - #include - }; - - const nzUInt8 fragmentSource_FXAA[] = { - #include - }; - - const nzUInt8 fragmentSource_GBufferClear[] = { - #include - }; - - const nzUInt8 fragmentSource_GaussianBlur[] = { - #include - }; - - const nzUInt8 fragmentSource_PointSpotLight[] = { - #include - }; - const char vertexSource_Basic[] = "#version 140\n" @@ -497,7 +497,7 @@ bool NzDeferredRenderTechnique::Initialize() NzShader* shader; // Shaders critiques (Nécessaires pour le Deferred Shading minimal) - shader = RegisterDeferredShader("DeferredGBufferClear", fragmentSource_GBufferClear, sizeof(fragmentSource_GBufferClear), ppVertexStage, &error); + shader = RegisterDeferredShader("DeferredGBufferClear", r_fragmentSource_GBufferClear, sizeof(r_fragmentSource_GBufferClear), ppVertexStage, &error); if (!shader) { NazaraError("Failed to register critical shader: " + error); @@ -505,7 +505,7 @@ bool NzDeferredRenderTechnique::Initialize() } - shader = RegisterDeferredShader("DeferredDirectionnalLight", fragmentSource_DirectionalLight, sizeof(fragmentSource_DirectionalLight), ppVertexStage, &error); + shader = RegisterDeferredShader("DeferredDirectionnalLight", r_fragmentSource_DirectionalLight, sizeof(r_fragmentSource_DirectionalLight), ppVertexStage, &error); if (!shader) { NazaraError("Failed to register critical shader: " + error); @@ -517,7 +517,7 @@ bool NzDeferredRenderTechnique::Initialize() shader->SendInteger(shader->GetUniformLocation("GBuffer2"), 2); - shader = RegisterDeferredShader("DeferredPointSpotLight", fragmentSource_PointSpotLight, sizeof(fragmentSource_PointSpotLight), basicVertexStage, &error); + shader = RegisterDeferredShader("DeferredPointSpotLight", r_fragmentSource_PointSpotLight, sizeof(r_fragmentSource_PointSpotLight), basicVertexStage, &error); if (!shader) { NazaraError("Failed to register critical shader: " + error); @@ -530,7 +530,7 @@ bool NzDeferredRenderTechnique::Initialize() // Shaders optionnels (S'ils ne sont pas présents, le rendu minimal sera quand même assuré) - shader = RegisterDeferredShader("DeferredBloomBright", fragmentSource_BloomBright, sizeof(fragmentSource_BloomBright), ppVertexStage, &error); + shader = RegisterDeferredShader("DeferredBloomBright", r_fragmentSource_BloomBright, sizeof(r_fragmentSource_BloomBright), ppVertexStage, &error); if (shader) shader->SendInteger(shader->GetUniformLocation("ColorTexture"), 0); else @@ -539,7 +539,7 @@ bool NzDeferredRenderTechnique::Initialize() } - shader = RegisterDeferredShader("DeferredBloomFinal", fragmentSource_BloomFinal, sizeof(fragmentSource_BloomFinal), ppVertexStage, &error); + shader = RegisterDeferredShader("DeferredBloomFinal", r_fragmentSource_BloomFinal, sizeof(r_fragmentSource_BloomFinal), ppVertexStage, &error); if (shader) { shader->SendInteger(shader->GetUniformLocation("ColorTexture"), 0); @@ -551,7 +551,7 @@ bool NzDeferredRenderTechnique::Initialize() } - shader = RegisterDeferredShader("DeferredFXAA", fragmentSource_FXAA, sizeof(fragmentSource_FXAA), ppVertexStage, &error); + shader = RegisterDeferredShader("DeferredFXAA", r_fragmentSource_FXAA, sizeof(r_fragmentSource_FXAA), ppVertexStage, &error); if (shader) shader->SendInteger(shader->GetUniformLocation("ColorTexture"), 0); else @@ -560,7 +560,7 @@ bool NzDeferredRenderTechnique::Initialize() } - shader = RegisterDeferredShader("DeferredGaussianBlur", fragmentSource_GaussianBlur, sizeof(fragmentSource_GaussianBlur), ppVertexStage, &error); + shader = RegisterDeferredShader("DeferredGaussianBlur", r_fragmentSource_GaussianBlur, sizeof(r_fragmentSource_GaussianBlur), ppVertexStage, &error); if (shader) shader->SendInteger(shader->GetUniformLocation("ColorTexture"), 0); else diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 0f7d82b19..c79b4d6d0 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -15,6 +15,25 @@ #include #include +namespace +{ + const nzUInt8 r_coreFragmentShader[] = { + #include + }; + + const nzUInt8 r_coreVertexShader[] = { + #include + }; + + const nzUInt8 r_compatibilityFragmentShader[] = { + #include + }; + + const nzUInt8 r_compatibilityVertexShader[] = { + #include + }; +} + bool NzMaterialParams::IsValid() const { if (!NzUberShaderLibrary::Has(shaderName)) @@ -719,29 +738,13 @@ bool NzMaterial::Initialize() NzString vertexShader; if (glsl140) { - const nzUInt8 coreFragmentShader[] = { - #include - }; - - const nzUInt8 coreVertexShader[] = { - #include - }; - - fragmentShader.Set(reinterpret_cast(coreFragmentShader), sizeof(coreFragmentShader)); - vertexShader.Set(reinterpret_cast(coreVertexShader), sizeof(coreVertexShader)); + fragmentShader.Set(reinterpret_cast(r_coreFragmentShader), sizeof(r_coreFragmentShader)); + vertexShader.Set(reinterpret_cast(r_coreVertexShader), sizeof(r_coreVertexShader)); } else { - const nzUInt8 compatibilityFragmentShader[] = { - #include - }; - - const nzUInt8 compatibilityVertexShader[] = { - #include - }; - - fragmentShader.Set(reinterpret_cast(compatibilityFragmentShader), sizeof(compatibilityFragmentShader)); - vertexShader.Set(reinterpret_cast(compatibilityVertexShader), sizeof(compatibilityVertexShader)); + fragmentShader.Set(reinterpret_cast(r_compatibilityFragmentShader), sizeof(r_compatibilityFragmentShader)); + vertexShader.Set(reinterpret_cast(r_compatibilityVertexShader), sizeof(r_compatibilityVertexShader)); } uberShader->SetShader(nzShaderStage_Fragment, fragmentShader, "FLAG_TEXTUREOVERLAY ALPHA_MAPPING ALPHA_TEST AUTO_TEXCOORDS DIFFUSE_MAPPING"); diff --git a/src/Nazara/Graphics/ParticleSystem.cpp b/src/Nazara/Graphics/ParticleSystem.cpp index fbc8cd908..9bde83488 100644 --- a/src/Nazara/Graphics/ParticleSystem.cpp +++ b/src/Nazara/Graphics/ParticleSystem.cpp @@ -279,7 +279,7 @@ void NzParticleSystem::ResizeBuffer() // Histoire de décrire un peu mieux l'erreur en cas d'échec try { - m_buffer.resize(m_maxParticleCount*m_particleSize); + m_buffer.resize(m_maxParticleCount*m_particleSize*2); } catch (const std::exception& e) { diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index ec806b69c..fff66de22 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -34,6 +34,22 @@ namespace { + const nzUInt8 r_coreFragmentShader[] = { + #include + }; + + const nzUInt8 r_coreVertexShader[] = { + #include + }; + + const nzUInt8 r_compatibilityFragmentShader[] = { + #include + }; + + const nzUInt8 r_compatibilityVertexShader[] = { + #include + }; + enum ResourceType { ResourceType_Context, @@ -876,39 +892,23 @@ bool NzRenderer::Initialize() return false; } - const nzUInt8 coreFragmentShader[] = { - #include - }; - - const nzUInt8 coreVertexShader[] = { - #include - }; - - const nzUInt8 compatibilityFragmentShader[] = { - #include - }; - - const nzUInt8 compatibilityVertexShader[] = { - #include - }; - const char* fragmentShader; const char* vertexShader; unsigned int fragmentShaderLength; unsigned int vertexShaderLength; if (NzOpenGL::GetGLSLVersion() >= 140) { - fragmentShader = reinterpret_cast(coreFragmentShader); - fragmentShaderLength = sizeof(coreFragmentShader); - vertexShader = reinterpret_cast(coreVertexShader); - vertexShaderLength = sizeof(coreVertexShader); + fragmentShader = reinterpret_cast(r_coreFragmentShader); + fragmentShaderLength = sizeof(r_coreFragmentShader); + vertexShader = reinterpret_cast(r_coreVertexShader); + vertexShaderLength = sizeof(r_coreVertexShader); } else { - fragmentShader = reinterpret_cast(compatibilityFragmentShader); - fragmentShaderLength = sizeof(compatibilityFragmentShader); - vertexShader = reinterpret_cast(compatibilityVertexShader); - vertexShaderLength = sizeof(compatibilityVertexShader); + fragmentShader = reinterpret_cast(r_compatibilityFragmentShader); + fragmentShaderLength = sizeof(r_compatibilityFragmentShader); + vertexShader = reinterpret_cast(r_compatibilityVertexShader); + vertexShaderLength = sizeof(r_compatibilityVertexShader); } if (!shader->AttachStageFromSource(nzShaderStage_Fragment, fragmentShader, fragmentShaderLength)) From 7cf561f05ebb2e936517e4db8237411277e59ee3 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 19 Jan 2015 22:56:47 +0100 Subject: [PATCH 202/233] Optimized SimpleTextSprite Former-commit-id: 623ab358d0e1a1e24d64e676949adc3597890303 --- src/Nazara/Utility/SimpleTextDrawer.cpp | 36 +++++++++++-------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/src/Nazara/Utility/SimpleTextDrawer.cpp b/src/Nazara/Utility/SimpleTextDrawer.cpp index a6477d23d..f0b06ad03 100644 --- a/src/Nazara/Utility/SimpleTextDrawer.cpp +++ b/src/Nazara/Utility/SimpleTextDrawer.cpp @@ -205,6 +205,9 @@ void NzSimpleTextDrawer::UpdateGlyphs() const // "Curseur" de dessin NzVector2ui drawPos(0, m_characterSize); + // On calcule les bornes en flottants pour accélérer les calculs (il est coûteux de changer de type trop souvent) + bool firstGlyph = true; + NzRectf textBounds = NzRectf::Zero(); m_glyphs.reserve(size); nzUInt32 previousCharacter = 0; for (unsigned int i = 0; i < size; ++i) @@ -250,7 +253,7 @@ void NzSimpleTextDrawer::UpdateGlyphs() const glyph.color = m_color; glyph.flipped = fontGlyph.flipped; - float advance = fontGlyph.advance; + int advance = fontGlyph.advance; NzRectf bounds(fontGlyph.aabb); bounds.x += drawPos.x; @@ -269,7 +272,7 @@ void NzSimpleTextDrawer::UpdateGlyphs() const bounds.y -= offset.y; // On ajuste l'espacement - advance *= 1.1f; + advance += advance/10; } // On "penche" le glyphe pour obtenir un semblant d'italique @@ -282,27 +285,18 @@ void NzSimpleTextDrawer::UpdateGlyphs() const glyph.corners[2].Set(bounds.x - italicBottom, bounds.y + bounds.height); glyph.corners[3].Set(bounds.x + bounds.width - italicBottom, bounds.y + bounds.height); - m_glyphs.push_back(glyph); + if (firstGlyph) + { + textBounds.Set(glyph.corners[0]); + firstGlyph = false; + } + + for (unsigned int j = 0; j < 4; ++j) + textBounds.ExtendTo(glyph.corners[j]); drawPos.x += advance; + m_glyphs.push_back(glyph); } - // Calcul des bornes - if (!m_glyphs.empty()) - { - for (unsigned int i = 0; i < m_glyphs.size(); ++i) - { - Glyph& glyph = m_glyphs[i]; - - for (unsigned int j = 0; j < 4; ++j) - { - NzVector2ui corner(std::ceil(glyph.corners[j].x), std::ceil(glyph.corners[j].y)); - - if (i == 0 && j == 0) - m_bounds.Set(corner.x, corner.y, 0, 0); - else - m_bounds.ExtendTo(corner); - } - } - } + m_bounds.Set(std::floor(textBounds.x), std::floor(textBounds.y), std::ceil(textBounds.width), std::ceil(textBounds.height)); } From c9d636c929abed06e11e1fde0d9f2d0f2dd5cd85 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 20 Jan 2015 00:12:50 +0100 Subject: [PATCH 203/233] Fixed particle generation terrible performances Former-commit-id: 484ab2a95a2848aecef0089dea458791c2b86735 --- src/Nazara/Graphics/ParticleSystem.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nazara/Graphics/ParticleSystem.cpp b/src/Nazara/Graphics/ParticleSystem.cpp index 9bde83488..213fd1fce 100644 --- a/src/Nazara/Graphics/ParticleSystem.cpp +++ b/src/Nazara/Graphics/ParticleSystem.cpp @@ -127,7 +127,7 @@ void* NzParticleSystem::GenerateParticles(unsigned int count) NzParticleMapper mapper(ptr, m_declaration); for (NzParticleGenerator* generator : m_generators) - generator->Generate(*this, mapper, 0, m_particleCount-1); + generator->Generate(*this, mapper, 0, count-1); return ptr; } @@ -279,7 +279,7 @@ void NzParticleSystem::ResizeBuffer() // Histoire de décrire un peu mieux l'erreur en cas d'échec try { - m_buffer.resize(m_maxParticleCount*m_particleSize*2); + m_buffer.resize(m_maxParticleCount*m_particleSize); } catch (const std::exception& e) { From f714a58993889c13a487f8b7088ecaa98b2d64af Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 20 Jan 2015 01:20:33 +0100 Subject: [PATCH 204/233] Added TODO Former-commit-id: 7695c390112ebaa2340779e32f417ae302905b09 --- src/Nazara/Graphics/ForwardRenderQueue.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index c12658a8d..ca4a4865c 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -7,6 +7,8 @@ #include #include +///TODO: Remplacer les sinus/cosinus par une lookup table (va booster les perfs d'un bon x10) + namespace { enum ResourceType From b7307c462ae2733933e2d656b0655b4f4cf0551e Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 20 Jan 2015 01:20:48 +0100 Subject: [PATCH 205/233] Removed old unused code Former-commit-id: 40985382a9f79620c4459f6997f1ce12b000a74f --- .../Graphics/ForwardRenderTechnique.cpp | 45 ------------------- 1 file changed, 45 deletions(-) diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index f42561fc3..09e4e7910 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -83,51 +83,6 @@ bool NzForwardRenderTechnique::Draw(const NzScene* scene) const drawable->Draw(); return true; - - // Les billboards - /*if (!m_renderQueue.billboards.empty()) - { - //NzRenderer::SetIndexBuffer(m_billboardIndexBuffer); - NzRenderer::SetMatrix(nzMatrixType_World, NzMatrix4f::Identity()); - NzRenderer::SetShader(m_billboardShader); - NzRenderer::SetVertexBuffer(m_billboardVertexBuffer); - - m_billboardShader->SendVector(s_cameraForwardLocation, camera->GetForward()); - m_billboardShader->SendVector(s_cameraUpLocation, camera->GetUp()); - m_billboardShader->SendVector(s_worldUpLocation, NzVector3f::Up()); - - // Couleur ambiante de la scène - m_billboardShader->SendColor(m_billboardShader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); - // Position de la caméra - m_billboardShader->SendVector(m_billboardShader->GetUniformLocation(nzShaderUniform_CameraPosition), camera->GetPosition()); - - lightCount = 0; - - // On envoie les lumières directionnelles s'il y a (Les mêmes pour tous) - m_renderQueue.lights[0]->Apply(m_billboardShader, 0); - - for (auto& matIt : m_renderQueue.billboards) - { - const NzMaterial* material = matIt.first; - auto& billboards = matIt.second; - - material->Apply(m_billboardShader); - - unsigned int billboardCount = billboards.size(); - const NzForwardRenderQueue::BillboardData* data = &billboards[0]; - while (billboardCount > 0) - { - unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboards); - billboardCount -= renderedBillboardCount; - - m_billboardVertexBuffer->FillVertices(data, 0, renderedBillboardCount, true); - data += renderedBillboardCount; - - NzRenderer::DrawPrimitives(nzPrimitiveMode_PointList, 0, renderedBillboardCount); - } - billboards.clear(); - } - }*/ } unsigned int NzForwardRenderTechnique::GetMaxLightPassPerObject() const From 7e9c5e9a0639b8033a6ddec89a6555e30b26ec29 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 20 Jan 2015 15:05:37 +0100 Subject: [PATCH 206/233] Improved NomalizeAngle function Former-commit-id: 79793b0c57a333e6d2d4a41a14f2b7fdc1d1f093 --- include/Nazara/Math/Algorithm.inl | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/include/Nazara/Math/Algorithm.inl b/include/Nazara/Math/Algorithm.inl index 49b54be32..c85a6ae4f 100644 --- a/include/Nazara/Math/Algorithm.inl +++ b/include/Nazara/Math/Algorithm.inl @@ -210,29 +210,20 @@ T NzNormalizeAngle(T angle) #else const T limit = F(180.0); #endif + const T twoLimit = limit*F(2.0); - ///TODO: Trouver une solution sans duplication - if (angle > F(0.0)) - { - angle += limit; - angle -= static_cast(angle / (F(2.0)*limit)) * (F(2.0)*limit); - angle -= limit; - } - else - { - angle -= limit; - angle -= static_cast(angle / (F(2.0)*limit)) * (F(2.0)*limit); - angle += limit; - } + angle = std::fmod(angle + limit, twoLimit); + if (angle < F(0.0)) + angle += twoLimit; - return angle; + return angle - limit; } template bool NzNumberEquals(T a, T b, T maxDifference) { T diff = a - b; - if (diff < 0) + if (diff < F(0.0)) diff = -diff; return diff <= maxDifference; From ac25c4a041b28aa34a2b35556e8f552011535467 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 20 Jan 2015 15:12:41 +0100 Subject: [PATCH 207/233] (TextSprite) Renamed SetText method to Update Former-commit-id: 798baecaaf919c20d43f036f361d10d459270d0b --- include/Nazara/Graphics/TextSprite.hpp | 3 ++- src/Nazara/Graphics/TextSprite.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/Nazara/Graphics/TextSprite.hpp b/include/Nazara/Graphics/TextSprite.hpp index be8df8b69..40e323d98 100644 --- a/include/Nazara/Graphics/TextSprite.hpp +++ b/include/Nazara/Graphics/TextSprite.hpp @@ -39,7 +39,8 @@ class NAZARA_API NzTextSprite : public NzSceneNode, NzAbstractAtlas::Listener void SetColor(const NzColor& color); void SetDefaultMaterial(); void SetMaterial(NzMaterial* material); - void SetText(const NzAbstractTextDrawer& drawer); + + void Update(const NzAbstractTextDrawer& drawer); NzTextSprite& operator=(const NzTextSprite& text); diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index 622ed0298..80def6d1f 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -126,7 +126,7 @@ void NzTextSprite::SetMaterial(NzMaterial* material) m_material = material; } -void NzTextSprite::SetText(const NzAbstractTextDrawer& drawer) +void NzTextSprite::Update(const NzAbstractTextDrawer& drawer) { ClearAtlases(); From bbfbec1aa3f46dca19b913caced029e25869d5f4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 20 Jan 2015 16:59:50 +0100 Subject: [PATCH 208/233] (ParticleSystem) Moved controllers update to a function Former-commit-id: 47586e675c202d871e3ea3561dc19781bdb264f3 --- include/Nazara/Graphics/ParticleSystem.hpp | 2 + src/Nazara/Graphics/ParticleSystem.cpp | 91 ++++++++++++---------- 2 files changed, 51 insertions(+), 42 deletions(-) diff --git a/include/Nazara/Graphics/ParticleSystem.hpp b/include/Nazara/Graphics/ParticleSystem.hpp index b5fc30c2b..7537da429 100644 --- a/include/Nazara/Graphics/ParticleSystem.hpp +++ b/include/Nazara/Graphics/ParticleSystem.hpp @@ -33,6 +33,8 @@ class NAZARA_API NzParticleSystem : public NzSceneNode, NzUpdatable void AddGenerator(NzParticleGenerator* generator); void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const; + void ApplyControllers(NzParticleMapper& mapper, unsigned int particleCount, float elapsedTime, float& stepAccumulator); + void* CreateParticle(); void* CreateParticles(unsigned int count); diff --git a/src/Nazara/Graphics/ParticleSystem.cpp b/src/Nazara/Graphics/ParticleSystem.cpp index 213fd1fce..b8533109b 100644 --- a/src/Nazara/Graphics/ParticleSystem.cpp +++ b/src/Nazara/Graphics/ParticleSystem.cpp @@ -186,7 +186,7 @@ void NzParticleSystem::KillParticle(unsigned int index) if (m_processing) { - // Le buffer est en train d'être modifié, nous ne pouvons pas réduire sa taille, on place alors la particule dans une liste de secours + // Le buffer est en train d'être modifié, nous ne pouvons pas réduire sa taille, on place alors la particule dans une liste d'attente m_dyingParticles.insert(index); return; } @@ -264,8 +264,53 @@ NzParticleSystem& NzParticleSystem::operator=(const NzParticleSystem& system) return *this; } +void NzParticleSystem::ApplyControllers(NzParticleMapper& mapper, unsigned int particleCount, float elapsedTime, float& stepAccumulator) +{ + m_processing = true; + + // Pour éviter un verrouillage en cas d'exception + NzCallOnExit onExit([this]() + { + m_processing = false; + }); + + if (m_fixedStepEnabled) + { + stepAccumulator += elapsedTime; + while (stepAccumulator >= m_stepSize) + { + for (NzParticleController* controller : m_controllers) + controller->Apply(*this, mapper, 0, particleCount-1, m_stepSize); + + stepAccumulator -= m_stepSize; + } + } + else + { + for (NzParticleController* controller : m_controllers) + controller->Apply(*this, mapper, 0, particleCount-1, elapsedTime); + } + + onExit.CallAndReset(); + + // On tue maintenant les particules mortes durant la mise à jour + if (m_dyingParticles.size() < m_particleCount) + { + // On tue les particules depuis la dernière vers la première (en terme de place), le std::set étant trié via std::greater + // La raison est simple, étant donné que la mort d'une particule signifie le déplacement de la dernière particule du buffer, + // sans cette solution certaines particules pourraient échapper à la mort + for (unsigned int index : m_dyingParticles) + KillParticle(index); + } + else + KillParticles(); // Toutes les particules sont mortes, ceci est beaucoup plus rapide + + m_dyingParticles.clear(); +} + void NzParticleSystem::GenerateAABB() const { + ///TODO: Calculer l'AABB (prendre la taille des particules en compte s'il y a) m_boundingVolume.MakeInfinite(); } @@ -306,48 +351,9 @@ void NzParticleSystem::Update() // Mise à jour if (m_particleCount > 0) { + ///TODO: Mettre à jour en utilisant des threads NzParticleMapper mapper(m_buffer.data(), m_declaration); - - m_processing = true; - - // Pour éviter un verrouillage en cas d'exception - NzCallOnExit onExit([this]() - { - m_processing = false; - }); - - if (m_fixedStepEnabled) - { - m_stepAccumulator += elapsedTime; - while (m_stepAccumulator >= m_stepSize) - { - for (NzParticleController* controller : m_controllers) - controller->Apply(*this, mapper, 0, m_particleCount-1, m_stepAccumulator); - - m_stepAccumulator -= m_stepSize; - } - } - else - { - for (NzParticleController* controller : m_controllers) - controller->Apply(*this, mapper, 0, m_particleCount-1, elapsedTime); - } - - onExit.CallAndReset(); - - // On tue maintenant les particules mortes durant la mise à jour - if (m_dyingParticles.size() < m_particleCount) - { - // On tue les particules depuis la dernière vers la première (en terme de place), le std::set étant trié via std::greater - // La raison est simple, étant donné que la mort d'une particule signifie le déplacement de la dernière particule du buffer, - // sans cette solution certaines particules pourraient échapper à la mort - for (unsigned int index : m_dyingParticles) - KillParticle(index); - } - else - KillParticles(); // Toutes les particules sont mortes, ceci est beaucoup plus rapide - - m_dyingParticles.clear(); + ApplyControllers(mapper, m_particleCount, elapsedTime, m_stepAccumulator); } } @@ -359,6 +365,7 @@ void NzParticleSystem::UpdateBoundingVolume() const if (!m_transformMatrixUpdated) UpdateTransformMatrix(); + ///FIXME: Pourquoi est-ce que le particle system est un node ? Il serait trop coûteux de calculer les particules relativement m_boundingVolume.Update(m_transformMatrix); m_boundingVolumeUpdated = true; } From bce3cadfd5a6396c4c21d975e13060d94accfa17 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 20 Jan 2015 17:48:11 +0100 Subject: [PATCH 209/233] (ParticleEmitter) Added lag compensation Former-commit-id: 914a976ba52b2629190ded068cc23e1cf7dee4d4 --- include/Nazara/Graphics/ParticleEmitter.hpp | 5 +++++ src/Nazara/Graphics/ParticleEmitter.cpp | 25 ++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Graphics/ParticleEmitter.hpp b/include/Nazara/Graphics/ParticleEmitter.hpp index 5e73426d5..6298c196c 100644 --- a/include/Nazara/Graphics/ParticleEmitter.hpp +++ b/include/Nazara/Graphics/ParticleEmitter.hpp @@ -23,9 +23,13 @@ class NAZARA_API NzParticleEmitter : public NzNode virtual void Emit(NzParticleSystem& system, float elapsedTime) const; + void EnableLagCompensation(bool enable); + unsigned int GetEmissionCount() const; float GetEmissionRate() const; + bool IsLagCompensationEnabled() const; + void SetEmissionCount(unsigned int count); void SetEmissionRate(float rate); @@ -35,6 +39,7 @@ class NAZARA_API NzParticleEmitter : public NzNode private: virtual void SetupParticles(NzParticleMapper& mapper, unsigned int count) const = 0; + bool m_lagCompensationEnabled; mutable float m_emissionAccumulator; float m_emissionRate; unsigned int m_emissionCount; diff --git a/src/Nazara/Graphics/ParticleEmitter.cpp b/src/Nazara/Graphics/ParticleEmitter.cpp index 46500f082..33eda8002 100644 --- a/src/Nazara/Graphics/ParticleEmitter.cpp +++ b/src/Nazara/Graphics/ParticleEmitter.cpp @@ -13,6 +13,7 @@ #include NzParticleEmitter::NzParticleEmitter() : +m_lagCompensationEnabled(false), m_emissionAccumulator(0.f), m_emissionRate(0.f), m_emissionCount(1) @@ -34,20 +35,37 @@ void NzParticleEmitter::Emit(NzParticleSystem& system, float elapsedTime) const if (emissionCount >= 1.f) { // On calcule le nombre maximum de particules pouvant être émises cette fois-ci - unsigned int maxParticleCount = static_cast(emissionCount)*m_emissionCount; + unsigned int emissionCountInt = static_cast(emissionCount); + unsigned int maxParticleCount = emissionCountInt*m_emissionCount; // On récupère le nombre de particules qu'il est possible de créer selon l'espace libre unsigned int particleCount = std::min(maxParticleCount, system.GetMaxParticleCount() - system.GetParticleCount()); + if (particleCount == 0) + return; // Et on émet nos particules void* particles = system.GenerateParticles(particleCount); NzParticleMapper mapper(particles, system.GetDeclaration()); SetupParticles(mapper, particleCount); + + if (m_lagCompensationEnabled) + { + // On va maintenant appliquer les contrôleurs + float accumulator = 0.f; + float invEmissionRate = 1.f/m_emissionRate; + for (unsigned int i = 1; i <= emissionCountInt; ++i) + system.ApplyControllers(mapper, std::min(m_emissionCount*i, particleCount), 20*invEmissionRate, accumulator); + } } } } +void NzParticleEmitter::EnableLagCompensation(bool enable) +{ + m_lagCompensationEnabled = enable; +} + unsigned int NzParticleEmitter::GetEmissionCount() const { return m_emissionCount; @@ -58,6 +76,11 @@ float NzParticleEmitter::GetEmissionRate() const return m_emissionRate; } +bool NzParticleEmitter::IsLagCompensationEnabled() const +{ + return m_lagCompensationEnabled; +} + void NzParticleEmitter::SetEmissionCount(unsigned int count) { m_emissionCount = count; From 8a3c410d605554444d83d5643d117c4dd97e3308 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 20 Jan 2015 20:35:16 +0100 Subject: [PATCH 210/233] Made bounding volume handing part of SceneNodes Former-commit-id: d09d06ac4515ce09aa16fd92dd045c2a06730a99 --- examples/FirstScene/main.cpp | 5 ++ include/Nazara/Graphics/Camera.hpp | 2 +- include/Nazara/Graphics/Light.hpp | 5 +- include/Nazara/Graphics/Model.hpp | 6 +- include/Nazara/Graphics/ParticleSystem.hpp | 6 +- include/Nazara/Graphics/SceneNode.hpp | 11 ++- include/Nazara/Graphics/SceneRoot.hpp | 2 +- include/Nazara/Graphics/SkeletalModel.hpp | 2 +- include/Nazara/Graphics/Sprite.hpp | 5 +- include/Nazara/Graphics/TextSprite.hpp | 5 +- include/Nazara/Graphics/View.hpp | 2 +- src/Nazara/Graphics/Light.cpp | 93 +++++++++------------- src/Nazara/Graphics/Model.cpp | 40 +--------- src/Nazara/Graphics/ParticleSystem.cpp | 28 +------ src/Nazara/Graphics/SceneNode.cpp | 29 +++++++ src/Nazara/Graphics/SceneRoot.cpp | 11 ++- src/Nazara/Graphics/SkeletalModel.cpp | 17 ++-- src/Nazara/Graphics/Sprite.cpp | 37 ++------- src/Nazara/Graphics/TextSprite.cpp | 50 ++++-------- 19 files changed, 127 insertions(+), 229 deletions(-) diff --git a/examples/FirstScene/main.cpp b/examples/FirstScene/main.cpp index 62a4425c8..45395cec9 100644 --- a/examples/FirstScene/main.cpp +++ b/examples/FirstScene/main.cpp @@ -225,6 +225,11 @@ int main() bool smoothMovement = true; NzVector3f targetPos = camera.GetPosition(); + NzTextSprite text; + text.SetParent(scene); + text.Update(NzSimpleTextDrawer::Draw("Hello world !", 72)); + text.Scale(0.1f); + // Début de la boucle de rendu du programme while (window.IsOpen()) { diff --git a/include/Nazara/Graphics/Camera.hpp b/include/Nazara/Graphics/Camera.hpp index 3cdb0eb41..e9b64d632 100644 --- a/include/Nazara/Graphics/Camera.hpp +++ b/include/Nazara/Graphics/Camera.hpp @@ -9,12 +9,12 @@ #include #include -#include #include #include #include #include #include +#include class NAZARA_API NzCamera : public NzAbstractViewer, public NzNode, NzRenderTarget::Listener { diff --git a/include/Nazara/Graphics/Light.hpp b/include/Nazara/Graphics/Light.hpp index 4a53eed94..9db57e7c6 100644 --- a/include/Nazara/Graphics/Light.hpp +++ b/include/Nazara/Graphics/Light.hpp @@ -28,7 +28,6 @@ class NAZARA_API NzLight : public NzSceneNode float GetAmbientFactor() const; float GetAttenuation() const; - const NzBoundingVolumef& GetBoundingVolume() const; NzColor GetColor() const; float GetDiffuseFactor() const; float GetInnerAngle() const; @@ -54,15 +53,13 @@ class NAZARA_API NzLight : public NzSceneNode private: bool FrustumCull(const NzFrustumf& frustum) const override; - void InvalidateNode() override; + void MakeBoundingVolume() const override; void Register() override; void Unregister() override; void UpdateBoundingVolume() const; nzLightType m_type; - mutable NzBoundingVolumef m_boundingVolume; NzColor m_color; - mutable bool m_boundingVolumeUpdated; float m_ambientFactor; float m_attenuation; float m_diffuseFactor; diff --git a/include/Nazara/Graphics/Model.hpp b/include/Nazara/Graphics/Model.hpp index 3249cdd48..5b193f5ee 100644 --- a/include/Nazara/Graphics/Model.hpp +++ b/include/Nazara/Graphics/Model.hpp @@ -44,7 +44,6 @@ class NAZARA_API NzModel : public NzSceneNode void EnableAnimation(bool animation); NzAnimation* GetAnimation() const; - const NzBoundingVolumef& GetBoundingVolume() const; NzMaterial* GetMaterial(const NzString& subMeshName) const; NzMaterial* GetMaterial(unsigned int matIndex) const; NzMaterial* GetMaterial(unsigned int skinIndex, const NzString& subMeshName) const; @@ -84,13 +83,10 @@ class NAZARA_API NzModel : public NzSceneNode NzModel& operator=(const NzModel& node); protected: - void InvalidateNode() override; - virtual void UpdateBoundingVolume() const; + void MakeBoundingVolume() const override; std::vector m_materials; - mutable NzBoundingVolumef m_boundingVolume; NzMeshRef m_mesh; - mutable bool m_boundingVolumeUpdated; unsigned int m_matCount; unsigned int m_skin; unsigned int m_skinCount; diff --git a/include/Nazara/Graphics/ParticleSystem.hpp b/include/Nazara/Graphics/ParticleSystem.hpp index 7537da429..b62fa368e 100644 --- a/include/Nazara/Graphics/ParticleSystem.hpp +++ b/include/Nazara/Graphics/ParticleSystem.hpp @@ -43,7 +43,6 @@ class NAZARA_API NzParticleSystem : public NzSceneNode, NzUpdatable void* GenerateParticle(); void* GenerateParticles(unsigned int count); - const NzBoundingVolumef& GetBoundingVolume() const override; const NzParticleDeclaration* GetDeclaration() const; float GetFixedStepSize() const; unsigned int GetMaxParticleCount() const; @@ -67,22 +66,19 @@ class NAZARA_API NzParticleSystem : public NzSceneNode, NzUpdatable NzParticleSystem& operator=(const NzParticleSystem& emitter); private: - void GenerateAABB() const; + void MakeBoundingVolume() const override; void Register() override; void ResizeBuffer(); void Unregister() override; void Update() override; - void UpdateBoundingVolume() const; std::set> m_dyingParticles; mutable std::vector m_buffer; std::vector m_controllers; std::vector m_emitters; std::vector m_generators; - mutable NzBoundingVolumef m_boundingVolume; NzParticleDeclarationConstRef m_declaration; NzParticleRendererRef m_renderer; - mutable bool m_boundingVolumeUpdated; bool m_fixedStepEnabled; bool m_processing; float m_stepAccumulator; diff --git a/include/Nazara/Graphics/SceneNode.hpp b/include/Nazara/Graphics/SceneNode.hpp index edfdf56e2..3cbfde9e9 100644 --- a/include/Nazara/Graphics/SceneNode.hpp +++ b/include/Nazara/Graphics/SceneNode.hpp @@ -14,6 +14,8 @@ #include #include +class NzScene; + class NAZARA_API NzSceneNode : public NzNode { friend class NzScene; @@ -29,7 +31,7 @@ class NAZARA_API NzSceneNode : public NzNode void EnableDrawing(bool drawingEnabled); NzVector3f GetBackward() const; - virtual const NzBoundingVolumef& GetBoundingVolume() const = 0; + virtual const NzBoundingVolumef& GetBoundingVolume() const; NzVector3f GetDown() const; NzVector3f GetForward() const; NzVector3f GetLeft() const; @@ -39,6 +41,8 @@ class NAZARA_API NzSceneNode : public NzNode virtual nzSceneNodeType GetSceneNodeType() const = 0; NzVector3f GetUp() const; + void InvalidateAABB(); + virtual bool IsDrawable() const = 0; bool IsDrawingEnabled() const; bool IsVisible() const; @@ -48,6 +52,8 @@ class NAZARA_API NzSceneNode : public NzNode protected: virtual bool FrustumCull(const NzFrustumf& frustum) const; + virtual void InvalidateNode() override; + virtual void MakeBoundingVolume() const = 0; virtual void OnParenting(const NzNode* parent) override; virtual void OnVisibilityChange(bool visibility); void RecursiveSetScene(NzScene* scene, NzNode* node); @@ -55,8 +61,11 @@ class NAZARA_API NzSceneNode : public NzNode void SetScene(NzScene* scene); virtual void Unregister(); virtual void Update(); + virtual void UpdateBoundingVolume() const; + mutable NzBoundingVolumef m_boundingVolume; NzScene* m_scene; + mutable bool m_boundingVolumeUpdated; bool m_drawingEnabled; bool m_visible; diff --git a/include/Nazara/Graphics/SceneRoot.hpp b/include/Nazara/Graphics/SceneRoot.hpp index 7b81fd5ac..9e09281ac 100644 --- a/include/Nazara/Graphics/SceneRoot.hpp +++ b/include/Nazara/Graphics/SceneRoot.hpp @@ -17,7 +17,6 @@ class NAZARA_API NzSceneRoot : public NzSceneNode public: void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; - const NzBoundingVolumef& GetBoundingVolume() const override; nzSceneNodeType GetSceneNodeType() const override; bool IsDrawable() const; @@ -26,6 +25,7 @@ class NAZARA_API NzSceneRoot : public NzSceneNode NzSceneRoot(NzScene* scene); virtual ~NzSceneRoot(); + void MakeBoundingVolume() const override; void Register(); void Unregister(); }; diff --git a/include/Nazara/Graphics/SkeletalModel.hpp b/include/Nazara/Graphics/SkeletalModel.hpp index 7938ba4c4..84c8e0f88 100644 --- a/include/Nazara/Graphics/SkeletalModel.hpp +++ b/include/Nazara/Graphics/SkeletalModel.hpp @@ -69,10 +69,10 @@ class NAZARA_API NzSkeletalModel : public NzModel, NzUpdatable NzSkeletalModel& operator=(NzSkeletalModel&& node); private: + void MakeBoundingVolume() const override; void Register() override; void Unregister() override; void Update() override; - void UpdateBoundingVolume() const; NzAnimationRef m_animation; NzSkeleton m_skeleton; diff --git a/include/Nazara/Graphics/Sprite.hpp b/include/Nazara/Graphics/Sprite.hpp index b3739cb07..69c51fa90 100644 --- a/include/Nazara/Graphics/Sprite.hpp +++ b/include/Nazara/Graphics/Sprite.hpp @@ -22,7 +22,6 @@ class NAZARA_API NzSprite : public NzSceneNode void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; - const NzBoundingVolumef& GetBoundingVolume() const override; const NzColor& GetColor() const; NzMaterial* GetMaterial() const; nzSceneNodeType GetSceneNodeType() const override; @@ -44,18 +43,16 @@ class NAZARA_API NzSprite : public NzSceneNode private: void InvalidateNode() override; + void MakeBoundingVolume() const override; void Register() override; void Unregister() override; - void UpdateBoundingVolume() const; void UpdateVertices() const; - mutable NzBoundingVolumef m_boundingVolume; NzColor m_color; NzMaterialRef m_material; NzRectf m_textureCoords; NzVector2f m_size; mutable NzVertexStruct_XYZ_Color_UV m_vertices[4]; - mutable bool m_boundingVolumeUpdated; mutable bool m_verticesUpdated; }; diff --git a/include/Nazara/Graphics/TextSprite.hpp b/include/Nazara/Graphics/TextSprite.hpp index 40e323d98..23ce1a7f3 100644 --- a/include/Nazara/Graphics/TextSprite.hpp +++ b/include/Nazara/Graphics/TextSprite.hpp @@ -28,7 +28,6 @@ class NAZARA_API NzTextSprite : public NzSceneNode, NzAbstractAtlas::Listener void Clear(); - const NzBoundingVolumef& GetBoundingVolume() const override; const NzColor& GetColor() const; NzMaterial* GetMaterial() const; nzSceneNodeType GetSceneNodeType() const override; @@ -47,12 +46,12 @@ class NAZARA_API NzTextSprite : public NzSceneNode, NzAbstractAtlas::Listener private: void ClearAtlases(); void InvalidateNode() override; + void MakeBoundingVolume() const override; bool OnAtlasCleared(const NzAbstractAtlas* atlas, void* userdata) override; bool OnAtlasLayerChange(const NzAbstractAtlas* atlas, NzAbstractImage* oldLayer, NzAbstractImage* newLayer, void* userdata) override; void OnAtlasReleased(const NzAbstractAtlas* atlas, void* userdata) override; void Register() override; void Unregister() override; - void UpdateBoundingVolume() const; void UpdateVertices() const; struct RenderIndices @@ -65,11 +64,9 @@ class NAZARA_API NzTextSprite : public NzSceneNode, NzAbstractAtlas::Listener mutable std::unordered_map m_renderInfos; mutable std::vector m_localVertices; mutable std::vector m_vertices; - mutable NzBoundingVolumef m_boundingVolume; NzColor m_color; NzMaterialRef m_material; NzRectui m_localBounds; - mutable bool m_boundingVolumeUpdated; mutable bool m_verticesUpdated; }; diff --git a/include/Nazara/Graphics/View.hpp b/include/Nazara/Graphics/View.hpp index b7f016afc..740bde621 100644 --- a/include/Nazara/Graphics/View.hpp +++ b/include/Nazara/Graphics/View.hpp @@ -9,12 +9,12 @@ #include #include -#include #include #include #include #include #include +#include class NAZARA_API NzView : public NzAbstractViewer, public NzNode, NzRenderTarget::Listener { diff --git a/src/Nazara/Graphics/Light.cpp b/src/Nazara/Graphics/Light.cpp index e3288adc2..73df7e784 100644 --- a/src/Nazara/Graphics/Light.cpp +++ b/src/Nazara/Graphics/Light.cpp @@ -14,11 +14,11 @@ #include ///TODO: Utilisation des UBOs +///TODO: Scale ? NzLight::NzLight(nzLightType type) : m_type(type), m_color(NzColor::White), -m_boundingVolumeUpdated(false), m_ambientFactor((type == nzLightType_Directional) ? 0.2f : 0.f), m_attenuation(0.9f), m_diffuseFactor(1.f), @@ -31,9 +31,7 @@ m_radius(5.f) NzLight::NzLight(const NzLight& light) : NzSceneNode(light), m_type(light.m_type), -m_boundingVolume(light.m_boundingVolume), m_color(light.m_color), -m_boundingVolumeUpdated(light.m_boundingVolumeUpdated), m_ambientFactor(light.m_ambientFactor), m_attenuation(light.m_attenuation), m_diffuseFactor(light.m_diffuseFactor), @@ -112,14 +110,6 @@ float NzLight::GetAttenuation() const return m_attenuation; } -const NzBoundingVolumef& NzLight::GetBoundingVolume() const -{ - if (!m_boundingVolumeUpdated) - UpdateBoundingVolume(); - - return m_boundingVolume; -} - NzColor NzLight::GetColor() const { return m_color; @@ -251,11 +241,45 @@ bool NzLight::FrustumCull(const NzFrustumf& frustum) const return false; } -void NzLight::InvalidateNode() +void NzLight::MakeBoundingVolume() const { - NzSceneNode::InvalidateNode(); + switch (m_type) + { + case nzLightType_Directional: + m_boundingVolume.MakeInfinite(); + break; - m_boundingVolumeUpdated = false; + case nzLightType_Point: + { + NzVector3f radius(m_radius); + m_boundingVolume.Set(-radius, radius); + break; + } + + case nzLightType_Spot: + { + // On forme une boite sur l'origine + NzBoxf box(NzVector3f::Zero()); + + // On calcule le reste des points + NzVector3f base(NzVector3f::Forward()*m_radius); + + // Il nous faut maintenant le rayon du cercle projeté à cette distance + // Tangente = Opposé/Adjaçent <=> Opposé = Adjaçent*Tangente + float radius = m_radius*std::tan(NzDegreeToRadian(m_outerAngle)); + NzVector3f lExtend = NzVector3f::Left()*radius; + NzVector3f uExtend = NzVector3f::Up()*radius; + + // Et on ajoute ensuite les quatres extrémités de la pyramide + box.ExtendTo(base + lExtend + uExtend); + box.ExtendTo(base + lExtend - uExtend); + box.ExtendTo(base - lExtend + uExtend); + box.ExtendTo(base - lExtend - uExtend); + + m_boundingVolume.Set(box); + break; + } + } } void NzLight::Register() @@ -269,46 +293,7 @@ void NzLight::Unregister() void NzLight::UpdateBoundingVolume() const { if (m_boundingVolume.IsNull()) - { - switch (m_type) - { - case nzLightType_Directional: - m_boundingVolume.MakeInfinite(); - m_boundingVolumeUpdated = true; - return; // Rien d'autre à faire - - case nzLightType_Point: - { - NzVector3f radius(m_radius); - m_boundingVolume.Set(-radius, radius); - break; - } - - case nzLightType_Spot: - { - // On forme une boite sur l'origine - NzBoxf box(NzVector3f::Zero()); - - // On calcule le reste des points - NzVector3f base(NzVector3f::Forward()*m_radius); - - // Il nous faut maintenant le rayon du cercle projeté à cette distance - // Tangente = Opposé/Adjaçent <=> Opposé = Adjaçent*Tangente - float radius = m_radius*std::tan(NzDegreeToRadian(m_outerAngle)); - NzVector3f lExtend = NzVector3f::Left()*radius; - NzVector3f uExtend = NzVector3f::Up()*radius; - - // Et on ajoute ensuite les quatres extrémités de la pyramide - box.ExtendTo(base + lExtend + uExtend); - box.ExtendTo(base + lExtend - uExtend); - box.ExtendTo(base - lExtend + uExtend); - box.ExtendTo(base - lExtend - uExtend); - - m_boundingVolume.Set(box); - break; - } - } - } + MakeBoundingVolume(); switch (m_type) { diff --git a/src/Nazara/Graphics/Model.cpp b/src/Nazara/Graphics/Model.cpp index cf32336b8..6bddc09cc 100644 --- a/src/Nazara/Graphics/Model.cpp +++ b/src/Nazara/Graphics/Model.cpp @@ -25,7 +25,6 @@ bool NzModelParameters::IsValid() const } NzModel::NzModel() : -m_boundingVolumeUpdated(true), m_matCount(0), m_skin(0), m_skinCount(1) @@ -35,9 +34,7 @@ m_skinCount(1) NzModel::NzModel(const NzModel& model) : NzSceneNode(model), m_materials(model.m_materials), -m_boundingVolume(model.m_boundingVolume), m_mesh(model.m_mesh), -m_boundingVolumeUpdated(model.m_boundingVolumeUpdated), m_matCount(model.m_matCount), m_skin(model.m_skin), m_skinCount(model.m_skinCount) @@ -69,24 +66,6 @@ void NzModel::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const } } -const NzBoundingVolumef& NzModel::GetBoundingVolume() const -{ - #if NAZARA_GRAPHICS_SAFE - if (!m_mesh) - { - NazaraError("Model has no mesh"); - - static NzBoundingVolumef dummy(nzExtend_Null); - return dummy; - } - #endif - - if (!m_boundingVolumeUpdated) - UpdateBoundingVolume(); - - return m_boundingVolume; -} - NzMaterial* NzModel::GetMaterial(const NzString& subMeshName) const { #if NAZARA_GRAPHICS_SAFE @@ -414,23 +393,12 @@ NzModel& NzModel::operator=(const NzModel& node) return *this; } -void NzModel::InvalidateNode() +void NzModel::MakeBoundingVolume() const { - NzSceneNode::InvalidateNode(); - - m_boundingVolumeUpdated = false; -} - -void NzModel::UpdateBoundingVolume() const -{ - if (m_boundingVolume.IsNull()) + if (m_mesh) m_boundingVolume.Set(m_mesh->GetAABB()); - - if (!m_transformMatrixUpdated) - UpdateTransformMatrix(); - - m_boundingVolume.Update(m_transformMatrix); - m_boundingVolumeUpdated = true; + else + m_boundingVolume.MakeNull(); } NzModelLoader::LoaderList NzModel::s_loaders; diff --git a/src/Nazara/Graphics/ParticleSystem.cpp b/src/Nazara/Graphics/ParticleSystem.cpp index b8533109b..1ded1113b 100644 --- a/src/Nazara/Graphics/ParticleSystem.cpp +++ b/src/Nazara/Graphics/ParticleSystem.cpp @@ -18,7 +18,6 @@ NzParticleSystem(maxParticleCount, NzParticleDeclaration::Get(layout)) NzParticleSystem::NzParticleSystem(unsigned int maxParticleCount, const NzParticleDeclaration* declaration) : m_declaration(declaration), -m_boundingVolumeUpdated(false), m_fixedStepEnabled(false), m_processing(false), m_stepAccumulator(0.f), @@ -38,10 +37,8 @@ NzParticleSystem::NzParticleSystem(const NzParticleSystem& system) : NzSceneNode(system), m_controllers(system.m_controllers), m_generators(system.m_generators), -m_boundingVolume(system.m_boundingVolume), m_declaration(system.m_declaration), m_renderer(system.m_renderer), -m_boundingVolumeUpdated(system.m_boundingVolumeUpdated), m_fixedStepEnabled(system.m_fixedStepEnabled), m_processing(false), m_stepAccumulator(0.f), @@ -132,14 +129,6 @@ void* NzParticleSystem::GenerateParticles(unsigned int count) return ptr; } -const NzBoundingVolumef& NzParticleSystem::GetBoundingVolume() const -{ - if (!m_boundingVolumeUpdated) - UpdateBoundingVolume(); - - return m_boundingVolume; -} - const NzParticleDeclaration* NzParticleSystem::GetDeclaration() const { return m_declaration; @@ -238,8 +227,6 @@ NzParticleSystem& NzParticleSystem::operator=(const NzParticleSystem& system) NzSceneNode::operator=(system); - m_boundingVolume = system.m_boundingVolume; - m_boundingVolumeUpdated = system.m_boundingVolumeUpdated; m_controllers = system.m_controllers; m_declaration = system.m_declaration; m_fixedStepEnabled = system.m_fixedStepEnabled; @@ -308,7 +295,7 @@ void NzParticleSystem::ApplyControllers(NzParticleMapper& mapper, unsigned int p m_dyingParticles.clear(); } -void NzParticleSystem::GenerateAABB() const +void NzParticleSystem::MakeBoundingVolume() const { ///TODO: Calculer l'AABB (prendre la taille des particules en compte s'il y a) m_boundingVolume.MakeInfinite(); @@ -356,16 +343,3 @@ void NzParticleSystem::Update() ApplyControllers(mapper, m_particleCount, elapsedTime, m_stepAccumulator); } } - -void NzParticleSystem::UpdateBoundingVolume() const -{ - if (m_boundingVolume.IsNull()) - GenerateAABB(); - - if (!m_transformMatrixUpdated) - UpdateTransformMatrix(); - - ///FIXME: Pourquoi est-ce que le particle system est un node ? Il serait trop coûteux de calculer les particules relativement - m_boundingVolume.Update(m_transformMatrix); - m_boundingVolumeUpdated = true; -} diff --git a/src/Nazara/Graphics/SceneNode.cpp b/src/Nazara/Graphics/SceneNode.cpp index d5ae7da72..29a343531 100644 --- a/src/Nazara/Graphics/SceneNode.cpp +++ b/src/Nazara/Graphics/SceneNode.cpp @@ -11,6 +11,7 @@ NzSceneNode::NzSceneNode() : m_scene(nullptr), +m_boundingVolumeUpdated(false), m_drawingEnabled(true), m_visible(false) { @@ -19,6 +20,7 @@ m_visible(false) NzSceneNode::NzSceneNode(const NzSceneNode& sceneNode) : NzNode(sceneNode), m_scene(nullptr), +m_boundingVolumeUpdated(false), m_drawingEnabled(sceneNode.m_drawingEnabled), m_visible(false) { @@ -44,6 +46,14 @@ NzVector3f NzSceneNode::GetBackward() const return NzNode::GetBackward(); } +const NzBoundingVolumef& NzSceneNode::GetBoundingVolume() const +{ + if (!m_boundingVolumeUpdated) + UpdateBoundingVolume(); + + return m_boundingVolume; +} + NzVector3f NzSceneNode::GetDown() const { if (m_scene) @@ -145,6 +155,13 @@ bool NzSceneNode::FrustumCull(const NzFrustumf& frustum) const return frustum.Contains(GetBoundingVolume()); } +void NzSceneNode::InvalidateNode() +{ + NzNode::InvalidateNode(); + + m_boundingVolumeUpdated = false; +} + void NzSceneNode::OnParenting(const NzNode* parent) { if (parent) @@ -207,6 +224,18 @@ void NzSceneNode::Update() { } +void NzSceneNode::UpdateBoundingVolume() const +{ + if (m_boundingVolume.IsNull()) + MakeBoundingVolume(); + + if (!m_transformMatrixUpdated) + UpdateTransformMatrix(); + + m_boundingVolume.Update(m_transformMatrix); + m_boundingVolumeUpdated = true; +} + void NzSceneNode::UpdateVisibility(const NzFrustumf& frustum) { bool wasVisible = m_visible; diff --git a/src/Nazara/Graphics/SceneRoot.cpp b/src/Nazara/Graphics/SceneRoot.cpp index 46e446eaa..5bb63f624 100644 --- a/src/Nazara/Graphics/SceneRoot.cpp +++ b/src/Nazara/Graphics/SceneRoot.cpp @@ -20,12 +20,6 @@ void NzSceneRoot::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const NazaraInternalError("SceneNode::AddToRenderQueue() called on SceneRoot"); } -const NzBoundingVolumef& NzSceneRoot::GetBoundingVolume() const -{ - static NzBoundingVolumef infinite(nzExtend_Infinite); - return infinite; -} - nzSceneNodeType NzSceneRoot::GetSceneNodeType() const { return nzSceneNodeType_Root; @@ -36,6 +30,11 @@ bool NzSceneRoot::IsDrawable() const return true; } +void NzSceneRoot::MakeBoundingVolume() const +{ + m_boundingVolume.MakeInfinite(); +} + void NzSceneRoot::Register() { NazaraInternalError("SceneNode::Register() called on SceneRoot"); diff --git a/src/Nazara/Graphics/SkeletalModel.cpp b/src/Nazara/Graphics/SkeletalModel.cpp index b7fe39f98..16b01f01f 100644 --- a/src/Nazara/Graphics/SkeletalModel.cpp +++ b/src/Nazara/Graphics/SkeletalModel.cpp @@ -325,6 +325,11 @@ NzSkeletalModel& NzSkeletalModel::operator=(NzSkeletalModel&& node) return *this; } +void NzSkeletalModel::MakeBoundingVolume() const +{ + m_boundingVolume.Set(m_skeleton.GetAABB()); +} + void NzSkeletalModel::Register() { if (m_animation) @@ -342,16 +347,4 @@ void NzSkeletalModel::Update() AdvanceAnimation(m_scene->GetUpdateTime()); } -void NzSkeletalModel::UpdateBoundingVolume() const -{ - if (m_boundingVolume.IsNull()) - m_boundingVolume.Set(m_skeleton.GetAABB()); - - if (!m_transformMatrixUpdated) - UpdateTransformMatrix(); - - m_boundingVolume.Update(m_transformMatrix); - m_boundingVolumeUpdated = true; -} - NzSkeletalModelLoader::LoaderList NzSkeletalModel::s_loaders; diff --git a/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index 983929d53..d660adc23 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -9,22 +9,18 @@ #include NzSprite::NzSprite() : -m_boundingVolume(NzBoundingVolumef::Null()), m_color(NzColor::White), m_textureCoords(0.f, 0.f, 1.f, 1.f), m_size(64.f, 64.f), -m_boundingVolumeUpdated(true), m_verticesUpdated(false) { SetDefaultMaterial(); } NzSprite::NzSprite(NzTexture* texture) : -m_boundingVolume(NzBoundingVolumef::Null()), m_color(NzColor::White), m_textureCoords(0.f, 0.f, 1.f, 1.f), m_size(64.f, 64.f), -m_boundingVolumeUpdated(false), m_verticesUpdated(false) { SetTexture(texture, true); @@ -32,13 +28,11 @@ m_verticesUpdated(false) NzSprite::NzSprite(const NzSprite& sprite) : NzSceneNode(sprite), -m_boundingVolume(sprite.m_boundingVolume), m_color(sprite.m_color), m_material(sprite.m_material), m_textureCoords(sprite.m_textureCoords), m_size(sprite.m_size), m_vertices(sprite.m_vertices), -m_boundingVolumeUpdated(sprite.m_boundingVolumeUpdated), m_verticesUpdated(sprite.m_verticesUpdated) { SetParent(sprite.GetParent()); @@ -52,14 +46,6 @@ void NzSprite::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const renderQueue->AddSprites(m_material, m_vertices, 1); } -const NzBoundingVolumef& NzSprite::GetBoundingVolume() const -{ - if (!m_boundingVolumeUpdated) - UpdateBoundingVolume(); - - return m_boundingVolume; -} - const NzColor& NzSprite::GetColor() const { return m_color; @@ -189,7 +175,6 @@ NzSprite& NzSprite::operator=(const NzSprite& sprite) m_size = sprite.m_size; // On ne copie pas les sommets finaux car il est très probable que nos paramètres soient modifiés et qu'ils doivent être régénérés de toute façon - m_boundingVolumeUpdated = false; m_verticesUpdated = false; return *this; @@ -199,7 +184,6 @@ void NzSprite::InvalidateNode() { NzSceneNode::InvalidateNode(); - m_boundingVolumeUpdated = false; m_verticesUpdated = false; } @@ -213,21 +197,12 @@ void NzSprite::Unregister() { } -void NzSprite::UpdateBoundingVolume() const +void NzSprite::MakeBoundingVolume() const { - if (m_boundingVolume.IsNull()) - { - NzVector3f down = m_scene->GetDown(); - NzVector3f right = m_scene->GetRight(); + NzVector3f down = (m_scene) ? m_scene->GetDown() : NzVector3f::Down(); + NzVector3f right = (m_scene) ? m_scene->GetRight() : NzVector3f::Right(); - m_boundingVolume.Set(NzVector3f(0.f), m_size.x*right + m_size.y*down); - } - - if (!m_transformMatrixUpdated) - UpdateTransformMatrix(); - - m_boundingVolume.Update(m_transformMatrix); - m_boundingVolumeUpdated = true; + m_boundingVolume.Set(NzVector3f(0.f), m_size.x*right + m_size.y*down); } void NzSprite::UpdateVertices() const @@ -235,8 +210,8 @@ void NzSprite::UpdateVertices() const if (!m_transformMatrixUpdated) UpdateTransformMatrix(); - NzVector3f down = m_scene->GetDown(); - NzVector3f right = m_scene->GetRight(); + NzVector3f down = (m_scene) ? m_scene->GetDown() : NzVector3f::Down(); + NzVector3f right = (m_scene) ? m_scene->GetRight() : NzVector3f::Right(); m_vertices[0].color = m_color; m_vertices[0].position = m_transformMatrix.Transform(NzVector3f(0.f)); diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index 80def6d1f..ac3b67a35 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -11,7 +11,6 @@ #include NzTextSprite::NzTextSprite() : -m_boundingVolume(NzBoundingVolumef::Null()), m_color(NzColor::White), m_verticesUpdated(false) { @@ -24,11 +23,9 @@ m_atlases(sprite.m_atlases), m_renderInfos(sprite.m_renderInfos), m_localVertices(sprite.m_localVertices), m_vertices(sprite.m_vertices), -m_boundingVolume(sprite.m_boundingVolume), m_color(sprite.m_color), m_material(sprite.m_material), m_localBounds(sprite.m_localBounds), -m_boundingVolumeUpdated(sprite.m_boundingVolumeUpdated), m_verticesUpdated(sprite.m_verticesUpdated) { SetParent(sprite.GetParent()); @@ -66,14 +63,6 @@ void NzTextSprite::Clear() m_vertices.clear(); } -const NzBoundingVolumef& NzTextSprite::GetBoundingVolume() const -{ - if (!m_boundingVolumeUpdated) - UpdateBoundingVolume(); - - return m_boundingVolume; -} - const NzColor& NzTextSprite::GetColor() const { return m_color; @@ -266,7 +255,6 @@ NzTextSprite& NzTextSprite::operator=(const NzTextSprite& text) m_localVertices = text.m_localVertices; // On ne copie pas les sommets finaux car il est très probable que nos paramètres soient modifiés et qu'ils doivent être régénérés de toute façon - m_boundingVolumeUpdated = false; m_verticesUpdated = false; return *this; @@ -284,10 +272,21 @@ void NzTextSprite::InvalidateNode() { NzSceneNode::InvalidateNode(); - m_boundingVolumeUpdated = false; m_verticesUpdated = false; } +void NzTextSprite::MakeBoundingVolume() const +{ + NzVector3f down = (m_scene) ? m_scene->GetDown() : NzVector3f::Down(); + NzVector3f right = (m_scene) ? m_scene->GetRight() : NzVector3f::Right(); + + NzRectf bounds(m_localBounds); + NzVector2f max = bounds.GetMaximum(); + NzVector2f min = bounds.GetMinimum(); + + m_boundingVolume.Set(min.x*right + min.y*down, max.x*right + max.y*down); +} + bool NzTextSprite::OnAtlasCleared(const NzAbstractAtlas* atlas, void* userdata) { NazaraUnused(userdata); @@ -373,34 +372,13 @@ void NzTextSprite::Unregister() { } -void NzTextSprite::UpdateBoundingVolume() const -{ - if (m_boundingVolume.IsNull()) - { - NzVector3f down = m_scene->GetDown(); - NzVector3f right = m_scene->GetRight(); - - NzRectf bounds(m_localBounds); - NzVector2f max = bounds.GetMaximum(); - NzVector2f min = bounds.GetMinimum(); - - m_boundingVolume.Set(min.x*right + min.y*down, max.x*right + max.y*down); - } - - if (!m_transformMatrixUpdated) - UpdateTransformMatrix(); - - m_boundingVolume.Update(m_transformMatrix); - m_boundingVolumeUpdated = true; -} - void NzTextSprite::UpdateVertices() const { if (!m_transformMatrixUpdated) UpdateTransformMatrix(); - NzVector3f down = m_scene->GetDown(); - NzVector3f right = m_scene->GetRight(); + NzVector3f down = (m_scene) ? m_scene->GetDown() : NzVector3f::Down(); + NzVector3f right = (m_scene) ? m_scene->GetRight() : NzVector3f::Right(); NzSparsePtr colorPtr(&m_vertices[0].color, sizeof(NzVertexStruct_XYZ_Color_UV)); NzSparsePtr posPtr(&m_vertices[0].position, sizeof(NzVertexStruct_XYZ_Color_UV)); From 3933b0709497adec13f8b39a42cf82ca8a8d19f5 Mon Sep 17 00:00:00 2001 From: Gawaboumga Date: Wed, 21 Jan 2015 13:51:49 +0100 Subject: [PATCH 211/233] Suppression of warnings OffsetOf: use of static_cast Updatable: API and virtual destructor Drawable: virtual destructor Vector: std::abs should be "the" abs. AbstractClass: API +Updatable: Like for others abstracts Buffer: nullptr for pointer to function. Image: wasn't returning a vector. Former-commit-id: 57e0009286a02b9e3b0b81945e500d7d9e466ae2 --- include/Nazara/Core/OffsetOf.hpp | 2 +- include/Nazara/Core/Updatable.hpp | 5 ++++- include/Nazara/Graphics/Drawable.hpp | 2 +- include/Nazara/Math/Vector2.inl | 14 +------------- include/Nazara/Math/Vector3.inl | 14 +------------- include/Nazara/Math/Vector4.inl | 14 +------------- include/Nazara/Utility/AbstractAtlas.hpp | 2 +- src/Nazara/Core/Updatable.cpp | 8 ++++++++ src/Nazara/Utility/Buffer.cpp | 2 +- src/Nazara/Utility/Image.cpp | 2 +- 10 files changed, 20 insertions(+), 45 deletions(-) create mode 100644 src/Nazara/Core/Updatable.cpp diff --git a/include/Nazara/Core/OffsetOf.hpp b/include/Nazara/Core/OffsetOf.hpp index 0393f7fc7..be3d7d79f 100644 --- a/include/Nazara/Core/OffsetOf.hpp +++ b/include/Nazara/Core/OffsetOf.hpp @@ -16,7 +16,7 @@ template M NzImplGetMemberType(M T::*); template constexpr std::size_t NzImplOffsetOf() { - return reinterpret_cast(&(((T*)0)->*M)); + return reinterpret_cast(&((static_cast(0))->*M)); } #define NzOffsetOf(type, member) NzImplOffsetOf() diff --git a/include/Nazara/Core/Updatable.hpp b/include/Nazara/Core/Updatable.hpp index f0aa8256a..e4905a77b 100644 --- a/include/Nazara/Core/Updatable.hpp +++ b/include/Nazara/Core/Updatable.hpp @@ -9,9 +9,12 @@ #include -class NzUpdatable +class NAZARA_API NzUpdatable { public: + NzUpdatable() = default; + virtual ~NzUpdatable(); + virtual void Update() = 0; }; diff --git a/include/Nazara/Graphics/Drawable.hpp b/include/Nazara/Graphics/Drawable.hpp index 97841eebb..3c45939df 100644 --- a/include/Nazara/Graphics/Drawable.hpp +++ b/include/Nazara/Graphics/Drawable.hpp @@ -13,7 +13,7 @@ class NAZARA_API NzDrawable { public: NzDrawable() = default; - ~NzDrawable(); + virtual ~NzDrawable(); virtual void Draw() const = 0; }; diff --git a/include/Nazara/Math/Vector2.inl b/include/Nazara/Math/Vector2.inl index 81e25ac51..72842ad3b 100644 --- a/include/Nazara/Math/Vector2.inl +++ b/include/Nazara/Math/Vector2.inl @@ -51,19 +51,7 @@ NzVector2::NzVector2(const NzVector4& vec) template T NzVector2::AbsDotProduct(const NzVector2& vec) const { - return std::fabs(x * vec.x) + std::fabs(y * vec.y); -} - -template<> -inline int NzVector2::AbsDotProduct(const NzVector2& vec) const -{ - return std::labs(x * vec.x) + std::labs(y * vec.y); -} - -template<> -inline unsigned int NzVector2::AbsDotProduct(const NzVector2& vec) const -{ - return std::labs(x * vec.x) + std::labs(y * vec.y); + return std::abs(x * vec.x) + std::abs(y * vec.y); } template diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index 1e09a2af3..d35988319 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -57,19 +57,7 @@ NzVector3::NzVector3(const NzVector4& vec) template T NzVector3::AbsDotProduct(const NzVector3& vec) const { - return std::fabs(x * vec.x) + std::fabs(y * vec.y) + std::fabs(z * vec.z); -} - -template<> -inline int NzVector3::AbsDotProduct(const NzVector3& vec) const -{ - return std::labs(x * vec.x) + std::labs(y * vec.y) + std::labs(z * vec.z); -} - -template<> -inline unsigned int NzVector3::AbsDotProduct(const NzVector3& vec) const -{ - return std::labs(x * vec.x) + std::labs(y * vec.y) + std::labs(z * vec.z); + return std::abs(x * vec.x) + std::abs(y * vec.y) + std::abs(z * vec.z); } template diff --git a/include/Nazara/Math/Vector4.inl b/include/Nazara/Math/Vector4.inl index c1d7f4d1c..518dda2c2 100644 --- a/include/Nazara/Math/Vector4.inl +++ b/include/Nazara/Math/Vector4.inl @@ -70,19 +70,7 @@ NzVector4::NzVector4(const NzVector4& vec) template T NzVector4::AbsDotProduct(const NzVector4& vec) const { - return std::fabs(x * vec.x) + std::fabs(y * vec.y) + std::fabs(z * vec.z) + std::fabs(w * vec.w); -} - -template<> -inline int NzVector4::AbsDotProduct(const NzVector4& vec) const -{ - return std::labs(x * vec.x) + std::labs(y * vec.y) + std::labs(z * vec.z) + std::labs(w * vec.w); -} - -template<> -inline unsigned int NzVector4::AbsDotProduct(const NzVector4& vec) const -{ - return std::labs(x * vec.x) + std::labs(y * vec.y) + std::labs(z * vec.z) + std::labs(w * vec.w); + return std::abs(x * vec.x) + std::abs(y * vec.y) + std::abs(z * vec.z) + std::abs(w * vec.w); } template diff --git a/include/Nazara/Utility/AbstractAtlas.hpp b/include/Nazara/Utility/AbstractAtlas.hpp index 3dabff1eb..eb0a240ae 100644 --- a/include/Nazara/Utility/AbstractAtlas.hpp +++ b/include/Nazara/Utility/AbstractAtlas.hpp @@ -35,7 +35,7 @@ class NAZARA_API NzAbstractAtlas void RemoveListener(Listener* font) const; - class Listener + class NAZARA_API Listener { public: Listener() = default; diff --git a/src/Nazara/Core/Updatable.cpp b/src/Nazara/Core/Updatable.cpp new file mode 100644 index 000000000..79495dcbc --- /dev/null +++ b/src/Nazara/Core/Updatable.cpp @@ -0,0 +1,8 @@ +// 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 + +NzUpdatable::~NzUpdatable() = default; diff --git a/src/Nazara/Utility/Buffer.cpp b/src/Nazara/Utility/Buffer.cpp index 1a631e990..757b799a1 100644 --- a/src/Nazara/Utility/Buffer.cpp +++ b/src/Nazara/Utility/Buffer.cpp @@ -297,4 +297,4 @@ void NzBuffer::Uninitialize() std::memset(s_bufferFactories, 0, (nzDataStorage_Max+1)*sizeof(NzBuffer::BufferFactory)); } -NzBuffer::BufferFactory NzBuffer::s_bufferFactories[nzDataStorage_Max+1] = {0}; +NzBuffer::BufferFactory NzBuffer::s_bufferFactories[nzDataStorage_Max+1] = {nullptr}; diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index b25ccdfd4..e33ce619a 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -809,7 +809,7 @@ NzVector3ui NzImage::GetSize(nzUInt8 level) const if (level >= m_sharedImage->levelCount) { NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')'); - return 0; + return NzVector3ui::Zero(); } #endif From ea8d6836244cd258c8f50817db2f3e9b78e982af Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 21 Jan 2015 20:53:01 +0100 Subject: [PATCH 212/233] Updated copyright year (532 files, wow) Former-commit-id: cbb31f1124a86720bd3a54fe589a0f849a87b434 --- include/Nazara/Audio/Algorithm.hpp | 2 +- include/Nazara/Audio/Algorithm.inl | 2 +- include/Nazara/Audio/Audio.hpp | 2 +- include/Nazara/Audio/Config.hpp | 2 +- include/Nazara/Audio/ConfigCheck.hpp | 2 +- include/Nazara/Audio/Debug.hpp | 2 +- include/Nazara/Audio/DebugOff.hpp | 2 +- include/Nazara/Audio/Enums.hpp | 2 +- include/Nazara/Audio/Music.hpp | 2 +- include/Nazara/Audio/OpenAL.hpp | 2 +- include/Nazara/Audio/Sound.hpp | 2 +- include/Nazara/Audio/SoundBuffer.hpp | 2 +- include/Nazara/Audio/SoundEmitter.hpp | 2 +- include/Nazara/Audio/SoundStream.hpp | 2 +- include/Nazara/Core/AbstractHash.hpp | 2 +- include/Nazara/Core/ByteArray.hpp | 2 +- include/Nazara/Core/CallOnExit.hpp | 2 +- include/Nazara/Core/CallOnExit.inl | 2 +- include/Nazara/Core/Clock.hpp | 2 +- include/Nazara/Core/Color.hpp | 2 +- include/Nazara/Core/Color.inl | 2 +- include/Nazara/Core/ConditionVariable.hpp | 2 +- include/Nazara/Core/Config.hpp | 2 +- include/Nazara/Core/ConfigCheck.hpp | 2 +- include/Nazara/Core/Core.hpp | 2 +- include/Nazara/Core/Debug.hpp | 2 +- include/Nazara/Core/Debug/NewRedefinition.hpp | 2 +- include/Nazara/Core/DebugOff.hpp | 2 +- include/Nazara/Core/Directory.hpp | 2 +- include/Nazara/Core/DynLib.hpp | 2 +- include/Nazara/Core/Endianness.hpp | 2 +- include/Nazara/Core/Endianness.inl | 2 +- include/Nazara/Core/Enums.hpp | 2 +- include/Nazara/Core/Error.hpp | 2 +- include/Nazara/Core/ErrorFlags.hpp | 2 +- include/Nazara/Core/File.hpp | 2 +- include/Nazara/Core/Format.hpp | 2 +- include/Nazara/Core/Functor.hpp | 2 +- include/Nazara/Core/Functor.inl | 2 +- include/Nazara/Core/GuillotineBinPack.hpp | 2 +- include/Nazara/Core/HardwareInfo.hpp | 2 +- include/Nazara/Core/Hash.hpp | 2 +- include/Nazara/Core/Hash/CRC32.hpp | 2 +- include/Nazara/Core/Hash/Fletcher16.hpp | 2 +- include/Nazara/Core/Hash/MD5.hpp | 2 +- include/Nazara/Core/Hash/SHA1.hpp | 2 +- include/Nazara/Core/Hash/SHA224.hpp | 2 +- include/Nazara/Core/Hash/SHA256.hpp | 2 +- include/Nazara/Core/Hash/SHA384.hpp | 2 +- include/Nazara/Core/Hash/SHA512.hpp | 2 +- include/Nazara/Core/Hash/Whirlpool.hpp | 2 +- include/Nazara/Core/HashDigest.hpp | 2 +- include/Nazara/Core/Hashable.hpp | 2 +- include/Nazara/Core/Initializer.hpp | 2 +- include/Nazara/Core/Initializer.inl | 2 +- include/Nazara/Core/InputStream.hpp | 2 +- include/Nazara/Core/LockGuard.hpp | 2 +- include/Nazara/Core/Log.hpp | 2 +- include/Nazara/Core/MemoryHelper.hpp | 2 +- include/Nazara/Core/MemoryHelper.inl | 2 +- include/Nazara/Core/MemoryManager.hpp | 2 +- include/Nazara/Core/MemoryPool.hpp | 2 +- include/Nazara/Core/MemoryPool.inl | 2 +- include/Nazara/Core/MemoryStream.hpp | 2 +- include/Nazara/Core/Mutex.hpp | 2 +- include/Nazara/Core/NonCopyable.hpp | 2 +- include/Nazara/Core/OffsetOf.hpp | 2 +- include/Nazara/Core/ParameterList.hpp | 2 +- include/Nazara/Core/PluginManager.hpp | 2 +- include/Nazara/Core/Primitive.hpp | 2 +- include/Nazara/Core/Primitive.inl | 2 +- include/Nazara/Core/PrimitiveList.hpp | 2 +- include/Nazara/Core/Resource.hpp | 2 +- include/Nazara/Core/ResourceListener.hpp | 2 +- include/Nazara/Core/ResourceLoader.hpp | 2 +- include/Nazara/Core/ResourceLoader.inl | 2 +- include/Nazara/Core/ResourceRef.hpp | 2 +- include/Nazara/Core/ResourceRef.inl | 2 +- include/Nazara/Core/Semaphore.hpp | 2 +- include/Nazara/Core/SparsePtr.hpp | 2 +- include/Nazara/Core/SparsePtr.inl | 2 +- include/Nazara/Core/Stream.hpp | 2 +- include/Nazara/Core/String.hpp | 2 +- include/Nazara/Core/String.inl | 2 +- include/Nazara/Core/StringStream.hpp | 2 +- include/Nazara/Core/TaskScheduler.hpp | 2 +- include/Nazara/Core/TaskScheduler.inl | 2 +- include/Nazara/Core/Thread.hpp | 2 +- include/Nazara/Core/Thread.inl | 2 +- include/Nazara/Core/ThreadSafety.hpp | 2 +- include/Nazara/Core/ThreadSafetyOff.hpp | 2 +- include/Nazara/Core/Tuple.hpp | 2 +- include/Nazara/Core/Tuple.inl | 2 +- include/Nazara/Core/Unicode.hpp | 2 +- include/Nazara/Core/Updatable.hpp | 2 +- include/Nazara/Graphics/AbstractBackground.hpp | 2 +- include/Nazara/Graphics/AbstractRenderQueue.hpp | 2 +- include/Nazara/Graphics/AbstractRenderTechnique.hpp | 2 +- include/Nazara/Graphics/AbstractViewer.hpp | 2 +- include/Nazara/Graphics/Camera.hpp | 2 +- include/Nazara/Graphics/ColorBackground.hpp | 2 +- include/Nazara/Graphics/Config.hpp | 2 +- include/Nazara/Graphics/ConfigCheck.hpp | 2 +- include/Nazara/Graphics/Debug.hpp | 2 +- include/Nazara/Graphics/DebugOff.hpp | 2 +- include/Nazara/Graphics/DeferredBloomPass.hpp | 2 +- include/Nazara/Graphics/DeferredDOFPass.hpp | 2 +- include/Nazara/Graphics/DeferredFXAAPass.hpp | 2 +- include/Nazara/Graphics/DeferredFinalPass.hpp | 2 +- include/Nazara/Graphics/DeferredFogPass.hpp | 2 +- include/Nazara/Graphics/DeferredForwardPass.hpp | 2 +- include/Nazara/Graphics/DeferredGeometryPass.hpp | 2 +- include/Nazara/Graphics/DeferredPhongLightingPass.hpp | 2 +- include/Nazara/Graphics/DeferredRenderPass.hpp | 2 +- include/Nazara/Graphics/DeferredRenderQueue.hpp | 2 +- include/Nazara/Graphics/DeferredRenderTechnique.hpp | 2 +- include/Nazara/Graphics/Drawable.hpp | 2 +- include/Nazara/Graphics/Enums.hpp | 2 +- include/Nazara/Graphics/ForwardRenderQueue.hpp | 2 +- include/Nazara/Graphics/ForwardRenderTechnique.hpp | 2 +- include/Nazara/Graphics/Graphics.hpp | 2 +- include/Nazara/Graphics/Light.hpp | 2 +- include/Nazara/Graphics/LightManager.hpp | 2 +- include/Nazara/Graphics/Material.hpp | 2 +- include/Nazara/Graphics/Model.hpp | 2 +- include/Nazara/Graphics/ParticleController.hpp | 2 +- include/Nazara/Graphics/ParticleDeclaration.hpp | 2 +- include/Nazara/Graphics/ParticleEmitter.hpp | 2 +- include/Nazara/Graphics/ParticleGenerator.hpp | 2 +- include/Nazara/Graphics/ParticleMapper.hpp | 2 +- include/Nazara/Graphics/ParticleMapper.inl | 2 +- include/Nazara/Graphics/ParticleRenderer.hpp | 2 +- include/Nazara/Graphics/ParticleStruct.hpp | 2 +- include/Nazara/Graphics/ParticleSystem.hpp | 2 +- include/Nazara/Graphics/RenderTechniques.hpp | 2 +- include/Nazara/Graphics/Scene.hpp | 2 +- include/Nazara/Graphics/SceneLayer.hpp | 2 +- include/Nazara/Graphics/SceneNode.hpp | 2 +- include/Nazara/Graphics/SceneRoot.hpp | 2 +- include/Nazara/Graphics/SkeletalModel.hpp | 2 +- include/Nazara/Graphics/SkinningManager.hpp | 2 +- include/Nazara/Graphics/SkyboxBackground.hpp | 2 +- include/Nazara/Graphics/Sprite.hpp | 2 +- include/Nazara/Graphics/TextSprite.hpp | 2 +- include/Nazara/Graphics/TextureBackground.hpp | 2 +- include/Nazara/Graphics/View.hpp | 2 +- include/Nazara/Lua/Config.hpp | 2 +- include/Nazara/Lua/ConfigCheck.hpp | 2 +- include/Nazara/Lua/Debug.hpp | 2 +- include/Nazara/Lua/DebugOff.hpp | 2 +- include/Nazara/Lua/Enums.hpp | 2 +- include/Nazara/Lua/Lua.hpp | 2 +- include/Nazara/Lua/LuaClass.hpp | 2 +- include/Nazara/Lua/LuaClass.inl | 2 +- include/Nazara/Lua/LuaInstance.hpp | 2 +- include/Nazara/Math/Algorithm.hpp | 2 +- include/Nazara/Math/Algorithm.inl | 2 +- include/Nazara/Math/BoundingVolume.hpp | 2 +- include/Nazara/Math/BoundingVolume.inl | 2 +- include/Nazara/Math/Box.hpp | 2 +- include/Nazara/Math/Box.inl | 2 +- include/Nazara/Math/Config.hpp | 2 +- include/Nazara/Math/Enums.hpp | 2 +- include/Nazara/Math/EulerAngles.hpp | 2 +- include/Nazara/Math/EulerAngles.inl | 2 +- include/Nazara/Math/Frustum.hpp | 2 +- include/Nazara/Math/Frustum.inl | 2 +- include/Nazara/Math/Matrix4.hpp | 2 +- include/Nazara/Math/Matrix4.inl | 2 +- include/Nazara/Math/OrientedBox.hpp | 2 +- include/Nazara/Math/OrientedBox.inl | 2 +- include/Nazara/Math/Plane.hpp | 2 +- include/Nazara/Math/Plane.inl | 2 +- include/Nazara/Math/Quaternion.hpp | 2 +- include/Nazara/Math/Quaternion.inl | 2 +- include/Nazara/Math/Ray.hpp | 2 +- include/Nazara/Math/Ray.inl | 2 +- include/Nazara/Math/Rect.hpp | 2 +- include/Nazara/Math/Rect.inl | 2 +- include/Nazara/Math/Sphere.hpp | 2 +- include/Nazara/Math/Sphere.inl | 2 +- include/Nazara/Math/Vector2.hpp | 2 +- include/Nazara/Math/Vector2.inl | 2 +- include/Nazara/Math/Vector3.hpp | 2 +- include/Nazara/Math/Vector3.inl | 2 +- include/Nazara/Math/Vector4.hpp | 2 +- include/Nazara/Math/Vector4.inl | 2 +- include/Nazara/Noise/Abstract2DNoise.hpp | 2 +- include/Nazara/Noise/Abstract3DNoise.hpp | 2 +- include/Nazara/Noise/Abstract4DNoise.hpp | 2 +- include/Nazara/Noise/ComplexNoiseBase.hpp | 2 +- include/Nazara/Noise/Config.hpp | 2 +- include/Nazara/Noise/ConfigCheck.hpp | 2 +- include/Nazara/Noise/Debug.hpp | 2 +- include/Nazara/Noise/DebugOff.hpp | 2 +- include/Nazara/Noise/FBM2D.hpp | 2 +- include/Nazara/Noise/FBM3D.hpp | 2 +- include/Nazara/Noise/FBM4D.hpp | 2 +- include/Nazara/Noise/HybridMultiFractal3D.hpp | 2 +- include/Nazara/Noise/HybridMultiFractal4D.hpp | 2 +- include/Nazara/Noise/HybridMultifractal2D.hpp | 2 +- include/Nazara/Noise/MappedNoiseBase.hpp | 2 +- include/Nazara/Noise/Noise.hpp | 2 +- include/Nazara/Noise/NoiseBase.hpp | 2 +- include/Nazara/Noise/Perlin2D.hpp | 2 +- include/Nazara/Noise/Perlin3D.hpp | 2 +- include/Nazara/Noise/Perlin4D.hpp | 2 +- include/Nazara/Noise/Simplex2D.hpp | 2 +- include/Nazara/Noise/Simplex3D.hpp | 2 +- include/Nazara/Noise/Simplex4D.hpp | 2 +- include/Nazara/Physics/Config.hpp | 2 +- include/Nazara/Physics/ConfigCheck.hpp | 2 +- include/Nazara/Physics/Debug.hpp | 2 +- include/Nazara/Physics/DebugOff.hpp | 2 +- include/Nazara/Physics/Enums.hpp | 2 +- include/Nazara/Physics/Geom.hpp | 2 +- include/Nazara/Physics/PhysObject.hpp | 2 +- include/Nazara/Physics/PhysWorld.hpp | 2 +- include/Nazara/Physics/Physics.hpp | 2 +- include/Nazara/Prerequesites.hpp | 2 +- include/Nazara/Renderer/Config.hpp | 2 +- include/Nazara/Renderer/ConfigCheck.hpp | 2 +- include/Nazara/Renderer/Context.hpp | 2 +- include/Nazara/Renderer/ContextParameters.hpp | 2 +- include/Nazara/Renderer/Debug.hpp | 2 +- include/Nazara/Renderer/DebugDrawer.hpp | 2 +- include/Nazara/Renderer/DebugOff.hpp | 2 +- include/Nazara/Renderer/Enums.hpp | 2 +- include/Nazara/Renderer/GpuQuery.hpp | 2 +- include/Nazara/Renderer/OpenGL.hpp | 2 +- include/Nazara/Renderer/RenderBuffer.hpp | 2 +- include/Nazara/Renderer/RenderStates.hpp | 2 +- include/Nazara/Renderer/RenderStates.inl | 2 +- include/Nazara/Renderer/RenderTarget.hpp | 2 +- include/Nazara/Renderer/RenderTargetParameters.hpp | 2 +- include/Nazara/Renderer/RenderTexture.hpp | 2 +- include/Nazara/Renderer/RenderWindow.hpp | 2 +- include/Nazara/Renderer/Renderer.hpp | 2 +- include/Nazara/Renderer/Shader.hpp | 2 +- include/Nazara/Renderer/ShaderLibrary.hpp | 2 +- include/Nazara/Renderer/ShaderStage.hpp | 2 +- include/Nazara/Renderer/Texture.hpp | 2 +- include/Nazara/Renderer/TextureSampler.hpp | 2 +- include/Nazara/Renderer/UberShader.hpp | 2 +- include/Nazara/Renderer/UberShaderInstance.hpp | 2 +- include/Nazara/Renderer/UberShaderInstancePreprocessor.hpp | 2 +- include/Nazara/Renderer/UberShaderLibrary.hpp | 2 +- include/Nazara/Renderer/UberShaderPreprocessor.hpp | 2 +- include/Nazara/Utility/AbstractBuffer.hpp | 2 +- include/Nazara/Utility/Algorithm.hpp | 2 +- include/Nazara/Utility/Algorithm.inl | 2 +- include/Nazara/Utility/Animation.hpp | 2 +- include/Nazara/Utility/Buffer.hpp | 2 +- include/Nazara/Utility/BufferMapper.hpp | 2 +- include/Nazara/Utility/BufferMapper.inl | 2 +- include/Nazara/Utility/Config.hpp | 2 +- include/Nazara/Utility/ConfigCheck.hpp | 2 +- include/Nazara/Utility/CubemapParams.hpp | 2 +- include/Nazara/Utility/Cursor.hpp | 2 +- include/Nazara/Utility/Debug.hpp | 2 +- include/Nazara/Utility/DebugOff.hpp | 2 +- include/Nazara/Utility/Enums.hpp | 2 +- include/Nazara/Utility/Event.hpp | 2 +- include/Nazara/Utility/Font.hpp | 2 +- include/Nazara/Utility/FontData.hpp | 2 +- include/Nazara/Utility/FontGlyph.hpp | 2 +- include/Nazara/Utility/Icon.hpp | 2 +- include/Nazara/Utility/Image.hpp | 2 +- include/Nazara/Utility/IndexBuffer.hpp | 2 +- include/Nazara/Utility/IndexIterator.hpp | 2 +- include/Nazara/Utility/IndexIterator.inl | 2 +- include/Nazara/Utility/IndexMapper.hpp | 2 +- include/Nazara/Utility/Joint.hpp | 2 +- include/Nazara/Utility/Keyboard.hpp | 2 +- include/Nazara/Utility/Mesh.hpp | 2 +- include/Nazara/Utility/MeshData.hpp | 2 +- include/Nazara/Utility/Mouse.hpp | 2 +- include/Nazara/Utility/Node.hpp | 2 +- include/Nazara/Utility/PixelFormat.hpp | 2 +- include/Nazara/Utility/PixelFormat.inl | 2 +- include/Nazara/Utility/Sequence.hpp | 2 +- include/Nazara/Utility/SkeletalMesh.hpp | 2 +- include/Nazara/Utility/Skeleton.hpp | 2 +- include/Nazara/Utility/StaticMesh.hpp | 2 +- include/Nazara/Utility/SubMesh.hpp | 2 +- include/Nazara/Utility/TriangleIterator.hpp | 2 +- include/Nazara/Utility/Utility.hpp | 2 +- include/Nazara/Utility/VertexBuffer.hpp | 2 +- include/Nazara/Utility/VertexDeclaration.hpp | 2 +- include/Nazara/Utility/VertexMapper.hpp | 2 +- include/Nazara/Utility/VertexMapper.inl | 2 +- include/Nazara/Utility/VertexStruct.hpp | 2 +- include/Nazara/Utility/VideoMode.hpp | 2 +- include/Nazara/Utility/Window.hpp | 2 +- include/Nazara/Utility/WindowHandle.hpp | 2 +- src/Nazara/Audio/Audio.cpp | 2 +- src/Nazara/Audio/Loaders/sndfile.hpp | 2 +- src/Nazara/Audio/Loaders/sndfile/Loader.cpp | 2 +- src/Nazara/Audio/Music.cpp | 2 +- src/Nazara/Audio/OpenAL.cpp | 2 +- src/Nazara/Audio/Sound.cpp | 2 +- src/Nazara/Audio/SoundBuffer.cpp | 2 +- src/Nazara/Audio/SoundEmitter.cpp | 2 +- src/Nazara/Audio/SoundStream.cpp | 2 +- src/Nazara/Core/AbstractHash.cpp | 2 +- src/Nazara/Core/ByteArray.cpp | 2 +- src/Nazara/Core/Clock.cpp | 2 +- src/Nazara/Core/Color.cpp | 2 +- src/Nazara/Core/ConditionVariable.cpp | 2 +- src/Nazara/Core/Core.cpp | 2 +- src/Nazara/Core/Debug/NewRedefinition.cpp | 2 +- src/Nazara/Core/Directory.cpp | 2 +- src/Nazara/Core/DynLib.cpp | 2 +- src/Nazara/Core/Error.cpp | 2 +- src/Nazara/Core/ErrorFlags.cpp | 2 +- src/Nazara/Core/File.cpp | 2 +- src/Nazara/Core/GuillotineBinPack.cpp | 2 +- src/Nazara/Core/HardwareInfo.cpp | 2 +- src/Nazara/Core/Hash.cpp | 2 +- src/Nazara/Core/Hash/CRC32.cpp | 2 +- src/Nazara/Core/Hash/Fletcher16.cpp | 2 +- src/Nazara/Core/Hash/MD5.cpp | 2 +- src/Nazara/Core/Hash/SHA/Internal.cpp | 2 +- src/Nazara/Core/Hash/SHA/Internal.hpp | 2 +- src/Nazara/Core/Hash/SHA1.cpp | 2 +- src/Nazara/Core/Hash/SHA224.cpp | 2 +- src/Nazara/Core/Hash/SHA256.cpp | 2 +- src/Nazara/Core/Hash/SHA384.cpp | 2 +- src/Nazara/Core/Hash/SHA512.cpp | 2 +- src/Nazara/Core/Hash/Whirlpool.cpp | 2 +- src/Nazara/Core/HashDigest.cpp | 2 +- src/Nazara/Core/Hashable.cpp | 2 +- src/Nazara/Core/InputStream.cpp | 2 +- src/Nazara/Core/LockGuard.cpp | 2 +- src/Nazara/Core/Log.cpp | 2 +- src/Nazara/Core/MemoryManager.cpp | 2 +- src/Nazara/Core/MemoryStream.cpp | 2 +- src/Nazara/Core/Mutex.cpp | 2 +- src/Nazara/Core/ParameterList.cpp | 2 +- src/Nazara/Core/PluginManager.cpp | 2 +- src/Nazara/Core/PrimitiveList.cpp | 2 +- src/Nazara/Core/Resource.cpp | 2 +- src/Nazara/Core/ResourceListener.cpp | 2 +- src/Nazara/Core/Semaphore.cpp | 2 +- src/Nazara/Core/Stream.cpp | 2 +- src/Nazara/Core/String.cpp | 2 +- src/Nazara/Core/StringStream.cpp | 2 +- src/Nazara/Core/TaskScheduler.cpp | 2 +- src/Nazara/Core/Thread.cpp | 2 +- src/Nazara/Core/Unicode.cpp | 2 +- src/Nazara/Core/Win32/ClockImpl.cpp | 2 +- src/Nazara/Core/Win32/ClockImpl.hpp | 2 +- src/Nazara/Core/Win32/ConditionVariableImpl.cpp | 2 +- src/Nazara/Core/Win32/ConditionVariableImpl.hpp | 2 +- src/Nazara/Core/Win32/DirectoryImpl.cpp | 2 +- src/Nazara/Core/Win32/DirectoryImpl.hpp | 2 +- src/Nazara/Core/Win32/DynLibImpl.cpp | 2 +- src/Nazara/Core/Win32/DynLibImpl.hpp | 2 +- src/Nazara/Core/Win32/FileImpl.cpp | 2 +- src/Nazara/Core/Win32/FileImpl.hpp | 2 +- src/Nazara/Core/Win32/HardwareInfoImpl.cpp | 2 +- src/Nazara/Core/Win32/HardwareInfoImpl.hpp | 2 +- src/Nazara/Core/Win32/MutexImpl.cpp | 2 +- src/Nazara/Core/Win32/MutexImpl.hpp | 2 +- src/Nazara/Core/Win32/SemaphoreImpl.cpp | 2 +- src/Nazara/Core/Win32/SemaphoreImpl.hpp | 2 +- src/Nazara/Core/Win32/TaskSchedulerImpl.cpp | 2 +- src/Nazara/Core/Win32/TaskSchedulerImpl.hpp | 2 +- src/Nazara/Core/Win32/ThreadImpl.cpp | 2 +- src/Nazara/Core/Win32/ThreadImpl.hpp | 2 +- src/Nazara/Core/Win32/Time.cpp | 2 +- src/Nazara/Core/Win32/Time.hpp | 2 +- src/Nazara/Graphics/AbstractBackground.cpp | 2 +- src/Nazara/Graphics/AbstractRenderQueue.cpp | 2 +- src/Nazara/Graphics/AbstractRenderTechnique.cpp | 2 +- src/Nazara/Graphics/AbstractViewer.cpp | 2 +- src/Nazara/Graphics/Camera.cpp | 2 +- src/Nazara/Graphics/ColorBackground.cpp | 2 +- src/Nazara/Graphics/DeferredBloomPass.cpp | 2 +- src/Nazara/Graphics/DeferredDOFPass.cpp | 2 +- src/Nazara/Graphics/DeferredFXAAPass.cpp | 2 +- src/Nazara/Graphics/DeferredFinalPass.cpp | 2 +- src/Nazara/Graphics/DeferredFogPass.cpp | 2 +- src/Nazara/Graphics/DeferredForwardPass.cpp | 2 +- src/Nazara/Graphics/DeferredGeometryPass.cpp | 2 +- src/Nazara/Graphics/DeferredPhongLightingPass.cpp | 2 +- src/Nazara/Graphics/DeferredRenderPass.cpp | 2 +- src/Nazara/Graphics/DeferredRenderQueue.cpp | 2 +- src/Nazara/Graphics/DeferredRenderTechnique.cpp | 2 +- src/Nazara/Graphics/Drawable.cpp | 2 +- src/Nazara/Graphics/ForwardRenderQueue.cpp | 2 +- src/Nazara/Graphics/ForwardRenderTechnique.cpp | 2 +- src/Nazara/Graphics/Graphics.cpp | 2 +- src/Nazara/Graphics/Light.cpp | 2 +- src/Nazara/Graphics/LightManager.cpp | 2 +- src/Nazara/Graphics/Loaders/Mesh.hpp | 2 +- src/Nazara/Graphics/Loaders/Mesh/Loader.cpp | 2 +- src/Nazara/Graphics/Loaders/OBJ.hpp | 2 +- src/Nazara/Graphics/Loaders/OBJ/Loader.cpp | 2 +- src/Nazara/Graphics/Loaders/OBJ/MTLParser.cpp | 2 +- src/Nazara/Graphics/Loaders/OBJ/MTLParser.hpp | 2 +- src/Nazara/Graphics/Loaders/OBJ/OBJParser.cpp | 2 +- src/Nazara/Graphics/Loaders/OBJ/OBJParser.hpp | 2 +- src/Nazara/Graphics/Loaders/Texture.hpp | 2 +- src/Nazara/Graphics/Loaders/Texture/Loader.cpp | 2 +- src/Nazara/Graphics/Material.cpp | 2 +- src/Nazara/Graphics/Model.cpp | 2 +- src/Nazara/Graphics/ParticleController.cpp | 2 +- src/Nazara/Graphics/ParticleDeclaration.cpp | 2 +- src/Nazara/Graphics/ParticleEmitter.cpp | 2 +- src/Nazara/Graphics/ParticleGenerator.cpp | 2 +- src/Nazara/Graphics/ParticleMapper.cpp | 2 +- src/Nazara/Graphics/ParticleRenderer.cpp | 2 +- src/Nazara/Graphics/ParticleSystem.cpp | 2 +- src/Nazara/Graphics/RenderTechniques.cpp | 2 +- src/Nazara/Graphics/Scene.cpp | 2 +- src/Nazara/Graphics/SceneNode.cpp | 2 +- src/Nazara/Graphics/SceneRoot.cpp | 2 +- src/Nazara/Graphics/SkeletalModel.cpp | 2 +- src/Nazara/Graphics/SkinningManager.cpp | 2 +- src/Nazara/Graphics/SkyboxBackground.cpp | 2 +- src/Nazara/Graphics/Sprite.cpp | 2 +- src/Nazara/Graphics/TextSprite.cpp | 2 +- src/Nazara/Graphics/TextureBackground.cpp | 2 +- src/Nazara/Graphics/View.cpp | 2 +- src/Nazara/Lua/Lua.cpp | 2 +- src/Nazara/Lua/LuaInstance.cpp | 2 +- src/Nazara/Noise/Abstract2DNoise.cpp | 2 +- src/Nazara/Noise/Abstract3DNoise.cpp | 2 +- src/Nazara/Noise/Abstract4DNoise.cpp | 2 +- src/Nazara/Noise/ComplexNoiseBase.cpp | 2 +- src/Nazara/Noise/FBM2D.cpp | 2 +- src/Nazara/Noise/FBM3D.cpp | 2 +- src/Nazara/Noise/FBM4D.cpp | 2 +- src/Nazara/Noise/HybridMultiFractal3D.cpp | 2 +- src/Nazara/Noise/HybridMultiFractal4D.cpp | 2 +- src/Nazara/Noise/HybridMultifractal2D.cpp | 2 +- src/Nazara/Noise/MappedNoiseBase.cpp | 2 +- src/Nazara/Noise/Noise.cpp | 2 +- src/Nazara/Noise/NoiseBase.cpp | 2 +- src/Nazara/Noise/Perlin2D.cpp | 2 +- src/Nazara/Noise/Perlin3D.cpp | 2 +- src/Nazara/Noise/Perlin4D.cpp | 2 +- src/Nazara/Noise/Simplex2D.cpp | 2 +- src/Nazara/Noise/Simplex3D.cpp | 2 +- src/Nazara/Noise/Simplex4D.cpp | 2 +- src/Nazara/Physics/Geom.cpp | 2 +- src/Nazara/Physics/PhysObject.cpp | 2 +- src/Nazara/Physics/PhysWorld.cpp | 2 +- src/Nazara/Physics/Physics.cpp | 2 +- src/Nazara/Renderer/Context.cpp | 2 +- src/Nazara/Renderer/ContextParameters.cpp | 2 +- src/Nazara/Renderer/DebugDrawer.cpp | 2 +- src/Nazara/Renderer/GpuQuery.cpp | 2 +- src/Nazara/Renderer/HardwareBuffer.cpp | 2 +- src/Nazara/Renderer/HardwareBuffer.hpp | 2 +- src/Nazara/Renderer/OpenGL.cpp | 2 +- src/Nazara/Renderer/RenderBuffer.cpp | 2 +- src/Nazara/Renderer/RenderTarget.cpp | 2 +- src/Nazara/Renderer/RenderTexture.cpp | 2 +- src/Nazara/Renderer/RenderWindow.cpp | 2 +- src/Nazara/Renderer/Renderer.cpp | 2 +- src/Nazara/Renderer/Shader.cpp | 2 +- src/Nazara/Renderer/ShaderLibrary.cpp | 2 +- src/Nazara/Renderer/ShaderStage.cpp | 2 +- src/Nazara/Renderer/Texture.cpp | 2 +- src/Nazara/Renderer/TextureSampler.cpp | 2 +- src/Nazara/Renderer/UberShader.cpp | 2 +- src/Nazara/Renderer/UberShaderInstance.cpp | 2 +- src/Nazara/Renderer/UberShaderInstancePreprocessor.cpp | 2 +- src/Nazara/Renderer/UberShaderLibrary.cpp | 2 +- src/Nazara/Renderer/UberShaderPreprocessor.cpp | 2 +- src/Nazara/Renderer/Win32/ContextImpl.cpp | 2 +- src/Nazara/Renderer/Win32/ContextImpl.hpp | 2 +- src/Nazara/Utility/AbstractBuffer.cpp | 2 +- src/Nazara/Utility/Algorithm.cpp | 2 +- src/Nazara/Utility/Animation.cpp | 2 +- src/Nazara/Utility/Buffer.cpp | 2 +- src/Nazara/Utility/Cursor.cpp | 2 +- src/Nazara/Utility/Font.cpp | 2 +- src/Nazara/Utility/FontData.cpp | 2 +- src/Nazara/Utility/Icon.cpp | 2 +- src/Nazara/Utility/Image.cpp | 2 +- src/Nazara/Utility/IndexBuffer.cpp | 2 +- src/Nazara/Utility/IndexMapper.cpp | 2 +- src/Nazara/Utility/Joint.cpp | 2 +- src/Nazara/Utility/Keyboard.cpp | 2 +- src/Nazara/Utility/Loaders/FreeType.hpp | 2 +- src/Nazara/Utility/Loaders/FreeType/Loader.cpp | 2 +- src/Nazara/Utility/Loaders/MD2.hpp | 2 +- src/Nazara/Utility/Loaders/MD2/Constants.cpp | 2 +- src/Nazara/Utility/Loaders/MD2/Constants.hpp | 2 +- src/Nazara/Utility/Loaders/MD2/Loader.cpp | 2 +- src/Nazara/Utility/Loaders/MD5Anim.hpp | 2 +- src/Nazara/Utility/Loaders/MD5Anim/Loader.cpp | 2 +- src/Nazara/Utility/Loaders/MD5Anim/Parser.cpp | 2 +- src/Nazara/Utility/Loaders/MD5Anim/Parser.hpp | 2 +- src/Nazara/Utility/Loaders/MD5Mesh.hpp | 2 +- src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp | 2 +- src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp | 2 +- src/Nazara/Utility/Loaders/MD5Mesh/Parser.hpp | 2 +- src/Nazara/Utility/Loaders/PCX.hpp | 2 +- src/Nazara/Utility/Loaders/PCX/Loader.cpp | 2 +- src/Nazara/Utility/Loaders/STB.hpp | 2 +- src/Nazara/Utility/Loaders/STB/Loader.cpp | 2 +- src/Nazara/Utility/Mesh.cpp | 2 +- src/Nazara/Utility/Mouse.cpp | 2 +- src/Nazara/Utility/Node.cpp | 2 +- src/Nazara/Utility/PixelFormat.cpp | 2 +- src/Nazara/Utility/SkeletalMesh.cpp | 2 +- src/Nazara/Utility/Skeleton.cpp | 2 +- src/Nazara/Utility/SoftwareBuffer.cpp | 2 +- src/Nazara/Utility/SoftwareBuffer.hpp | 2 +- src/Nazara/Utility/StaticMesh.cpp | 2 +- src/Nazara/Utility/SubMesh.cpp | 2 +- src/Nazara/Utility/TriangleIterator.cpp | 2 +- src/Nazara/Utility/Utility.cpp | 2 +- src/Nazara/Utility/VertexBuffer.cpp | 2 +- src/Nazara/Utility/VertexDeclaration.cpp | 2 +- src/Nazara/Utility/VertexMapper.cpp | 2 +- src/Nazara/Utility/VideoMode.cpp | 2 +- src/Nazara/Utility/VideoModeImpl.hpp | 2 +- src/Nazara/Utility/Win32/CursorImpl.cpp | 2 +- src/Nazara/Utility/Win32/CursorImpl.hpp | 2 +- src/Nazara/Utility/Win32/IconImpl.cpp | 2 +- src/Nazara/Utility/Win32/IconImpl.hpp | 2 +- src/Nazara/Utility/Win32/InputImpl.cpp | 2 +- src/Nazara/Utility/Win32/InputImpl.hpp | 2 +- src/Nazara/Utility/Win32/VideoModeImpl.cpp | 2 +- src/Nazara/Utility/Win32/WindowImpl.cpp | 2 +- src/Nazara/Utility/Win32/WindowImpl.hpp | 2 +- src/Nazara/Utility/Window.cpp | 2 +- 532 files changed, 532 insertions(+), 532 deletions(-) diff --git a/include/Nazara/Audio/Algorithm.hpp b/include/Nazara/Audio/Algorithm.hpp index 2042536b3..696d64682 100644 --- a/include/Nazara/Audio/Algorithm.hpp +++ b/include/Nazara/Audio/Algorithm.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Audio/Algorithm.inl b/include/Nazara/Audio/Algorithm.inl index 9d8e4aa13..c673d9601 100644 --- a/include/Nazara/Audio/Algorithm.inl +++ b/include/Nazara/Audio/Algorithm.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Audio/Audio.hpp b/include/Nazara/Audio/Audio.hpp index 876b182a8..2c82bc424 100644 --- a/include/Nazara/Audio/Audio.hpp +++ b/include/Nazara/Audio/Audio.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Audio/Config.hpp b/include/Nazara/Audio/Config.hpp index 0adc2c04f..a30e67e3c 100644 --- a/include/Nazara/Audio/Config.hpp +++ b/include/Nazara/Audio/Config.hpp @@ -1,7 +1,7 @@ /* Nazara Engine - Audio module - Copyright (C) 2014 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) + Copyright (C) 2015 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/include/Nazara/Audio/ConfigCheck.hpp b/include/Nazara/Audio/ConfigCheck.hpp index e102d56ab..7c32933bd 100644 --- a/include/Nazara/Audio/ConfigCheck.hpp +++ b/include/Nazara/Audio/ConfigCheck.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Audio/Debug.hpp b/include/Nazara/Audio/Debug.hpp index ae84c7a0c..4e6124741 100644 --- a/include/Nazara/Audio/Debug.hpp +++ b/include/Nazara/Audio/Debug.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Audio/DebugOff.hpp b/include/Nazara/Audio/DebugOff.hpp index c91fba4e5..254d7701d 100644 --- a/include/Nazara/Audio/DebugOff.hpp +++ b/include/Nazara/Audio/DebugOff.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Audio/Enums.hpp b/include/Nazara/Audio/Enums.hpp index bbdac5941..a9d8dd41d 100644 --- a/include/Nazara/Audio/Enums.hpp +++ b/include/Nazara/Audio/Enums.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Audio/Music.hpp b/include/Nazara/Audio/Music.hpp index 716d68cc0..3b18e6b40 100644 --- a/include/Nazara/Audio/Music.hpp +++ b/include/Nazara/Audio/Music.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Audio/OpenAL.hpp b/include/Nazara/Audio/OpenAL.hpp index 2ab4a0518..d806e890e 100644 --- a/include/Nazara/Audio/OpenAL.hpp +++ b/include/Nazara/Audio/OpenAL.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Audio/Sound.hpp b/include/Nazara/Audio/Sound.hpp index 88f0f3aaf..c05e215aa 100644 --- a/include/Nazara/Audio/Sound.hpp +++ b/include/Nazara/Audio/Sound.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Audio/SoundBuffer.hpp b/include/Nazara/Audio/SoundBuffer.hpp index 7f5480cfd..d82570991 100644 --- a/include/Nazara/Audio/SoundBuffer.hpp +++ b/include/Nazara/Audio/SoundBuffer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Audio/SoundEmitter.hpp b/include/Nazara/Audio/SoundEmitter.hpp index e105d22fb..41b488395 100644 --- a/include/Nazara/Audio/SoundEmitter.hpp +++ b/include/Nazara/Audio/SoundEmitter.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Audio/SoundStream.hpp b/include/Nazara/Audio/SoundStream.hpp index 382702d59..c3bb47eb7 100644 --- a/include/Nazara/Audio/SoundStream.hpp +++ b/include/Nazara/Audio/SoundStream.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Core/AbstractHash.hpp b/include/Nazara/Core/AbstractHash.hpp index 7bad4f20f..11ea82906 100644 --- a/include/Nazara/Core/AbstractHash.hpp +++ b/include/Nazara/Core/AbstractHash.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/ByteArray.hpp b/include/Nazara/Core/ByteArray.hpp index edf19b178..aba0d0158 100644 --- a/include/Nazara/Core/ByteArray.hpp +++ b/include/Nazara/Core/ByteArray.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/CallOnExit.hpp b/include/Nazara/Core/CallOnExit.hpp index 45ea2622d..9c6da1ae6 100644 --- a/include/Nazara/Core/CallOnExit.hpp +++ b/include/Nazara/Core/CallOnExit.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/CallOnExit.inl b/include/Nazara/Core/CallOnExit.inl index fd7f4de80..c24b737a5 100644 --- a/include/Nazara/Core/CallOnExit.inl +++ b/include/Nazara/Core/CallOnExit.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Clock.hpp b/include/Nazara/Core/Clock.hpp index ba39018fb..7f4ffc156 100644 --- a/include/Nazara/Core/Clock.hpp +++ b/include/Nazara/Core/Clock.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Color.hpp b/include/Nazara/Core/Color.hpp index 8e174056c..611fa8e59 100644 --- a/include/Nazara/Core/Color.hpp +++ b/include/Nazara/Core/Color.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Color.inl b/include/Nazara/Core/Color.inl index 662c86911..00b29321e 100644 --- a/include/Nazara/Core/Color.inl +++ b/include/Nazara/Core/Color.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/ConditionVariable.hpp b/include/Nazara/Core/ConditionVariable.hpp index d8290d7fa..5e1787cb7 100644 --- a/include/Nazara/Core/ConditionVariable.hpp +++ b/include/Nazara/Core/ConditionVariable.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Config.hpp b/include/Nazara/Core/Config.hpp index a8c33e665..56a7dcad3 100644 --- a/include/Nazara/Core/Config.hpp +++ b/include/Nazara/Core/Config.hpp @@ -1,7 +1,7 @@ /* Nazara Engine - Core module - Copyright (C) 2014 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) + Copyright (C) 2015 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/include/Nazara/Core/ConfigCheck.hpp b/include/Nazara/Core/ConfigCheck.hpp index a5d0b3772..503152153 100644 --- a/include/Nazara/Core/ConfigCheck.hpp +++ b/include/Nazara/Core/ConfigCheck.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Core.hpp b/include/Nazara/Core/Core.hpp index 021432a8a..5443e8f2b 100644 --- a/include/Nazara/Core/Core.hpp +++ b/include/Nazara/Core/Core.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Debug.hpp b/include/Nazara/Core/Debug.hpp index 7febcddd3..6301f574a 100644 --- a/include/Nazara/Core/Debug.hpp +++ b/include/Nazara/Core/Debug.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Debug/NewRedefinition.hpp b/include/Nazara/Core/Debug/NewRedefinition.hpp index d0fea86c2..b315d7ade 100644 --- a/include/Nazara/Core/Debug/NewRedefinition.hpp +++ b/include/Nazara/Core/Debug/NewRedefinition.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/DebugOff.hpp b/include/Nazara/Core/DebugOff.hpp index fd70b6f0b..e042eff24 100644 --- a/include/Nazara/Core/DebugOff.hpp +++ b/include/Nazara/Core/DebugOff.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Directory.hpp b/include/Nazara/Core/Directory.hpp index 393914473..b5afb15f0 100644 --- a/include/Nazara/Core/Directory.hpp +++ b/include/Nazara/Core/Directory.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/DynLib.hpp b/include/Nazara/Core/DynLib.hpp index 12b89249f..733b7c962 100644 --- a/include/Nazara/Core/DynLib.hpp +++ b/include/Nazara/Core/DynLib.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Endianness.hpp b/include/Nazara/Core/Endianness.hpp index fb58c63d5..76b9e34ad 100644 --- a/include/Nazara/Core/Endianness.hpp +++ b/include/Nazara/Core/Endianness.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Endianness.inl b/include/Nazara/Core/Endianness.inl index b9e6d8f17..ab696dba3 100644 --- a/include/Nazara/Core/Endianness.inl +++ b/include/Nazara/Core/Endianness.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Enums.hpp b/include/Nazara/Core/Enums.hpp index 82e384138..81ccae4e0 100644 --- a/include/Nazara/Core/Enums.hpp +++ b/include/Nazara/Core/Enums.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Error.hpp b/include/Nazara/Core/Error.hpp index 51de269e1..dde4a5100 100644 --- a/include/Nazara/Core/Error.hpp +++ b/include/Nazara/Core/Error.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/ErrorFlags.hpp b/include/Nazara/Core/ErrorFlags.hpp index e763293c7..714996b4f 100644 --- a/include/Nazara/Core/ErrorFlags.hpp +++ b/include/Nazara/Core/ErrorFlags.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/File.hpp b/include/Nazara/Core/File.hpp index 8eff60c73..10abc76e3 100644 --- a/include/Nazara/Core/File.hpp +++ b/include/Nazara/Core/File.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Format.hpp b/include/Nazara/Core/Format.hpp index caa69d879..d03f05eae 100644 --- a/include/Nazara/Core/Format.hpp +++ b/include/Nazara/Core/Format.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Functor.hpp b/include/Nazara/Core/Functor.hpp index 0adbebcf4..4ecbeed25 100644 --- a/include/Nazara/Core/Functor.hpp +++ b/include/Nazara/Core/Functor.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Functor.inl b/include/Nazara/Core/Functor.inl index dfcaac9c4..265ef5605 100644 --- a/include/Nazara/Core/Functor.inl +++ b/include/Nazara/Core/Functor.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/GuillotineBinPack.hpp b/include/Nazara/Core/GuillotineBinPack.hpp index fecac3d00..c1562ba3a 100644 --- a/include/Nazara/Core/GuillotineBinPack.hpp +++ b/include/Nazara/Core/GuillotineBinPack.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/HardwareInfo.hpp b/include/Nazara/Core/HardwareInfo.hpp index bafd8f687..575b3ebc9 100644 --- a/include/Nazara/Core/HardwareInfo.hpp +++ b/include/Nazara/Core/HardwareInfo.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Hash.hpp b/include/Nazara/Core/Hash.hpp index c092b78fb..2f3f45b7b 100644 --- a/include/Nazara/Core/Hash.hpp +++ b/include/Nazara/Core/Hash.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Hash/CRC32.hpp b/include/Nazara/Core/Hash/CRC32.hpp index 00b7276f0..067717e43 100644 --- a/include/Nazara/Core/Hash/CRC32.hpp +++ b/include/Nazara/Core/Hash/CRC32.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Hash/Fletcher16.hpp b/include/Nazara/Core/Hash/Fletcher16.hpp index afdaa17db..cd756477c 100644 --- a/include/Nazara/Core/Hash/Fletcher16.hpp +++ b/include/Nazara/Core/Hash/Fletcher16.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Core/Hash/MD5.hpp b/include/Nazara/Core/Hash/MD5.hpp index 00d64d17e..a2559c4c3 100644 --- a/include/Nazara/Core/Hash/MD5.hpp +++ b/include/Nazara/Core/Hash/MD5.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Core/Hash/SHA1.hpp b/include/Nazara/Core/Hash/SHA1.hpp index d49a2ec0e..896a5ea45 100644 --- a/include/Nazara/Core/Hash/SHA1.hpp +++ b/include/Nazara/Core/Hash/SHA1.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Core/Hash/SHA224.hpp b/include/Nazara/Core/Hash/SHA224.hpp index 467b679b7..d65d28328 100644 --- a/include/Nazara/Core/Hash/SHA224.hpp +++ b/include/Nazara/Core/Hash/SHA224.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Core/Hash/SHA256.hpp b/include/Nazara/Core/Hash/SHA256.hpp index 0bea3ccdb..aa27760ff 100644 --- a/include/Nazara/Core/Hash/SHA256.hpp +++ b/include/Nazara/Core/Hash/SHA256.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Core/Hash/SHA384.hpp b/include/Nazara/Core/Hash/SHA384.hpp index 912828365..a07885760 100644 --- a/include/Nazara/Core/Hash/SHA384.hpp +++ b/include/Nazara/Core/Hash/SHA384.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Core/Hash/SHA512.hpp b/include/Nazara/Core/Hash/SHA512.hpp index ffdaff72e..22dd2e968 100644 --- a/include/Nazara/Core/Hash/SHA512.hpp +++ b/include/Nazara/Core/Hash/SHA512.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Core/Hash/Whirlpool.hpp b/include/Nazara/Core/Hash/Whirlpool.hpp index ec6651f49..b4970712e 100644 --- a/include/Nazara/Core/Hash/Whirlpool.hpp +++ b/include/Nazara/Core/Hash/Whirlpool.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Core/HashDigest.hpp b/include/Nazara/Core/HashDigest.hpp index 8f61dd2f4..ef0acd151 100644 --- a/include/Nazara/Core/HashDigest.hpp +++ b/include/Nazara/Core/HashDigest.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Hashable.hpp b/include/Nazara/Core/Hashable.hpp index b6bdf9d6b..483262622 100644 --- a/include/Nazara/Core/Hashable.hpp +++ b/include/Nazara/Core/Hashable.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Initializer.hpp b/include/Nazara/Core/Initializer.hpp index 4645cbac7..3737593df 100644 --- a/include/Nazara/Core/Initializer.hpp +++ b/include/Nazara/Core/Initializer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Initializer.inl b/include/Nazara/Core/Initializer.inl index fe92b3a2f..732a12418 100644 --- a/include/Nazara/Core/Initializer.inl +++ b/include/Nazara/Core/Initializer.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/InputStream.hpp b/include/Nazara/Core/InputStream.hpp index ae6ce3ee7..4db9be523 100644 --- a/include/Nazara/Core/InputStream.hpp +++ b/include/Nazara/Core/InputStream.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/LockGuard.hpp b/include/Nazara/Core/LockGuard.hpp index b73a30d84..394f13e2a 100644 --- a/include/Nazara/Core/LockGuard.hpp +++ b/include/Nazara/Core/LockGuard.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Log.hpp b/include/Nazara/Core/Log.hpp index 0348d2c10..458dc1b3d 100644 --- a/include/Nazara/Core/Log.hpp +++ b/include/Nazara/Core/Log.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/MemoryHelper.hpp b/include/Nazara/Core/MemoryHelper.hpp index 472f10f9d..1dafec898 100644 --- a/include/Nazara/Core/MemoryHelper.hpp +++ b/include/Nazara/Core/MemoryHelper.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/MemoryHelper.inl b/include/Nazara/Core/MemoryHelper.inl index 841f5d4c5..14a297fff 100644 --- a/include/Nazara/Core/MemoryHelper.inl +++ b/include/Nazara/Core/MemoryHelper.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/MemoryManager.hpp b/include/Nazara/Core/MemoryManager.hpp index 437e5c53b..a9481468d 100644 --- a/include/Nazara/Core/MemoryManager.hpp +++ b/include/Nazara/Core/MemoryManager.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/MemoryPool.hpp b/include/Nazara/Core/MemoryPool.hpp index 64efc4ccd..c53df3786 100644 --- a/include/Nazara/Core/MemoryPool.hpp +++ b/include/Nazara/Core/MemoryPool.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/Core/MemoryPool.inl b/include/Nazara/Core/MemoryPool.inl index 8e8034814..0ad5c3398 100644 --- a/include/Nazara/Core/MemoryPool.inl +++ b/include/Nazara/Core/MemoryPool.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/MemoryStream.hpp b/include/Nazara/Core/MemoryStream.hpp index 91e3d3390..0370d8465 100644 --- a/include/Nazara/Core/MemoryStream.hpp +++ b/include/Nazara/Core/MemoryStream.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Mutex.hpp b/include/Nazara/Core/Mutex.hpp index dc7adaf87..b34341836 100644 --- a/include/Nazara/Core/Mutex.hpp +++ b/include/Nazara/Core/Mutex.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/NonCopyable.hpp b/include/Nazara/Core/NonCopyable.hpp index aff4d3ce7..b6bc2ab2f 100644 --- a/include/Nazara/Core/NonCopyable.hpp +++ b/include/Nazara/Core/NonCopyable.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/OffsetOf.hpp b/include/Nazara/Core/OffsetOf.hpp index be3d7d79f..4f13abacf 100644 --- a/include/Nazara/Core/OffsetOf.hpp +++ b/include/Nazara/Core/OffsetOf.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/ParameterList.hpp b/include/Nazara/Core/ParameterList.hpp index f43979d9e..e8c3fb51c 100644 --- a/include/Nazara/Core/ParameterList.hpp +++ b/include/Nazara/Core/ParameterList.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/PluginManager.hpp b/include/Nazara/Core/PluginManager.hpp index 3f1ab6178..e4a1851b4 100644 --- a/include/Nazara/Core/PluginManager.hpp +++ b/include/Nazara/Core/PluginManager.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Primitive.hpp b/include/Nazara/Core/Primitive.hpp index f54a6a8c6..655a8fdab 100644 --- a/include/Nazara/Core/Primitive.hpp +++ b/include/Nazara/Core/Primitive.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Primitive.inl b/include/Nazara/Core/Primitive.inl index 6de686238..b27031f56 100644 --- a/include/Nazara/Core/Primitive.inl +++ b/include/Nazara/Core/Primitive.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/PrimitiveList.hpp b/include/Nazara/Core/PrimitiveList.hpp index 9894040dd..8a8b096aa 100644 --- a/include/Nazara/Core/PrimitiveList.hpp +++ b/include/Nazara/Core/PrimitiveList.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Resource.hpp b/include/Nazara/Core/Resource.hpp index 61cbafd1a..4be7cbaca 100644 --- a/include/Nazara/Core/Resource.hpp +++ b/include/Nazara/Core/Resource.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/ResourceListener.hpp b/include/Nazara/Core/ResourceListener.hpp index 821d17758..4a8a7747b 100644 --- a/include/Nazara/Core/ResourceListener.hpp +++ b/include/Nazara/Core/ResourceListener.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/ResourceLoader.hpp b/include/Nazara/Core/ResourceLoader.hpp index 83a3f8ce5..5242bfbf9 100644 --- a/include/Nazara/Core/ResourceLoader.hpp +++ b/include/Nazara/Core/ResourceLoader.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/ResourceLoader.inl b/include/Nazara/Core/ResourceLoader.inl index e716434d0..df0d2d7d9 100644 --- a/include/Nazara/Core/ResourceLoader.inl +++ b/include/Nazara/Core/ResourceLoader.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/ResourceRef.hpp b/include/Nazara/Core/ResourceRef.hpp index 9a5a7eba5..22c35a429 100644 --- a/include/Nazara/Core/ResourceRef.hpp +++ b/include/Nazara/Core/ResourceRef.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/ResourceRef.inl b/include/Nazara/Core/ResourceRef.inl index 0d4d42614..a223bcbdf 100644 --- a/include/Nazara/Core/ResourceRef.inl +++ b/include/Nazara/Core/ResourceRef.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Semaphore.hpp b/include/Nazara/Core/Semaphore.hpp index f09c4a3cb..2dd6f5ef5 100644 --- a/include/Nazara/Core/Semaphore.hpp +++ b/include/Nazara/Core/Semaphore.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/SparsePtr.hpp b/include/Nazara/Core/SparsePtr.hpp index b077b6d56..317d3f8b8 100644 --- a/include/Nazara/Core/SparsePtr.hpp +++ b/include/Nazara/Core/SparsePtr.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/Core/SparsePtr.inl b/include/Nazara/Core/SparsePtr.inl index 188996d4b..fbe48f727 100644 --- a/include/Nazara/Core/SparsePtr.inl +++ b/include/Nazara/Core/SparsePtr.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Stream.hpp b/include/Nazara/Core/Stream.hpp index 91ed88fa6..fa4aafe12 100644 --- a/include/Nazara/Core/Stream.hpp +++ b/include/Nazara/Core/Stream.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/String.hpp b/include/Nazara/Core/String.hpp index 73253fa95..b9be14585 100644 --- a/include/Nazara/Core/String.hpp +++ b/include/Nazara/Core/String.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/String.inl b/include/Nazara/Core/String.inl index ac922d99b..1224afa32 100644 --- a/include/Nazara/Core/String.inl +++ b/include/Nazara/Core/String.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/StringStream.hpp b/include/Nazara/Core/StringStream.hpp index 7807c9806..c3899f16b 100644 --- a/include/Nazara/Core/StringStream.hpp +++ b/include/Nazara/Core/StringStream.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/TaskScheduler.hpp b/include/Nazara/Core/TaskScheduler.hpp index 65fddbc79..1d34403e4 100644 --- a/include/Nazara/Core/TaskScheduler.hpp +++ b/include/Nazara/Core/TaskScheduler.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/TaskScheduler.inl b/include/Nazara/Core/TaskScheduler.inl index bbe33c9cf..ffef85de3 100644 --- a/include/Nazara/Core/TaskScheduler.inl +++ b/include/Nazara/Core/TaskScheduler.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Thread.hpp b/include/Nazara/Core/Thread.hpp index 088300118..bbf82c31b 100644 --- a/include/Nazara/Core/Thread.hpp +++ b/include/Nazara/Core/Thread.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Thread.inl b/include/Nazara/Core/Thread.inl index dc9aa46af..b057d770e 100644 --- a/include/Nazara/Core/Thread.inl +++ b/include/Nazara/Core/Thread.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/ThreadSafety.hpp b/include/Nazara/Core/ThreadSafety.hpp index 9a0d8e274..7eb5bbf0b 100644 --- a/include/Nazara/Core/ThreadSafety.hpp +++ b/include/Nazara/Core/ThreadSafety.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/ThreadSafetyOff.hpp b/include/Nazara/Core/ThreadSafetyOff.hpp index a77e0acaa..e6a1ce208 100644 --- a/include/Nazara/Core/ThreadSafetyOff.hpp +++ b/include/Nazara/Core/ThreadSafetyOff.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Tuple.hpp b/include/Nazara/Core/Tuple.hpp index 13a5a69e7..1626e5177 100644 --- a/include/Nazara/Core/Tuple.hpp +++ b/include/Nazara/Core/Tuple.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Tuple.inl b/include/Nazara/Core/Tuple.inl index db7e80b45..46c6b5753 100644 --- a/include/Nazara/Core/Tuple.inl +++ b/include/Nazara/Core/Tuple.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Unicode.hpp b/include/Nazara/Core/Unicode.hpp index 2a0d1f48f..bc086ee46 100644 --- a/include/Nazara/Core/Unicode.hpp +++ b/include/Nazara/Core/Unicode.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Core/Updatable.hpp b/include/Nazara/Core/Updatable.hpp index e4905a77b..540754caa 100644 --- a/include/Nazara/Core/Updatable.hpp +++ b/include/Nazara/Core/Updatable.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Graphics/AbstractBackground.hpp b/include/Nazara/Graphics/AbstractBackground.hpp index 00ded21f3..42471d504 100644 --- a/include/Nazara/Graphics/AbstractBackground.hpp +++ b/include/Nazara/Graphics/AbstractBackground.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/AbstractRenderQueue.hpp b/include/Nazara/Graphics/AbstractRenderQueue.hpp index 2003a1db6..367d6ec78 100644 --- a/include/Nazara/Graphics/AbstractRenderQueue.hpp +++ b/include/Nazara/Graphics/AbstractRenderQueue.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/AbstractRenderTechnique.hpp b/include/Nazara/Graphics/AbstractRenderTechnique.hpp index 66947bada..3cc22e30c 100644 --- a/include/Nazara/Graphics/AbstractRenderTechnique.hpp +++ b/include/Nazara/Graphics/AbstractRenderTechnique.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/AbstractViewer.hpp b/include/Nazara/Graphics/AbstractViewer.hpp index d6c3d5f3f..50ea34e24 100644 --- a/include/Nazara/Graphics/AbstractViewer.hpp +++ b/include/Nazara/Graphics/AbstractViewer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/Camera.hpp b/include/Nazara/Graphics/Camera.hpp index 3cdb0eb41..051db1bdb 100644 --- a/include/Nazara/Graphics/Camera.hpp +++ b/include/Nazara/Graphics/Camera.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/ColorBackground.hpp b/include/Nazara/Graphics/ColorBackground.hpp index c0fe76371..d2418289a 100644 --- a/include/Nazara/Graphics/ColorBackground.hpp +++ b/include/Nazara/Graphics/ColorBackground.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/Config.hpp b/include/Nazara/Graphics/Config.hpp index b09bace5e..1a51c5803 100644 --- a/include/Nazara/Graphics/Config.hpp +++ b/include/Nazara/Graphics/Config.hpp @@ -1,7 +1,7 @@ /* Nazara Engine - Graphics module - Copyright (C) 2014 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) + Copyright (C) 2015 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/include/Nazara/Graphics/ConfigCheck.hpp b/include/Nazara/Graphics/ConfigCheck.hpp index 8b46edaaf..98fee1840 100644 --- a/include/Nazara/Graphics/ConfigCheck.hpp +++ b/include/Nazara/Graphics/ConfigCheck.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/Debug.hpp b/include/Nazara/Graphics/Debug.hpp index 7902d36b1..1d048c131 100644 --- a/include/Nazara/Graphics/Debug.hpp +++ b/include/Nazara/Graphics/Debug.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/DebugOff.hpp b/include/Nazara/Graphics/DebugOff.hpp index 17972d2f0..38a452aab 100644 --- a/include/Nazara/Graphics/DebugOff.hpp +++ b/include/Nazara/Graphics/DebugOff.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/DeferredBloomPass.hpp b/include/Nazara/Graphics/DeferredBloomPass.hpp index e273ad530..ae6b2ff65 100644 --- a/include/Nazara/Graphics/DeferredBloomPass.hpp +++ b/include/Nazara/Graphics/DeferredBloomPass.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/DeferredDOFPass.hpp b/include/Nazara/Graphics/DeferredDOFPass.hpp index 81f3dae32..d5c7bd298 100644 --- a/include/Nazara/Graphics/DeferredDOFPass.hpp +++ b/include/Nazara/Graphics/DeferredDOFPass.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/DeferredFXAAPass.hpp b/include/Nazara/Graphics/DeferredFXAAPass.hpp index a12f7774e..662d89d5b 100644 --- a/include/Nazara/Graphics/DeferredFXAAPass.hpp +++ b/include/Nazara/Graphics/DeferredFXAAPass.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/DeferredFinalPass.hpp b/include/Nazara/Graphics/DeferredFinalPass.hpp index 84512b6ce..fb0990feb 100644 --- a/include/Nazara/Graphics/DeferredFinalPass.hpp +++ b/include/Nazara/Graphics/DeferredFinalPass.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/DeferredFogPass.hpp b/include/Nazara/Graphics/DeferredFogPass.hpp index 9a785b3e4..fd4e831e2 100644 --- a/include/Nazara/Graphics/DeferredFogPass.hpp +++ b/include/Nazara/Graphics/DeferredFogPass.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/DeferredForwardPass.hpp b/include/Nazara/Graphics/DeferredForwardPass.hpp index 94f99eaba..b0c561c93 100644 --- a/include/Nazara/Graphics/DeferredForwardPass.hpp +++ b/include/Nazara/Graphics/DeferredForwardPass.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/DeferredGeometryPass.hpp b/include/Nazara/Graphics/DeferredGeometryPass.hpp index 8f90f1609..11c238d53 100644 --- a/include/Nazara/Graphics/DeferredGeometryPass.hpp +++ b/include/Nazara/Graphics/DeferredGeometryPass.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/DeferredPhongLightingPass.hpp b/include/Nazara/Graphics/DeferredPhongLightingPass.hpp index 2b8f37ac1..94f53ec2a 100644 --- a/include/Nazara/Graphics/DeferredPhongLightingPass.hpp +++ b/include/Nazara/Graphics/DeferredPhongLightingPass.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/DeferredRenderPass.hpp b/include/Nazara/Graphics/DeferredRenderPass.hpp index 62f1cd339..a4dd5eaa5 100644 --- a/include/Nazara/Graphics/DeferredRenderPass.hpp +++ b/include/Nazara/Graphics/DeferredRenderPass.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/DeferredRenderQueue.hpp b/include/Nazara/Graphics/DeferredRenderQueue.hpp index dff95292c..cd403d174 100644 --- a/include/Nazara/Graphics/DeferredRenderQueue.hpp +++ b/include/Nazara/Graphics/DeferredRenderQueue.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/DeferredRenderTechnique.hpp b/include/Nazara/Graphics/DeferredRenderTechnique.hpp index 90f81fc46..1a5f2669c 100644 --- a/include/Nazara/Graphics/DeferredRenderTechnique.hpp +++ b/include/Nazara/Graphics/DeferredRenderTechnique.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/Drawable.hpp b/include/Nazara/Graphics/Drawable.hpp index 3c45939df..7ccfc936b 100644 --- a/include/Nazara/Graphics/Drawable.hpp +++ b/include/Nazara/Graphics/Drawable.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 a19507fb9..1e301ecb9 100644 --- a/include/Nazara/Graphics/Enums.hpp +++ b/include/Nazara/Graphics/Enums.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/ForwardRenderQueue.hpp b/include/Nazara/Graphics/ForwardRenderQueue.hpp index c1cbbdaf5..223ff5642 100644 --- a/include/Nazara/Graphics/ForwardRenderQueue.hpp +++ b/include/Nazara/Graphics/ForwardRenderQueue.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/ForwardRenderTechnique.hpp b/include/Nazara/Graphics/ForwardRenderTechnique.hpp index 59cbf47ea..27ada0354 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.hpp +++ b/include/Nazara/Graphics/ForwardRenderTechnique.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/Graphics.hpp b/include/Nazara/Graphics/Graphics.hpp index 169ed9dcd..adba47320 100644 --- a/include/Nazara/Graphics/Graphics.hpp +++ b/include/Nazara/Graphics/Graphics.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/Light.hpp b/include/Nazara/Graphics/Light.hpp index 4a53eed94..46655a260 100644 --- a/include/Nazara/Graphics/Light.hpp +++ b/include/Nazara/Graphics/Light.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/LightManager.hpp b/include/Nazara/Graphics/LightManager.hpp index 2796084dc..939421cae 100644 --- a/include/Nazara/Graphics/LightManager.hpp +++ b/include/Nazara/Graphics/LightManager.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/Material.hpp b/include/Nazara/Graphics/Material.hpp index 1e5692c70..65b08d007 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/Model.hpp b/include/Nazara/Graphics/Model.hpp index 3249cdd48..a9f0ac172 100644 --- a/include/Nazara/Graphics/Model.hpp +++ b/include/Nazara/Graphics/Model.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/ParticleController.hpp b/include/Nazara/Graphics/ParticleController.hpp index 2794a32ba..8bfebd813 100644 --- a/include/Nazara/Graphics/ParticleController.hpp +++ b/include/Nazara/Graphics/ParticleController.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/ParticleDeclaration.hpp b/include/Nazara/Graphics/ParticleDeclaration.hpp index f32413054..5410e1ccb 100644 --- a/include/Nazara/Graphics/ParticleDeclaration.hpp +++ b/include/Nazara/Graphics/ParticleDeclaration.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/ParticleEmitter.hpp b/include/Nazara/Graphics/ParticleEmitter.hpp index 6298c196c..b8bb32deb 100644 --- a/include/Nazara/Graphics/ParticleEmitter.hpp +++ b/include/Nazara/Graphics/ParticleEmitter.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/ParticleGenerator.hpp b/include/Nazara/Graphics/ParticleGenerator.hpp index 5091014db..973be66d3 100644 --- a/include/Nazara/Graphics/ParticleGenerator.hpp +++ b/include/Nazara/Graphics/ParticleGenerator.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/ParticleMapper.hpp b/include/Nazara/Graphics/ParticleMapper.hpp index ac4b8dccf..9fb4e7102 100644 --- a/include/Nazara/Graphics/ParticleMapper.hpp +++ b/include/Nazara/Graphics/ParticleMapper.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/ParticleMapper.inl b/include/Nazara/Graphics/ParticleMapper.inl index b2dfdc1b2..07f974ad8 100644 --- a/include/Nazara/Graphics/ParticleMapper.inl +++ b/include/Nazara/Graphics/ParticleMapper.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/ParticleRenderer.hpp b/include/Nazara/Graphics/ParticleRenderer.hpp index 0871bc549..be66d18c6 100644 --- a/include/Nazara/Graphics/ParticleRenderer.hpp +++ b/include/Nazara/Graphics/ParticleRenderer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/ParticleStruct.hpp b/include/Nazara/Graphics/ParticleStruct.hpp index d023b1470..7c478b812 100644 --- a/include/Nazara/Graphics/ParticleStruct.hpp +++ b/include/Nazara/Graphics/ParticleStruct.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/ParticleSystem.hpp b/include/Nazara/Graphics/ParticleSystem.hpp index 7537da429..f81c42c2e 100644 --- a/include/Nazara/Graphics/ParticleSystem.hpp +++ b/include/Nazara/Graphics/ParticleSystem.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/RenderTechniques.hpp b/include/Nazara/Graphics/RenderTechniques.hpp index 63f9ad3ac..0821e3f51 100644 --- a/include/Nazara/Graphics/RenderTechniques.hpp +++ b/include/Nazara/Graphics/RenderTechniques.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/Scene.hpp b/include/Nazara/Graphics/Scene.hpp index 8a9b1b89c..6dbe5250e 100644 --- a/include/Nazara/Graphics/Scene.hpp +++ b/include/Nazara/Graphics/Scene.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/SceneLayer.hpp b/include/Nazara/Graphics/SceneLayer.hpp index 20fe359a2..20046057e 100644 --- a/include/Nazara/Graphics/SceneLayer.hpp +++ b/include/Nazara/Graphics/SceneLayer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/SceneNode.hpp b/include/Nazara/Graphics/SceneNode.hpp index edfdf56e2..47a977c8a 100644 --- a/include/Nazara/Graphics/SceneNode.hpp +++ b/include/Nazara/Graphics/SceneNode.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/SceneRoot.hpp b/include/Nazara/Graphics/SceneRoot.hpp index 7b81fd5ac..41935cf94 100644 --- a/include/Nazara/Graphics/SceneRoot.hpp +++ b/include/Nazara/Graphics/SceneRoot.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/SkeletalModel.hpp b/include/Nazara/Graphics/SkeletalModel.hpp index 7938ba4c4..82b0c69a9 100644 --- a/include/Nazara/Graphics/SkeletalModel.hpp +++ b/include/Nazara/Graphics/SkeletalModel.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/SkinningManager.hpp b/include/Nazara/Graphics/SkinningManager.hpp index 5b015c066..550fddc9a 100644 --- a/include/Nazara/Graphics/SkinningManager.hpp +++ b/include/Nazara/Graphics/SkinningManager.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/SkyboxBackground.hpp b/include/Nazara/Graphics/SkyboxBackground.hpp index 6815dbc3a..97bc164c9 100644 --- a/include/Nazara/Graphics/SkyboxBackground.hpp +++ b/include/Nazara/Graphics/SkyboxBackground.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/Sprite.hpp b/include/Nazara/Graphics/Sprite.hpp index b3739cb07..b9b60dad2 100644 --- a/include/Nazara/Graphics/Sprite.hpp +++ b/include/Nazara/Graphics/Sprite.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/TextSprite.hpp b/include/Nazara/Graphics/TextSprite.hpp index 40e323d98..482eaf392 100644 --- a/include/Nazara/Graphics/TextSprite.hpp +++ b/include/Nazara/Graphics/TextSprite.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/TextureBackground.hpp b/include/Nazara/Graphics/TextureBackground.hpp index 707d70c14..e20ac25a2 100644 --- a/include/Nazara/Graphics/TextureBackground.hpp +++ b/include/Nazara/Graphics/TextureBackground.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/View.hpp b/include/Nazara/Graphics/View.hpp index b7f016afc..1c3f073e5 100644 --- a/include/Nazara/Graphics/View.hpp +++ b/include/Nazara/Graphics/View.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/Lua/Config.hpp b/include/Nazara/Lua/Config.hpp index 7a4440231..9e7563345 100644 --- a/include/Nazara/Lua/Config.hpp +++ b/include/Nazara/Lua/Config.hpp @@ -1,7 +1,7 @@ /* Nazara Engine - Lua scripting module - Copyright (C) 2014 Jérôme Leclercq (lynix680@gmail.com) + Copyright (C) 2015 Jérôme Leclercq (lynix680@gmail.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/include/Nazara/Lua/ConfigCheck.hpp b/include/Nazara/Lua/ConfigCheck.hpp index 21d39454d..246fe1d52 100644 --- a/include/Nazara/Lua/ConfigCheck.hpp +++ b/include/Nazara/Lua/ConfigCheck.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Lua module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Lua/Debug.hpp b/include/Nazara/Lua/Debug.hpp index 4d6e67953..8cfefe4fc 100644 --- a/include/Nazara/Lua/Debug.hpp +++ b/include/Nazara/Lua/Debug.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Lua/DebugOff.hpp b/include/Nazara/Lua/DebugOff.hpp index 6d9271835..3609f245d 100644 --- a/include/Nazara/Lua/DebugOff.hpp +++ b/include/Nazara/Lua/DebugOff.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Lua/Enums.hpp b/include/Nazara/Lua/Enums.hpp index 251887ade..8e54ed526 100644 --- a/include/Nazara/Lua/Enums.hpp +++ b/include/Nazara/Lua/Enums.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Lua/Lua.hpp b/include/Nazara/Lua/Lua.hpp index 95c42b1c3..3defd0c5f 100644 --- a/include/Nazara/Lua/Lua.hpp +++ b/include/Nazara/Lua/Lua.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Lua/LuaClass.hpp b/include/Nazara/Lua/LuaClass.hpp index bb75569fe..85cad0162 100644 --- a/include/Nazara/Lua/LuaClass.hpp +++ b/include/Nazara/Lua/LuaClass.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Lua/LuaClass.inl b/include/Nazara/Lua/LuaClass.inl index 79c8a88ce..3f5e68c25 100644 --- a/include/Nazara/Lua/LuaClass.inl +++ b/include/Nazara/Lua/LuaClass.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Lua/LuaInstance.hpp b/include/Nazara/Lua/LuaInstance.hpp index a7d530c6a..f18c2dde8 100644 --- a/include/Nazara/Lua/LuaInstance.hpp +++ b/include/Nazara/Lua/LuaInstance.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Algorithm.hpp b/include/Nazara/Math/Algorithm.hpp index c4420f621..a842c1df8 100644 --- a/include/Nazara/Math/Algorithm.hpp +++ b/include/Nazara/Math/Algorithm.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Algorithm.inl b/include/Nazara/Math/Algorithm.inl index c85a6ae4f..8a1a0b91e 100644 --- a/include/Nazara/Math/Algorithm.inl +++ b/include/Nazara/Math/Algorithm.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/BoundingVolume.hpp b/include/Nazara/Math/BoundingVolume.hpp index 999bfdd6a..1d0521d72 100644 --- a/include/Nazara/Math/BoundingVolume.hpp +++ b/include/Nazara/Math/BoundingVolume.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/BoundingVolume.inl b/include/Nazara/Math/BoundingVolume.inl index 71c0c2cea..ad8fc9415 100644 --- a/include/Nazara/Math/BoundingVolume.inl +++ b/include/Nazara/Math/BoundingVolume.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Box.hpp b/include/Nazara/Math/Box.hpp index 1705f25df..6b5e5d565 100644 --- a/include/Nazara/Math/Box.hpp +++ b/include/Nazara/Math/Box.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Box.inl b/include/Nazara/Math/Box.inl index 11578f605..b7873d064 100644 --- a/include/Nazara/Math/Box.inl +++ b/include/Nazara/Math/Box.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Config.hpp b/include/Nazara/Math/Config.hpp index dd5f70041..f265fdd52 100644 --- a/include/Nazara/Math/Config.hpp +++ b/include/Nazara/Math/Config.hpp @@ -1,7 +1,7 @@ /* Nazara Engine - Mathematics module - Copyright (C) 2014 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) + Copyright (C) 2015 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) Rémi "overdrivr" Bèges (remi.beges@laposte.net) Permission is hereby granted, free of charge, to any person obtaining a copy of diff --git a/include/Nazara/Math/Enums.hpp b/include/Nazara/Math/Enums.hpp index 214c9958c..496615b9e 100644 --- a/include/Nazara/Math/Enums.hpp +++ b/include/Nazara/Math/Enums.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/EulerAngles.hpp b/include/Nazara/Math/EulerAngles.hpp index 73f86e25f..41030d7be 100644 --- a/include/Nazara/Math/EulerAngles.hpp +++ b/include/Nazara/Math/EulerAngles.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/EulerAngles.inl b/include/Nazara/Math/EulerAngles.inl index d92821189..8e29a40d9 100644 --- a/include/Nazara/Math/EulerAngles.inl +++ b/include/Nazara/Math/EulerAngles.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Frustum.hpp b/include/Nazara/Math/Frustum.hpp index f94c229b0..e28949f46 100644 --- a/include/Nazara/Math/Frustum.hpp +++ b/include/Nazara/Math/Frustum.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Frustum.inl b/include/Nazara/Math/Frustum.inl index 336f5ad0a..fbdbdbdcc 100644 --- a/include/Nazara/Math/Frustum.inl +++ b/include/Nazara/Math/Frustum.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Matrix4.hpp b/include/Nazara/Math/Matrix4.hpp index 9f53bd227..ac142f4f1 100644 --- a/include/Nazara/Math/Matrix4.hpp +++ b/include/Nazara/Math/Matrix4.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index 89363a31e..d689879d0 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/OrientedBox.hpp b/include/Nazara/Math/OrientedBox.hpp index b6ea75fd7..1631099aa 100644 --- a/include/Nazara/Math/OrientedBox.hpp +++ b/include/Nazara/Math/OrientedBox.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/OrientedBox.inl b/include/Nazara/Math/OrientedBox.inl index 8d242d52e..c83aee440 100644 --- a/include/Nazara/Math/OrientedBox.inl +++ b/include/Nazara/Math/OrientedBox.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Plane.hpp b/include/Nazara/Math/Plane.hpp index b816ae195..f2c428bde 100644 --- a/include/Nazara/Math/Plane.hpp +++ b/include/Nazara/Math/Plane.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Plane.inl b/include/Nazara/Math/Plane.inl index b87464bc7..10ece793d 100644 --- a/include/Nazara/Math/Plane.inl +++ b/include/Nazara/Math/Plane.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Quaternion.hpp b/include/Nazara/Math/Quaternion.hpp index 35e6a7b65..03b27c02a 100644 --- a/include/Nazara/Math/Quaternion.hpp +++ b/include/Nazara/Math/Quaternion.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges - Jérôme Leclercq +// Copyright (C) 2015 Rémi Bèges - Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Quaternion.inl b/include/Nazara/Math/Quaternion.inl index e62ed166f..9d498b5c6 100644 --- a/include/Nazara/Math/Quaternion.inl +++ b/include/Nazara/Math/Quaternion.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges - Jérôme Leclercq +// Copyright (C) 2015 Rémi Bèges - Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Ray.hpp b/include/Nazara/Math/Ray.hpp index d47663e88..e1cc40829 100644 --- a/include/Nazara/Math/Ray.hpp +++ b/include/Nazara/Math/Ray.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Gawaboumga (https://github.com/Gawaboumga) - Jérôme Leclercq +// Copyright (C) 2015 Gawaboumga (https://github.com/Gawaboumga) - Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Ray.inl b/include/Nazara/Math/Ray.inl index 900ec2bbf..035a7bc06 100644 --- a/include/Nazara/Math/Ray.inl +++ b/include/Nazara/Math/Ray.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Gawaboumga (https://github.com/Gawaboumga) - Jérôme Leclercq +// Copyright (C) 2015 Gawaboumga (https://github.com/Gawaboumga) - Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Rect.hpp b/include/Nazara/Math/Rect.hpp index 424d69079..cb93b2167 100644 --- a/include/Nazara/Math/Rect.hpp +++ b/include/Nazara/Math/Rect.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Rect.inl b/include/Nazara/Math/Rect.inl index 5cee6602d..9782ac69e 100644 --- a/include/Nazara/Math/Rect.inl +++ b/include/Nazara/Math/Rect.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Sphere.hpp b/include/Nazara/Math/Sphere.hpp index 64378a949..f452ddf4e 100644 --- a/include/Nazara/Math/Sphere.hpp +++ b/include/Nazara/Math/Sphere.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Sphere.inl b/include/Nazara/Math/Sphere.inl index c85f12000..f8ece724c 100644 --- a/include/Nazara/Math/Sphere.inl +++ b/include/Nazara/Math/Sphere.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Vector2.hpp b/include/Nazara/Math/Vector2.hpp index 53850c631..c42700de5 100644 --- a/include/Nazara/Math/Vector2.hpp +++ b/include/Nazara/Math/Vector2.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Vector2.inl b/include/Nazara/Math/Vector2.inl index 72842ad3b..05a7ae792 100644 --- a/include/Nazara/Math/Vector2.inl +++ b/include/Nazara/Math/Vector2.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Vector3.hpp b/include/Nazara/Math/Vector3.hpp index e8fe8f7d0..14cd41b0a 100644 --- a/include/Nazara/Math/Vector3.hpp +++ b/include/Nazara/Math/Vector3.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges - Jérôme Leclercq +// Copyright (C) 2015 Rémi Bèges - Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index d35988319..a2f0ed35c 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges - Jérôme Leclercq +// Copyright (C) 2015 Rémi Bèges - Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Vector4.hpp b/include/Nazara/Math/Vector4.hpp index 7bad9b918..d4620a64a 100644 --- a/include/Nazara/Math/Vector4.hpp +++ b/include/Nazara/Math/Vector4.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges - Jérôme Leclercq +// Copyright (C) 2015 Rémi Bèges - Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Math/Vector4.inl b/include/Nazara/Math/Vector4.inl index 518dda2c2..fdef535a7 100644 --- a/include/Nazara/Math/Vector4.inl +++ b/include/Nazara/Math/Vector4.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges - Jérôme Leclercq +// Copyright (C) 2015 Rémi Bèges - Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/Abstract2DNoise.hpp b/include/Nazara/Noise/Abstract2DNoise.hpp index 6ee7c551a..b472c36b3 100644 --- a/include/Nazara/Noise/Abstract2DNoise.hpp +++ b/include/Nazara/Noise/Abstract2DNoise.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/Abstract3DNoise.hpp b/include/Nazara/Noise/Abstract3DNoise.hpp index 9ca263e8b..f40ec770e 100644 --- a/include/Nazara/Noise/Abstract3DNoise.hpp +++ b/include/Nazara/Noise/Abstract3DNoise.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/Abstract4DNoise.hpp b/include/Nazara/Noise/Abstract4DNoise.hpp index 66192420b..a9ba2a8b7 100644 --- a/include/Nazara/Noise/Abstract4DNoise.hpp +++ b/include/Nazara/Noise/Abstract4DNoise.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/ComplexNoiseBase.hpp b/include/Nazara/Noise/ComplexNoiseBase.hpp index 649655a16..528ab5582 100644 --- a/include/Nazara/Noise/ComplexNoiseBase.hpp +++ b/include/Nazara/Noise/ComplexNoiseBase.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/Config.hpp b/include/Nazara/Noise/Config.hpp index c9a033f1b..29b7c647a 100644 --- a/include/Nazara/Noise/Config.hpp +++ b/include/Nazara/Noise/Config.hpp @@ -1,7 +1,7 @@ /* Nazara Engine - Noise module - Copyright (C) 2014 Rémi "Overdrivr" Bèges (remi.beges@laposte.net) + Copyright (C) 2015 Rémi "Overdrivr" Bèges (remi.beges@laposte.net) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/include/Nazara/Noise/ConfigCheck.hpp b/include/Nazara/Noise/ConfigCheck.hpp index 3cad1d19a..04bbcdeeb 100644 --- a/include/Nazara/Noise/ConfigCheck.hpp +++ b/include/Nazara/Noise/ConfigCheck.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/Debug.hpp b/include/Nazara/Noise/Debug.hpp index c47777ba1..377ae7b1c 100644 --- a/include/Nazara/Noise/Debug.hpp +++ b/include/Nazara/Noise/Debug.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/DebugOff.hpp b/include/Nazara/Noise/DebugOff.hpp index 9993f1d15..75903b6cc 100644 --- a/include/Nazara/Noise/DebugOff.hpp +++ b/include/Nazara/Noise/DebugOff.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/FBM2D.hpp b/include/Nazara/Noise/FBM2D.hpp index 6e17b9f50..4ffade2c8 100644 --- a/include/Nazara/Noise/FBM2D.hpp +++ b/include/Nazara/Noise/FBM2D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/FBM3D.hpp b/include/Nazara/Noise/FBM3D.hpp index e856cb3cb..985c0c777 100644 --- a/include/Nazara/Noise/FBM3D.hpp +++ b/include/Nazara/Noise/FBM3D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/FBM4D.hpp b/include/Nazara/Noise/FBM4D.hpp index 9367167ef..e79f83c4a 100644 --- a/include/Nazara/Noise/FBM4D.hpp +++ b/include/Nazara/Noise/FBM4D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/HybridMultiFractal3D.hpp b/include/Nazara/Noise/HybridMultiFractal3D.hpp index 4578b0951..615a3b9a1 100644 --- a/include/Nazara/Noise/HybridMultiFractal3D.hpp +++ b/include/Nazara/Noise/HybridMultiFractal3D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/HybridMultiFractal4D.hpp b/include/Nazara/Noise/HybridMultiFractal4D.hpp index f52ab9ee4..8d27df096 100644 --- a/include/Nazara/Noise/HybridMultiFractal4D.hpp +++ b/include/Nazara/Noise/HybridMultiFractal4D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/HybridMultifractal2D.hpp b/include/Nazara/Noise/HybridMultifractal2D.hpp index 831a9429d..9ed2d0b2a 100644 --- a/include/Nazara/Noise/HybridMultifractal2D.hpp +++ b/include/Nazara/Noise/HybridMultifractal2D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/MappedNoiseBase.hpp b/include/Nazara/Noise/MappedNoiseBase.hpp index 9c61acfb6..62a1f9fc5 100644 --- a/include/Nazara/Noise/MappedNoiseBase.hpp +++ b/include/Nazara/Noise/MappedNoiseBase.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/Noise.hpp b/include/Nazara/Noise/Noise.hpp index 0a2f53dec..ea7cc91a3 100644 --- a/include/Nazara/Noise/Noise.hpp +++ b/include/Nazara/Noise/Noise.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/NoiseBase.hpp b/include/Nazara/Noise/NoiseBase.hpp index a108d20dd..76c2c4315 100644 --- a/include/Nazara/Noise/NoiseBase.hpp +++ b/include/Nazara/Noise/NoiseBase.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/Perlin2D.hpp b/include/Nazara/Noise/Perlin2D.hpp index fb9022e82..e719a3870 100644 --- a/include/Nazara/Noise/Perlin2D.hpp +++ b/include/Nazara/Noise/Perlin2D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/Perlin3D.hpp b/include/Nazara/Noise/Perlin3D.hpp index c1b4e97db..e487a49fc 100644 --- a/include/Nazara/Noise/Perlin3D.hpp +++ b/include/Nazara/Noise/Perlin3D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/Perlin4D.hpp b/include/Nazara/Noise/Perlin4D.hpp index 66a436149..90ec5a92e 100644 --- a/include/Nazara/Noise/Perlin4D.hpp +++ b/include/Nazara/Noise/Perlin4D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/Simplex2D.hpp b/include/Nazara/Noise/Simplex2D.hpp index 33e77fd4d..8b44a5a11 100644 --- a/include/Nazara/Noise/Simplex2D.hpp +++ b/include/Nazara/Noise/Simplex2D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/Simplex3D.hpp b/include/Nazara/Noise/Simplex3D.hpp index 9d9042f1f..b2257c063 100644 --- a/include/Nazara/Noise/Simplex3D.hpp +++ b/include/Nazara/Noise/Simplex3D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/Simplex4D.hpp b/include/Nazara/Noise/Simplex4D.hpp index a9b87fa87..3415e16cb 100644 --- a/include/Nazara/Noise/Simplex4D.hpp +++ b/include/Nazara/Noise/Simplex4D.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Physics/Config.hpp b/include/Nazara/Physics/Config.hpp index 3f10a9aad..06d30e383 100644 --- a/include/Nazara/Physics/Config.hpp +++ b/include/Nazara/Physics/Config.hpp @@ -1,7 +1,7 @@ /* Nazara Engine - Physics module - Copyright (C) 2014 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) + Copyright (C) 2015 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/include/Nazara/Physics/ConfigCheck.hpp b/include/Nazara/Physics/ConfigCheck.hpp index 037b6d0ec..3ec7c9599 100644 --- a/include/Nazara/Physics/ConfigCheck.hpp +++ b/include/Nazara/Physics/ConfigCheck.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Physics/Debug.hpp b/include/Nazara/Physics/Debug.hpp index f5ac12a54..c97bc63f7 100644 --- a/include/Nazara/Physics/Debug.hpp +++ b/include/Nazara/Physics/Debug.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Physics/DebugOff.hpp b/include/Nazara/Physics/DebugOff.hpp index b22910c3b..6e6dd97a4 100644 --- a/include/Nazara/Physics/DebugOff.hpp +++ b/include/Nazara/Physics/DebugOff.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Physics/Enums.hpp b/include/Nazara/Physics/Enums.hpp index 090ccde97..defbdae19 100644 --- a/include/Nazara/Physics/Enums.hpp +++ b/include/Nazara/Physics/Enums.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Physics/Geom.hpp b/include/Nazara/Physics/Geom.hpp index 85522ba55..5c851ee30 100644 --- a/include/Nazara/Physics/Geom.hpp +++ b/include/Nazara/Physics/Geom.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Physics/PhysObject.hpp b/include/Nazara/Physics/PhysObject.hpp index c395f176e..10e0bece9 100644 --- a/include/Nazara/Physics/PhysObject.hpp +++ b/include/Nazara/Physics/PhysObject.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Physics/PhysWorld.hpp b/include/Nazara/Physics/PhysWorld.hpp index 80071da32..7069ff412 100644 --- a/include/Nazara/Physics/PhysWorld.hpp +++ b/include/Nazara/Physics/PhysWorld.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Physics/Physics.hpp b/include/Nazara/Physics/Physics.hpp index 7a0e73aec..c4da3db7f 100644 --- a/include/Nazara/Physics/Physics.hpp +++ b/include/Nazara/Physics/Physics.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Prerequesites.hpp b/include/Nazara/Prerequesites.hpp index 04fa0b48b..ac58d90ea 100644 --- a/include/Nazara/Prerequesites.hpp +++ b/include/Nazara/Prerequesites.hpp @@ -1,7 +1,7 @@ /* Nazara Engine - Copyright (C) 2014 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) + Copyright (C) 2015 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/include/Nazara/Renderer/Config.hpp b/include/Nazara/Renderer/Config.hpp index 0e5b08fc7..eb9bf3d7f 100644 --- a/include/Nazara/Renderer/Config.hpp +++ b/include/Nazara/Renderer/Config.hpp @@ -1,7 +1,7 @@ /* Nazara Engine - Renderer module - Copyright (C) 2014 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) + Copyright (C) 2015 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/include/Nazara/Renderer/ConfigCheck.hpp b/include/Nazara/Renderer/ConfigCheck.hpp index 9e362d5ed..3860a809b 100644 --- a/include/Nazara/Renderer/ConfigCheck.hpp +++ b/include/Nazara/Renderer/ConfigCheck.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/Renderer/Context.hpp b/include/Nazara/Renderer/Context.hpp index 99e722cba..a8bce8c94 100644 --- a/include/Nazara/Renderer/Context.hpp +++ b/include/Nazara/Renderer/Context.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/ContextParameters.hpp b/include/Nazara/Renderer/ContextParameters.hpp index c7c80de9b..5e344778c 100644 --- a/include/Nazara/Renderer/ContextParameters.hpp +++ b/include/Nazara/Renderer/ContextParameters.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/Debug.hpp b/include/Nazara/Renderer/Debug.hpp index 2d30c585b..ef0e73147 100644 --- a/include/Nazara/Renderer/Debug.hpp +++ b/include/Nazara/Renderer/Debug.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/DebugDrawer.hpp b/include/Nazara/Renderer/DebugDrawer.hpp index 1bb055c37..cb1ae2953 100644 --- a/include/Nazara/Renderer/DebugDrawer.hpp +++ b/include/Nazara/Renderer/DebugDrawer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/DebugOff.hpp b/include/Nazara/Renderer/DebugOff.hpp index 031da1959..b20650b99 100644 --- a/include/Nazara/Renderer/DebugOff.hpp +++ b/include/Nazara/Renderer/DebugOff.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/Enums.hpp b/include/Nazara/Renderer/Enums.hpp index 2a1959a46..d20b6dd87 100644 --- a/include/Nazara/Renderer/Enums.hpp +++ b/include/Nazara/Renderer/Enums.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/GpuQuery.hpp b/include/Nazara/Renderer/GpuQuery.hpp index 76dc4d46f..bd792b979 100644 --- a/include/Nazara/Renderer/GpuQuery.hpp +++ b/include/Nazara/Renderer/GpuQuery.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/OpenGL.hpp b/include/Nazara/Renderer/OpenGL.hpp index 8aa5a438d..08079582a 100644 --- a/include/Nazara/Renderer/OpenGL.hpp +++ b/include/Nazara/Renderer/OpenGL.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/RenderBuffer.hpp b/include/Nazara/Renderer/RenderBuffer.hpp index d3a038e41..5ca4ec3f3 100644 --- a/include/Nazara/Renderer/RenderBuffer.hpp +++ b/include/Nazara/Renderer/RenderBuffer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/RenderStates.hpp b/include/Nazara/Renderer/RenderStates.hpp index 3ae14d6d6..15d796afb 100644 --- a/include/Nazara/Renderer/RenderStates.hpp +++ b/include/Nazara/Renderer/RenderStates.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/RenderStates.inl b/include/Nazara/Renderer/RenderStates.inl index 26f60c8cd..8a7f188da 100644 --- a/include/Nazara/Renderer/RenderStates.inl +++ b/include/Nazara/Renderer/RenderStates.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/RenderTarget.hpp b/include/Nazara/Renderer/RenderTarget.hpp index b04edd177..b9f5643ad 100644 --- a/include/Nazara/Renderer/RenderTarget.hpp +++ b/include/Nazara/Renderer/RenderTarget.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/RenderTargetParameters.hpp b/include/Nazara/Renderer/RenderTargetParameters.hpp index 57e7071ad..cd8a4ab0a 100644 --- a/include/Nazara/Renderer/RenderTargetParameters.hpp +++ b/include/Nazara/Renderer/RenderTargetParameters.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/RenderTexture.hpp b/include/Nazara/Renderer/RenderTexture.hpp index 0e1dc5b65..5bd6c8565 100644 --- a/include/Nazara/Renderer/RenderTexture.hpp +++ b/include/Nazara/Renderer/RenderTexture.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/RenderWindow.hpp b/include/Nazara/Renderer/RenderWindow.hpp index 141b2590e..41c2e6412 100644 --- a/include/Nazara/Renderer/RenderWindow.hpp +++ b/include/Nazara/Renderer/RenderWindow.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/Renderer.hpp b/include/Nazara/Renderer/Renderer.hpp index 42832c661..2b5625ea2 100644 --- a/include/Nazara/Renderer/Renderer.hpp +++ b/include/Nazara/Renderer/Renderer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/Shader.hpp b/include/Nazara/Renderer/Shader.hpp index edf5f6582..5aaae7f54 100644 --- a/include/Nazara/Renderer/Shader.hpp +++ b/include/Nazara/Renderer/Shader.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/ShaderLibrary.hpp b/include/Nazara/Renderer/ShaderLibrary.hpp index bc1d6b1ce..859be77af 100644 --- a/include/Nazara/Renderer/ShaderLibrary.hpp +++ b/include/Nazara/Renderer/ShaderLibrary.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/ShaderStage.hpp b/include/Nazara/Renderer/ShaderStage.hpp index c5ecac17a..adb1f7f2c 100644 --- a/include/Nazara/Renderer/ShaderStage.hpp +++ b/include/Nazara/Renderer/ShaderStage.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/Texture.hpp b/include/Nazara/Renderer/Texture.hpp index fb23834bd..c9d93a2be 100644 --- a/include/Nazara/Renderer/Texture.hpp +++ b/include/Nazara/Renderer/Texture.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/TextureSampler.hpp b/include/Nazara/Renderer/TextureSampler.hpp index 61dd5a17d..6eefb8793 100644 --- a/include/Nazara/Renderer/TextureSampler.hpp +++ b/include/Nazara/Renderer/TextureSampler.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/UberShader.hpp b/include/Nazara/Renderer/UberShader.hpp index 2582b6b4f..b99ef33b6 100644 --- a/include/Nazara/Renderer/UberShader.hpp +++ b/include/Nazara/Renderer/UberShader.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/UberShaderInstance.hpp b/include/Nazara/Renderer/UberShaderInstance.hpp index 1720a5f79..c42020d19 100644 --- a/include/Nazara/Renderer/UberShaderInstance.hpp +++ b/include/Nazara/Renderer/UberShaderInstance.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/UberShaderInstancePreprocessor.hpp b/include/Nazara/Renderer/UberShaderInstancePreprocessor.hpp index 4f1b09f08..2bbeb8d49 100644 --- a/include/Nazara/Renderer/UberShaderInstancePreprocessor.hpp +++ b/include/Nazara/Renderer/UberShaderInstancePreprocessor.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/UberShaderLibrary.hpp b/include/Nazara/Renderer/UberShaderLibrary.hpp index 8561d809d..8a52da284 100644 --- a/include/Nazara/Renderer/UberShaderLibrary.hpp +++ b/include/Nazara/Renderer/UberShaderLibrary.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Renderer/UberShaderPreprocessor.hpp b/include/Nazara/Renderer/UberShaderPreprocessor.hpp index 0aa7679ac..83ae69b3d 100644 --- a/include/Nazara/Renderer/UberShaderPreprocessor.hpp +++ b/include/Nazara/Renderer/UberShaderPreprocessor.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Utility/AbstractBuffer.hpp b/include/Nazara/Utility/AbstractBuffer.hpp index e8c7a47db..bb05c2cca 100644 --- a/include/Nazara/Utility/AbstractBuffer.hpp +++ b/include/Nazara/Utility/AbstractBuffer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/Algorithm.hpp b/include/Nazara/Utility/Algorithm.hpp index 37d4a5705..72306ce90 100644 --- a/include/Nazara/Utility/Algorithm.hpp +++ b/include/Nazara/Utility/Algorithm.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/Algorithm.inl b/include/Nazara/Utility/Algorithm.inl index 0fb69cf93..93664c35e 100644 --- a/include/Nazara/Utility/Algorithm.inl +++ b/include/Nazara/Utility/Algorithm.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/Animation.hpp b/include/Nazara/Utility/Animation.hpp index 72a78db98..f2b18897c 100644 --- a/include/Nazara/Utility/Animation.hpp +++ b/include/Nazara/Utility/Animation.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/Buffer.hpp b/include/Nazara/Utility/Buffer.hpp index def55d0c4..f8dc70b0a 100644 --- a/include/Nazara/Utility/Buffer.hpp +++ b/include/Nazara/Utility/Buffer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/BufferMapper.hpp b/include/Nazara/Utility/BufferMapper.hpp index 546f2cdb0..814d78f8b 100644 --- a/include/Nazara/Utility/BufferMapper.hpp +++ b/include/Nazara/Utility/BufferMapper.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/BufferMapper.inl b/include/Nazara/Utility/BufferMapper.inl index 758a60ca8..1f6499c85 100644 --- a/include/Nazara/Utility/BufferMapper.inl +++ b/include/Nazara/Utility/BufferMapper.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/Config.hpp b/include/Nazara/Utility/Config.hpp index a05568d2f..6eae437b9 100644 --- a/include/Nazara/Utility/Config.hpp +++ b/include/Nazara/Utility/Config.hpp @@ -1,7 +1,7 @@ /* Nazara Engine - Utility module - Copyright (C) 2014 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) + Copyright (C) 2015 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/include/Nazara/Utility/ConfigCheck.hpp b/include/Nazara/Utility/ConfigCheck.hpp index 85379eba1..b4c976edc 100644 --- a/include/Nazara/Utility/ConfigCheck.hpp +++ b/include/Nazara/Utility/ConfigCheck.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/CubemapParams.hpp b/include/Nazara/Utility/CubemapParams.hpp index 760782acf..a9e82e299 100644 --- a/include/Nazara/Utility/CubemapParams.hpp +++ b/include/Nazara/Utility/CubemapParams.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/Cursor.hpp b/include/Nazara/Utility/Cursor.hpp index a3a3015e4..884bd04ab 100644 --- a/include/Nazara/Utility/Cursor.hpp +++ b/include/Nazara/Utility/Cursor.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/Debug.hpp b/include/Nazara/Utility/Debug.hpp index d5ae45202..85319685a 100644 --- a/include/Nazara/Utility/Debug.hpp +++ b/include/Nazara/Utility/Debug.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/DebugOff.hpp b/include/Nazara/Utility/DebugOff.hpp index 177f4e29a..5cb9a0750 100644 --- a/include/Nazara/Utility/DebugOff.hpp +++ b/include/Nazara/Utility/DebugOff.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/Enums.hpp b/include/Nazara/Utility/Enums.hpp index ac056a41b..49d66c2af 100644 --- a/include/Nazara/Utility/Enums.hpp +++ b/include/Nazara/Utility/Enums.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/Event.hpp b/include/Nazara/Utility/Event.hpp index 723866011..0403bd51e 100644 --- a/include/Nazara/Utility/Event.hpp +++ b/include/Nazara/Utility/Event.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index 1b01ad9f8..39618ebb9 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/FontData.hpp b/include/Nazara/Utility/FontData.hpp index 171735b10..11f0e6c9e 100644 --- a/include/Nazara/Utility/FontData.hpp +++ b/include/Nazara/Utility/FontData.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/FontGlyph.hpp b/include/Nazara/Utility/FontGlyph.hpp index 11bceb255..516052be4 100644 --- a/include/Nazara/Utility/FontGlyph.hpp +++ b/include/Nazara/Utility/FontGlyph.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/Icon.hpp b/include/Nazara/Utility/Icon.hpp index 67dbc0791..369cc7639 100644 --- a/include/Nazara/Utility/Icon.hpp +++ b/include/Nazara/Utility/Icon.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/Image.hpp b/include/Nazara/Utility/Image.hpp index 39a79ae89..91d1ac6d6 100644 --- a/include/Nazara/Utility/Image.hpp +++ b/include/Nazara/Utility/Image.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/IndexBuffer.hpp b/include/Nazara/Utility/IndexBuffer.hpp index a25c47421..20b42c6a0 100644 --- a/include/Nazara/Utility/IndexBuffer.hpp +++ b/include/Nazara/Utility/IndexBuffer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/IndexIterator.hpp b/include/Nazara/Utility/IndexIterator.hpp index d989f90fb..b0eaa8cb8 100644 --- a/include/Nazara/Utility/IndexIterator.hpp +++ b/include/Nazara/Utility/IndexIterator.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/IndexIterator.inl b/include/Nazara/Utility/IndexIterator.inl index d7def8d59..38ac4e6f5 100644 --- a/include/Nazara/Utility/IndexIterator.inl +++ b/include/Nazara/Utility/IndexIterator.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/IndexMapper.hpp b/include/Nazara/Utility/IndexMapper.hpp index 4e53fb609..e06d1826f 100644 --- a/include/Nazara/Utility/IndexMapper.hpp +++ b/include/Nazara/Utility/IndexMapper.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/Joint.hpp b/include/Nazara/Utility/Joint.hpp index 64f48f034..1aec0d5dd 100644 --- a/include/Nazara/Utility/Joint.hpp +++ b/include/Nazara/Utility/Joint.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/Keyboard.hpp b/include/Nazara/Utility/Keyboard.hpp index f9f5e5702..475ec7e91 100644 --- a/include/Nazara/Utility/Keyboard.hpp +++ b/include/Nazara/Utility/Keyboard.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp index 1e2896e0e..7ae235234 100644 --- a/include/Nazara/Utility/Mesh.hpp +++ b/include/Nazara/Utility/Mesh.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/MeshData.hpp b/include/Nazara/Utility/MeshData.hpp index f2bac177b..ff12d3681 100644 --- a/include/Nazara/Utility/MeshData.hpp +++ b/include/Nazara/Utility/MeshData.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/Mouse.hpp b/include/Nazara/Utility/Mouse.hpp index 843504ae9..8dad35bbd 100644 --- a/include/Nazara/Utility/Mouse.hpp +++ b/include/Nazara/Utility/Mouse.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/Node.hpp b/include/Nazara/Utility/Node.hpp index 11f9d1f15..f7d33286b 100644 --- a/include/Nazara/Utility/Node.hpp +++ b/include/Nazara/Utility/Node.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/PixelFormat.hpp b/include/Nazara/Utility/PixelFormat.hpp index f4443c22b..c84f20d38 100644 --- a/include/Nazara/Utility/PixelFormat.hpp +++ b/include/Nazara/Utility/PixelFormat.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/PixelFormat.inl b/include/Nazara/Utility/PixelFormat.inl index 2154d2f05..e399e408f 100644 --- a/include/Nazara/Utility/PixelFormat.inl +++ b/include/Nazara/Utility/PixelFormat.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/Sequence.hpp b/include/Nazara/Utility/Sequence.hpp index 79bd08dcb..2497b7d0a 100644 --- a/include/Nazara/Utility/Sequence.hpp +++ b/include/Nazara/Utility/Sequence.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/SkeletalMesh.hpp b/include/Nazara/Utility/SkeletalMesh.hpp index 72a0567ba..f60f9ec46 100644 --- a/include/Nazara/Utility/SkeletalMesh.hpp +++ b/include/Nazara/Utility/SkeletalMesh.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/Skeleton.hpp b/include/Nazara/Utility/Skeleton.hpp index 12f088622..699752d4c 100644 --- a/include/Nazara/Utility/Skeleton.hpp +++ b/include/Nazara/Utility/Skeleton.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/StaticMesh.hpp b/include/Nazara/Utility/StaticMesh.hpp index 3af527155..1f33b0489 100644 --- a/include/Nazara/Utility/StaticMesh.hpp +++ b/include/Nazara/Utility/StaticMesh.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/SubMesh.hpp b/include/Nazara/Utility/SubMesh.hpp index cfa031b22..08c1ad26c 100644 --- a/include/Nazara/Utility/SubMesh.hpp +++ b/include/Nazara/Utility/SubMesh.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/TriangleIterator.hpp b/include/Nazara/Utility/TriangleIterator.hpp index 48c68e86b..59288fa1d 100644 --- a/include/Nazara/Utility/TriangleIterator.hpp +++ b/include/Nazara/Utility/TriangleIterator.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/Utility.hpp b/include/Nazara/Utility/Utility.hpp index 94749ec4b..fa40d5135 100644 --- a/include/Nazara/Utility/Utility.hpp +++ b/include/Nazara/Utility/Utility.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/VertexBuffer.hpp b/include/Nazara/Utility/VertexBuffer.hpp index 51bbe75f0..936ff88a8 100644 --- a/include/Nazara/Utility/VertexBuffer.hpp +++ b/include/Nazara/Utility/VertexBuffer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/VertexDeclaration.hpp b/include/Nazara/Utility/VertexDeclaration.hpp index 27f6a7aee..c81315e2d 100644 --- a/include/Nazara/Utility/VertexDeclaration.hpp +++ b/include/Nazara/Utility/VertexDeclaration.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/VertexMapper.hpp b/include/Nazara/Utility/VertexMapper.hpp index 149e73832..8bfdd4ca0 100644 --- a/include/Nazara/Utility/VertexMapper.hpp +++ b/include/Nazara/Utility/VertexMapper.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/VertexMapper.inl b/include/Nazara/Utility/VertexMapper.inl index cd7900430..34270b084 100644 --- a/include/Nazara/Utility/VertexMapper.inl +++ b/include/Nazara/Utility/VertexMapper.inl @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/VertexStruct.hpp b/include/Nazara/Utility/VertexStruct.hpp index 9cc365aee..2f4130398 100644 --- a/include/Nazara/Utility/VertexStruct.hpp +++ b/include/Nazara/Utility/VertexStruct.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/VideoMode.hpp b/include/Nazara/Utility/VideoMode.hpp index 5a2b476df..57b0c7d63 100644 --- a/include/Nazara/Utility/VideoMode.hpp +++ b/include/Nazara/Utility/VideoMode.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/Window.hpp b/include/Nazara/Utility/Window.hpp index 9e4b75d38..1850c07a4 100644 --- a/include/Nazara/Utility/Window.hpp +++ b/include/Nazara/Utility/Window.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/include/Nazara/Utility/WindowHandle.hpp b/include/Nazara/Utility/WindowHandle.hpp index 9b26b8fbc..bebbc1107 100644 --- a/include/Nazara/Utility/WindowHandle.hpp +++ b/include/Nazara/Utility/WindowHandle.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Audio/Audio.cpp b/src/Nazara/Audio/Audio.cpp index 656dccdcd..3ef54bf46 100644 --- a/src/Nazara/Audio/Audio.cpp +++ b/src/Nazara/Audio/Audio.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Audio/Loaders/sndfile.hpp b/src/Nazara/Audio/Loaders/sndfile.hpp index ad5ffb562..5ab600bce 100644 --- a/src/Nazara/Audio/Loaders/sndfile.hpp +++ b/src/Nazara/Audio/Loaders/sndfile.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Audio/Loaders/sndfile/Loader.cpp b/src/Nazara/Audio/Loaders/sndfile/Loader.cpp index 918455ecd..d1b8be31f 100644 --- a/src/Nazara/Audio/Loaders/sndfile/Loader.cpp +++ b/src/Nazara/Audio/Loaders/sndfile/Loader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Audio/Music.cpp b/src/Nazara/Audio/Music.cpp index aad189270..50bff83be 100644 --- a/src/Nazara/Audio/Music.cpp +++ b/src/Nazara/Audio/Music.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Audio/OpenAL.cpp b/src/Nazara/Audio/OpenAL.cpp index 2e15a4ba7..f156ec729 100644 --- a/src/Nazara/Audio/OpenAL.cpp +++ b/src/Nazara/Audio/OpenAL.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Audio/Sound.cpp b/src/Nazara/Audio/Sound.cpp index 69a24c054..da0e9a959 100644 --- a/src/Nazara/Audio/Sound.cpp +++ b/src/Nazara/Audio/Sound.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Audio/SoundBuffer.cpp b/src/Nazara/Audio/SoundBuffer.cpp index 7d6dcfe41..6cbfcc6ba 100644 --- a/src/Nazara/Audio/SoundBuffer.cpp +++ b/src/Nazara/Audio/SoundBuffer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Audio/SoundEmitter.cpp b/src/Nazara/Audio/SoundEmitter.cpp index 54d326954..47b39a741 100644 --- a/src/Nazara/Audio/SoundEmitter.cpp +++ b/src/Nazara/Audio/SoundEmitter.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Audio/SoundStream.cpp b/src/Nazara/Audio/SoundStream.cpp index b10bd90a0..a81ea7e41 100644 --- a/src/Nazara/Audio/SoundStream.cpp +++ b/src/Nazara/Audio/SoundStream.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Audio module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Core/AbstractHash.cpp b/src/Nazara/Core/AbstractHash.cpp index 838a62859..b388da5e2 100644 --- a/src/Nazara/Core/AbstractHash.cpp +++ b/src/Nazara/Core/AbstractHash.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/ByteArray.cpp b/src/Nazara/Core/ByteArray.cpp index 135a72895..16a7ed1b2 100644 --- a/src/Nazara/Core/ByteArray.cpp +++ b/src/Nazara/Core/ByteArray.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Clock.cpp b/src/Nazara/Core/Clock.cpp index f1cf8ceb0..8ad7a32a1 100644 --- a/src/Nazara/Core/Clock.cpp +++ b/src/Nazara/Core/Clock.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Color.cpp b/src/Nazara/Core/Color.cpp index 815fad032..a6e596021 100644 --- a/src/Nazara/Core/Color.cpp +++ b/src/Nazara/Core/Color.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/ConditionVariable.cpp b/src/Nazara/Core/ConditionVariable.cpp index f45393a95..ac8dcd50a 100644 --- a/src/Nazara/Core/ConditionVariable.cpp +++ b/src/Nazara/Core/ConditionVariable.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Core.cpp b/src/Nazara/Core/Core.cpp index 0fd722719..7e32de55d 100644 --- a/src/Nazara/Core/Core.cpp +++ b/src/Nazara/Core/Core.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Debug/NewRedefinition.cpp b/src/Nazara/Core/Debug/NewRedefinition.cpp index b5707192e..36a9f2d91 100644 --- a/src/Nazara/Core/Debug/NewRedefinition.cpp +++ b/src/Nazara/Core/Debug/NewRedefinition.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Directory.cpp b/src/Nazara/Core/Directory.cpp index 32ce320ef..e500eda06 100644 --- a/src/Nazara/Core/Directory.cpp +++ b/src/Nazara/Core/Directory.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/DynLib.cpp b/src/Nazara/Core/DynLib.cpp index b819f1ef7..13182213a 100644 --- a/src/Nazara/Core/DynLib.cpp +++ b/src/Nazara/Core/DynLib.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Error.cpp b/src/Nazara/Core/Error.cpp index e73a3e87a..42a297076 100644 --- a/src/Nazara/Core/Error.cpp +++ b/src/Nazara/Core/Error.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/ErrorFlags.cpp b/src/Nazara/Core/ErrorFlags.cpp index a6805f87e..15a298087 100644 --- a/src/Nazara/Core/ErrorFlags.cpp +++ b/src/Nazara/Core/ErrorFlags.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index 512a29144..6c38f30f7 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/GuillotineBinPack.cpp b/src/Nazara/Core/GuillotineBinPack.cpp index 7a32f3ae1..3127c4203 100644 --- a/src/Nazara/Core/GuillotineBinPack.cpp +++ b/src/Nazara/Core/GuillotineBinPack.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/HardwareInfo.cpp b/src/Nazara/Core/HardwareInfo.cpp index 09299e052..6bc12835a 100644 --- a/src/Nazara/Core/HardwareInfo.cpp +++ b/src/Nazara/Core/HardwareInfo.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Hash.cpp b/src/Nazara/Core/Hash.cpp index 3a1707710..4a7654d77 100644 --- a/src/Nazara/Core/Hash.cpp +++ b/src/Nazara/Core/Hash.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Hash/CRC32.cpp b/src/Nazara/Core/Hash/CRC32.cpp index c2c1377e0..6021cf455 100644 --- a/src/Nazara/Core/Hash/CRC32.cpp +++ b/src/Nazara/Core/Hash/CRC32.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Hash/Fletcher16.cpp b/src/Nazara/Core/Hash/Fletcher16.cpp index 609896211..3a608a6b1 100644 --- a/src/Nazara/Core/Hash/Fletcher16.cpp +++ b/src/Nazara/Core/Hash/Fletcher16.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Hash/MD5.cpp b/src/Nazara/Core/Hash/MD5.cpp index a2c8a2483..5ac1ff61e 100644 --- a/src/Nazara/Core/Hash/MD5.cpp +++ b/src/Nazara/Core/Hash/MD5.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Hash/SHA/Internal.cpp b/src/Nazara/Core/Hash/SHA/Internal.cpp index d011ddbe3..922a8767d 100644 --- a/src/Nazara/Core/Hash/SHA/Internal.cpp +++ b/src/Nazara/Core/Hash/SHA/Internal.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Hash/SHA/Internal.hpp b/src/Nazara/Core/Hash/SHA/Internal.hpp index 1e8e7eae1..78748bdff 100644 --- a/src/Nazara/Core/Hash/SHA/Internal.hpp +++ b/src/Nazara/Core/Hash/SHA/Internal.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Hash/SHA1.cpp b/src/Nazara/Core/Hash/SHA1.cpp index 20e81ea1a..b35c3fb4b 100644 --- a/src/Nazara/Core/Hash/SHA1.cpp +++ b/src/Nazara/Core/Hash/SHA1.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Hash/SHA224.cpp b/src/Nazara/Core/Hash/SHA224.cpp index 1c6f70d0e..fd0a3f12b 100644 --- a/src/Nazara/Core/Hash/SHA224.cpp +++ b/src/Nazara/Core/Hash/SHA224.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Hash/SHA256.cpp b/src/Nazara/Core/Hash/SHA256.cpp index 572f1c6eb..056f06343 100644 --- a/src/Nazara/Core/Hash/SHA256.cpp +++ b/src/Nazara/Core/Hash/SHA256.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Hash/SHA384.cpp b/src/Nazara/Core/Hash/SHA384.cpp index 8c3d1f3dc..816b26dd9 100644 --- a/src/Nazara/Core/Hash/SHA384.cpp +++ b/src/Nazara/Core/Hash/SHA384.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Hash/SHA512.cpp b/src/Nazara/Core/Hash/SHA512.cpp index 91071acf3..513797448 100644 --- a/src/Nazara/Core/Hash/SHA512.cpp +++ b/src/Nazara/Core/Hash/SHA512.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Hash/Whirlpool.cpp b/src/Nazara/Core/Hash/Whirlpool.cpp index 6921f05c7..886943f41 100644 --- a/src/Nazara/Core/Hash/Whirlpool.cpp +++ b/src/Nazara/Core/Hash/Whirlpool.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/HashDigest.cpp b/src/Nazara/Core/HashDigest.cpp index 27aa22db3..aeba77415 100644 --- a/src/Nazara/Core/HashDigest.cpp +++ b/src/Nazara/Core/HashDigest.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Hashable.cpp b/src/Nazara/Core/Hashable.cpp index 881341088..6b3f1e074 100644 --- a/src/Nazara/Core/Hashable.cpp +++ b/src/Nazara/Core/Hashable.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/InputStream.cpp b/src/Nazara/Core/InputStream.cpp index 2e5f4f14c..cd231bebf 100644 --- a/src/Nazara/Core/InputStream.cpp +++ b/src/Nazara/Core/InputStream.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/LockGuard.cpp b/src/Nazara/Core/LockGuard.cpp index 9e25a8d3c..4ffaa3aed 100644 --- a/src/Nazara/Core/LockGuard.cpp +++ b/src/Nazara/Core/LockGuard.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Log.cpp b/src/Nazara/Core/Log.cpp index 0726d886c..51622d100 100644 --- a/src/Nazara/Core/Log.cpp +++ b/src/Nazara/Core/Log.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/MemoryManager.cpp b/src/Nazara/Core/MemoryManager.cpp index ff38dadc1..a91133234 100644 --- a/src/Nazara/Core/MemoryManager.cpp +++ b/src/Nazara/Core/MemoryManager.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/MemoryStream.cpp b/src/Nazara/Core/MemoryStream.cpp index 1c1bcd6cb..f8b391c6e 100644 --- a/src/Nazara/Core/MemoryStream.cpp +++ b/src/Nazara/Core/MemoryStream.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Mutex.cpp b/src/Nazara/Core/Mutex.cpp index 923309566..ca2929a3a 100644 --- a/src/Nazara/Core/Mutex.cpp +++ b/src/Nazara/Core/Mutex.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/ParameterList.cpp b/src/Nazara/Core/ParameterList.cpp index 6ac8e9c54..5b6e74b93 100644 --- a/src/Nazara/Core/ParameterList.cpp +++ b/src/Nazara/Core/ParameterList.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/PluginManager.cpp b/src/Nazara/Core/PluginManager.cpp index 5ee08fe91..77346ec29 100644 --- a/src/Nazara/Core/PluginManager.cpp +++ b/src/Nazara/Core/PluginManager.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/PrimitiveList.cpp b/src/Nazara/Core/PrimitiveList.cpp index 6e4961cbe..2636ed415 100644 --- a/src/Nazara/Core/PrimitiveList.cpp +++ b/src/Nazara/Core/PrimitiveList.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Resource.cpp b/src/Nazara/Core/Resource.cpp index d262b5e8b..7d2410df7 100644 --- a/src/Nazara/Core/Resource.cpp +++ b/src/Nazara/Core/Resource.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/ResourceListener.cpp b/src/Nazara/Core/ResourceListener.cpp index 6e8019a84..0517cb683 100644 --- a/src/Nazara/Core/ResourceListener.cpp +++ b/src/Nazara/Core/ResourceListener.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Semaphore.cpp b/src/Nazara/Core/Semaphore.cpp index a36efa875..6cdb83f6d 100644 --- a/src/Nazara/Core/Semaphore.cpp +++ b/src/Nazara/Core/Semaphore.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Stream.cpp b/src/Nazara/Core/Stream.cpp index be7227935..77948a382 100644 --- a/src/Nazara/Core/Stream.cpp +++ b/src/Nazara/Core/Stream.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index 259b59006..e2b0ed97e 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/StringStream.cpp b/src/Nazara/Core/StringStream.cpp index a15196cac..9eb4494ff 100644 --- a/src/Nazara/Core/StringStream.cpp +++ b/src/Nazara/Core/StringStream.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/TaskScheduler.cpp b/src/Nazara/Core/TaskScheduler.cpp index bf916392e..4e328045e 100644 --- a/src/Nazara/Core/TaskScheduler.cpp +++ b/src/Nazara/Core/TaskScheduler.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Thread.cpp b/src/Nazara/Core/Thread.cpp index 2d603dce9..47d7d102d 100644 --- a/src/Nazara/Core/Thread.cpp +++ b/src/Nazara/Core/Thread.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Unicode.cpp b/src/Nazara/Core/Unicode.cpp index a00abfdac..25b54c20c 100644 --- a/src/Nazara/Core/Unicode.cpp +++ b/src/Nazara/Core/Unicode.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Win32/ClockImpl.cpp b/src/Nazara/Core/Win32/ClockImpl.cpp index dbc3c1602..334b977db 100644 --- a/src/Nazara/Core/Win32/ClockImpl.cpp +++ b/src/Nazara/Core/Win32/ClockImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Win32/ClockImpl.hpp b/src/Nazara/Core/Win32/ClockImpl.hpp index a5a329c2e..c73eb5dcf 100644 --- a/src/Nazara/Core/Win32/ClockImpl.hpp +++ b/src/Nazara/Core/Win32/ClockImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Win32/ConditionVariableImpl.cpp b/src/Nazara/Core/Win32/ConditionVariableImpl.cpp index 2df0558c6..0e1d30539 100644 --- a/src/Nazara/Core/Win32/ConditionVariableImpl.cpp +++ b/src/Nazara/Core/Win32/ConditionVariableImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Win32/ConditionVariableImpl.hpp b/src/Nazara/Core/Win32/ConditionVariableImpl.hpp index e9041927b..171c9cd2a 100644 --- a/src/Nazara/Core/Win32/ConditionVariableImpl.hpp +++ b/src/Nazara/Core/Win32/ConditionVariableImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Win32/DirectoryImpl.cpp b/src/Nazara/Core/Win32/DirectoryImpl.cpp index d5fd6eb93..f48a0c7f4 100644 --- a/src/Nazara/Core/Win32/DirectoryImpl.cpp +++ b/src/Nazara/Core/Win32/DirectoryImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Win32/DirectoryImpl.hpp b/src/Nazara/Core/Win32/DirectoryImpl.hpp index 040e3afee..cb2df657d 100644 --- a/src/Nazara/Core/Win32/DirectoryImpl.hpp +++ b/src/Nazara/Core/Win32/DirectoryImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Win32/DynLibImpl.cpp b/src/Nazara/Core/Win32/DynLibImpl.cpp index 37ac5a0e9..b10ae8a38 100644 --- a/src/Nazara/Core/Win32/DynLibImpl.cpp +++ b/src/Nazara/Core/Win32/DynLibImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Win32/DynLibImpl.hpp b/src/Nazara/Core/Win32/DynLibImpl.hpp index fedc93103..662524370 100644 --- a/src/Nazara/Core/Win32/DynLibImpl.hpp +++ b/src/Nazara/Core/Win32/DynLibImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Win32/FileImpl.cpp b/src/Nazara/Core/Win32/FileImpl.cpp index 3f88b71ad..455c99e18 100644 --- a/src/Nazara/Core/Win32/FileImpl.cpp +++ b/src/Nazara/Core/Win32/FileImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Win32/FileImpl.hpp b/src/Nazara/Core/Win32/FileImpl.hpp index 6802214e7..15420b8db 100644 --- a/src/Nazara/Core/Win32/FileImpl.hpp +++ b/src/Nazara/Core/Win32/FileImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Win32/HardwareInfoImpl.cpp b/src/Nazara/Core/Win32/HardwareInfoImpl.cpp index 0f5aa77a6..4fb664aca 100644 --- a/src/Nazara/Core/Win32/HardwareInfoImpl.cpp +++ b/src/Nazara/Core/Win32/HardwareInfoImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Win32/HardwareInfoImpl.hpp b/src/Nazara/Core/Win32/HardwareInfoImpl.hpp index 238b1ea66..cd8f4264a 100644 --- a/src/Nazara/Core/Win32/HardwareInfoImpl.hpp +++ b/src/Nazara/Core/Win32/HardwareInfoImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Win32/MutexImpl.cpp b/src/Nazara/Core/Win32/MutexImpl.cpp index 504c9be48..81c712077 100644 --- a/src/Nazara/Core/Win32/MutexImpl.cpp +++ b/src/Nazara/Core/Win32/MutexImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Win32/MutexImpl.hpp b/src/Nazara/Core/Win32/MutexImpl.hpp index 148fe7dfb..a45b49b0d 100644 --- a/src/Nazara/Core/Win32/MutexImpl.hpp +++ b/src/Nazara/Core/Win32/MutexImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Win32/SemaphoreImpl.cpp b/src/Nazara/Core/Win32/SemaphoreImpl.cpp index 2561f4846..eddba3927 100644 --- a/src/Nazara/Core/Win32/SemaphoreImpl.cpp +++ b/src/Nazara/Core/Win32/SemaphoreImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Win32/SemaphoreImpl.hpp b/src/Nazara/Core/Win32/SemaphoreImpl.hpp index 62cb250d3..e89c93908 100644 --- a/src/Nazara/Core/Win32/SemaphoreImpl.hpp +++ b/src/Nazara/Core/Win32/SemaphoreImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp b/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp index 09c3c1abd..bb230f086 100644 --- a/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp +++ b/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Win32/TaskSchedulerImpl.hpp b/src/Nazara/Core/Win32/TaskSchedulerImpl.hpp index df1630414..0eb0fd6e1 100644 --- a/src/Nazara/Core/Win32/TaskSchedulerImpl.hpp +++ b/src/Nazara/Core/Win32/TaskSchedulerImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Win32/ThreadImpl.cpp b/src/Nazara/Core/Win32/ThreadImpl.cpp index c5b88701c..e654e9158 100644 --- a/src/Nazara/Core/Win32/ThreadImpl.cpp +++ b/src/Nazara/Core/Win32/ThreadImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Win32/ThreadImpl.hpp b/src/Nazara/Core/Win32/ThreadImpl.hpp index 17044b465..564f66db9 100644 --- a/src/Nazara/Core/Win32/ThreadImpl.hpp +++ b/src/Nazara/Core/Win32/ThreadImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Win32/Time.cpp b/src/Nazara/Core/Win32/Time.cpp index 91d1b2713..c4802a2f2 100644 --- a/src/Nazara/Core/Win32/Time.cpp +++ b/src/Nazara/Core/Win32/Time.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Core/Win32/Time.hpp b/src/Nazara/Core/Win32/Time.hpp index 6a6096b02..e28fe7654 100644 --- a/src/Nazara/Core/Win32/Time.hpp +++ b/src/Nazara/Core/Win32/Time.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Graphics/AbstractBackground.cpp b/src/Nazara/Graphics/AbstractBackground.cpp index 718e68ca1..5792b448f 100644 --- a/src/Nazara/Graphics/AbstractBackground.cpp +++ b/src/Nazara/Graphics/AbstractBackground.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/AbstractRenderQueue.cpp b/src/Nazara/Graphics/AbstractRenderQueue.cpp index dde6a4305..4ceea80f5 100644 --- a/src/Nazara/Graphics/AbstractRenderQueue.cpp +++ b/src/Nazara/Graphics/AbstractRenderQueue.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/AbstractRenderTechnique.cpp b/src/Nazara/Graphics/AbstractRenderTechnique.cpp index bd5f7d39c..c338091b8 100644 --- a/src/Nazara/Graphics/AbstractRenderTechnique.cpp +++ b/src/Nazara/Graphics/AbstractRenderTechnique.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/AbstractViewer.cpp b/src/Nazara/Graphics/AbstractViewer.cpp index 43fbb2072..58feebfa7 100644 --- a/src/Nazara/Graphics/AbstractViewer.cpp +++ b/src/Nazara/Graphics/AbstractViewer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/Camera.cpp b/src/Nazara/Graphics/Camera.cpp index 570b1f289..ba7539481 100644 --- a/src/Nazara/Graphics/Camera.cpp +++ b/src/Nazara/Graphics/Camera.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/ColorBackground.cpp b/src/Nazara/Graphics/ColorBackground.cpp index 71193fe82..5428873fb 100644 --- a/src/Nazara/Graphics/ColorBackground.cpp +++ b/src/Nazara/Graphics/ColorBackground.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/DeferredBloomPass.cpp b/src/Nazara/Graphics/DeferredBloomPass.cpp index 754a4b88c..29e875d3c 100644 --- a/src/Nazara/Graphics/DeferredBloomPass.cpp +++ b/src/Nazara/Graphics/DeferredBloomPass.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/DeferredDOFPass.cpp b/src/Nazara/Graphics/DeferredDOFPass.cpp index d526640cf..541181411 100644 --- a/src/Nazara/Graphics/DeferredDOFPass.cpp +++ b/src/Nazara/Graphics/DeferredDOFPass.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/DeferredFXAAPass.cpp b/src/Nazara/Graphics/DeferredFXAAPass.cpp index defd181ef..929a23453 100644 --- a/src/Nazara/Graphics/DeferredFXAAPass.cpp +++ b/src/Nazara/Graphics/DeferredFXAAPass.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/DeferredFinalPass.cpp b/src/Nazara/Graphics/DeferredFinalPass.cpp index 71794c090..a44bbd6d9 100644 --- a/src/Nazara/Graphics/DeferredFinalPass.cpp +++ b/src/Nazara/Graphics/DeferredFinalPass.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/DeferredFogPass.cpp b/src/Nazara/Graphics/DeferredFogPass.cpp index abd439d23..01f20f95b 100644 --- a/src/Nazara/Graphics/DeferredFogPass.cpp +++ b/src/Nazara/Graphics/DeferredFogPass.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/DeferredForwardPass.cpp b/src/Nazara/Graphics/DeferredForwardPass.cpp index 368377e08..b6c16971b 100644 --- a/src/Nazara/Graphics/DeferredForwardPass.cpp +++ b/src/Nazara/Graphics/DeferredForwardPass.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/DeferredGeometryPass.cpp b/src/Nazara/Graphics/DeferredGeometryPass.cpp index a9b10f652..93052d322 100644 --- a/src/Nazara/Graphics/DeferredGeometryPass.cpp +++ b/src/Nazara/Graphics/DeferredGeometryPass.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/DeferredPhongLightingPass.cpp b/src/Nazara/Graphics/DeferredPhongLightingPass.cpp index 64b58ddb1..6208edbd5 100644 --- a/src/Nazara/Graphics/DeferredPhongLightingPass.cpp +++ b/src/Nazara/Graphics/DeferredPhongLightingPass.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/DeferredRenderPass.cpp b/src/Nazara/Graphics/DeferredRenderPass.cpp index 2d9a33226..b71b3dd73 100644 --- a/src/Nazara/Graphics/DeferredRenderPass.cpp +++ b/src/Nazara/Graphics/DeferredRenderPass.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/DeferredRenderQueue.cpp b/src/Nazara/Graphics/DeferredRenderQueue.cpp index 2736e7e32..6cecb980f 100644 --- a/src/Nazara/Graphics/DeferredRenderQueue.cpp +++ b/src/Nazara/Graphics/DeferredRenderQueue.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/DeferredRenderTechnique.cpp b/src/Nazara/Graphics/DeferredRenderTechnique.cpp index d05b39fe7..fb2d6320f 100644 --- a/src/Nazara/Graphics/DeferredRenderTechnique.cpp +++ b/src/Nazara/Graphics/DeferredRenderTechnique.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/Drawable.cpp b/src/Nazara/Graphics/Drawable.cpp index 7c474bb69..d6ec401a1 100644 --- a/src/Nazara/Graphics/Drawable.cpp +++ b/src/Nazara/Graphics/Drawable.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index ca4a4865c..1580615c9 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 09e4e7910..22f2a1234 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/Graphics.cpp b/src/Nazara/Graphics/Graphics.cpp index 77da10887..93c7766a3 100644 --- a/src/Nazara/Graphics/Graphics.cpp +++ b/src/Nazara/Graphics/Graphics.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/Light.cpp b/src/Nazara/Graphics/Light.cpp index e3288adc2..17b726f35 100644 --- a/src/Nazara/Graphics/Light.cpp +++ b/src/Nazara/Graphics/Light.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/LightManager.cpp b/src/Nazara/Graphics/LightManager.cpp index 8153e7d2a..d0f8b3bb6 100644 --- a/src/Nazara/Graphics/LightManager.cpp +++ b/src/Nazara/Graphics/LightManager.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/Loaders/Mesh.hpp b/src/Nazara/Graphics/Loaders/Mesh.hpp index c730f2a92..44c5d98e1 100644 --- a/src/Nazara/Graphics/Loaders/Mesh.hpp +++ b/src/Nazara/Graphics/Loaders/Mesh.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/Loaders/Mesh/Loader.cpp b/src/Nazara/Graphics/Loaders/Mesh/Loader.cpp index 2c2d5e514..ad973f77e 100644 --- a/src/Nazara/Graphics/Loaders/Mesh/Loader.cpp +++ b/src/Nazara/Graphics/Loaders/Mesh/Loader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/Loaders/OBJ.hpp b/src/Nazara/Graphics/Loaders/OBJ.hpp index 4748fc7bd..71f20f8e3 100644 --- a/src/Nazara/Graphics/Loaders/OBJ.hpp +++ b/src/Nazara/Graphics/Loaders/OBJ.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp b/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp index bc9f3b3a4..d848ef052 100644 --- a/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp +++ b/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/Loaders/OBJ/MTLParser.cpp b/src/Nazara/Graphics/Loaders/OBJ/MTLParser.cpp index fedbf0ed3..2614fa511 100644 --- a/src/Nazara/Graphics/Loaders/OBJ/MTLParser.cpp +++ b/src/Nazara/Graphics/Loaders/OBJ/MTLParser.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/Loaders/OBJ/MTLParser.hpp b/src/Nazara/Graphics/Loaders/OBJ/MTLParser.hpp index 6103d75d9..5bfbef6d0 100644 --- a/src/Nazara/Graphics/Loaders/OBJ/MTLParser.hpp +++ b/src/Nazara/Graphics/Loaders/OBJ/MTLParser.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/Loaders/OBJ/OBJParser.cpp b/src/Nazara/Graphics/Loaders/OBJ/OBJParser.cpp index 6a404e2c6..6bb87be56 100644 --- a/src/Nazara/Graphics/Loaders/OBJ/OBJParser.cpp +++ b/src/Nazara/Graphics/Loaders/OBJ/OBJParser.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/Loaders/OBJ/OBJParser.hpp b/src/Nazara/Graphics/Loaders/OBJ/OBJParser.hpp index baf7215e2..512eda666 100644 --- a/src/Nazara/Graphics/Loaders/OBJ/OBJParser.hpp +++ b/src/Nazara/Graphics/Loaders/OBJ/OBJParser.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/Loaders/Texture.hpp b/src/Nazara/Graphics/Loaders/Texture.hpp index b2d459400..4b746b35a 100644 --- a/src/Nazara/Graphics/Loaders/Texture.hpp +++ b/src/Nazara/Graphics/Loaders/Texture.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/Loaders/Texture/Loader.cpp b/src/Nazara/Graphics/Loaders/Texture/Loader.cpp index 84a38997f..8412e2ca5 100644 --- a/src/Nazara/Graphics/Loaders/Texture/Loader.cpp +++ b/src/Nazara/Graphics/Loaders/Texture/Loader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index c79b4d6d0..ea6087b97 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/Model.cpp b/src/Nazara/Graphics/Model.cpp index cf32336b8..1a19a1b8a 100644 --- a/src/Nazara/Graphics/Model.cpp +++ b/src/Nazara/Graphics/Model.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/ParticleController.cpp b/src/Nazara/Graphics/ParticleController.cpp index 695fd7d5c..ff81046f4 100644 --- a/src/Nazara/Graphics/ParticleController.cpp +++ b/src/Nazara/Graphics/ParticleController.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/ParticleDeclaration.cpp b/src/Nazara/Graphics/ParticleDeclaration.cpp index b2ab27d68..089ce0138 100644 --- a/src/Nazara/Graphics/ParticleDeclaration.cpp +++ b/src/Nazara/Graphics/ParticleDeclaration.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/ParticleEmitter.cpp b/src/Nazara/Graphics/ParticleEmitter.cpp index 33eda8002..c38233630 100644 --- a/src/Nazara/Graphics/ParticleEmitter.cpp +++ b/src/Nazara/Graphics/ParticleEmitter.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/ParticleGenerator.cpp b/src/Nazara/Graphics/ParticleGenerator.cpp index 846e2c1ac..2dd8dbc3d 100644 --- a/src/Nazara/Graphics/ParticleGenerator.cpp +++ b/src/Nazara/Graphics/ParticleGenerator.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/ParticleMapper.cpp b/src/Nazara/Graphics/ParticleMapper.cpp index a73a53349..03e1a1082 100644 --- a/src/Nazara/Graphics/ParticleMapper.cpp +++ b/src/Nazara/Graphics/ParticleMapper.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/ParticleRenderer.cpp b/src/Nazara/Graphics/ParticleRenderer.cpp index 77f9e64c9..ccc2b55bd 100644 --- a/src/Nazara/Graphics/ParticleRenderer.cpp +++ b/src/Nazara/Graphics/ParticleRenderer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/ParticleSystem.cpp b/src/Nazara/Graphics/ParticleSystem.cpp index b8533109b..43e1cac9f 100644 --- a/src/Nazara/Graphics/ParticleSystem.cpp +++ b/src/Nazara/Graphics/ParticleSystem.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/RenderTechniques.cpp b/src/Nazara/Graphics/RenderTechniques.cpp index 6f7635f3c..820700451 100644 --- a/src/Nazara/Graphics/RenderTechniques.cpp +++ b/src/Nazara/Graphics/RenderTechniques.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/Scene.cpp b/src/Nazara/Graphics/Scene.cpp index e66a99f03..d0115b8b0 100644 --- a/src/Nazara/Graphics/Scene.cpp +++ b/src/Nazara/Graphics/Scene.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/SceneNode.cpp b/src/Nazara/Graphics/SceneNode.cpp index d5ae7da72..b0e42bc1d 100644 --- a/src/Nazara/Graphics/SceneNode.cpp +++ b/src/Nazara/Graphics/SceneNode.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/SceneRoot.cpp b/src/Nazara/Graphics/SceneRoot.cpp index 46e446eaa..e817f511f 100644 --- a/src/Nazara/Graphics/SceneRoot.cpp +++ b/src/Nazara/Graphics/SceneRoot.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/SkeletalModel.cpp b/src/Nazara/Graphics/SkeletalModel.cpp index b7fe39f98..958f66ed3 100644 --- a/src/Nazara/Graphics/SkeletalModel.cpp +++ b/src/Nazara/Graphics/SkeletalModel.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/SkinningManager.cpp b/src/Nazara/Graphics/SkinningManager.cpp index a29fb882e..9f0447f14 100644 --- a/src/Nazara/Graphics/SkinningManager.cpp +++ b/src/Nazara/Graphics/SkinningManager.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/SkyboxBackground.cpp b/src/Nazara/Graphics/SkyboxBackground.cpp index 76cbd7b08..ba806d76b 100644 --- a/src/Nazara/Graphics/SkyboxBackground.cpp +++ b/src/Nazara/Graphics/SkyboxBackground.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index 983929d53..426f51321 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index 80def6d1f..41766ec97 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/TextureBackground.cpp b/src/Nazara/Graphics/TextureBackground.cpp index a9d4a1bbc..38f501590 100644 --- a/src/Nazara/Graphics/TextureBackground.cpp +++ b/src/Nazara/Graphics/TextureBackground.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Graphics/View.cpp b/src/Nazara/Graphics/View.cpp index fb55c5054..0316b9e53 100644 --- a/src/Nazara/Graphics/View.cpp +++ b/src/Nazara/Graphics/View.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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/src/Nazara/Lua/Lua.cpp b/src/Nazara/Lua/Lua.cpp index 236ae84a8..5ea40b97d 100644 --- a/src/Nazara/Lua/Lua.cpp +++ b/src/Nazara/Lua/Lua.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Lua/LuaInstance.cpp b/src/Nazara/Lua/LuaInstance.cpp index c1d0c96c8..396fd4a35 100644 --- a/src/Nazara/Lua/LuaInstance.cpp +++ b/src/Nazara/Lua/LuaInstance.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Lua scripting module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/Abstract2DNoise.cpp b/src/Nazara/Noise/Abstract2DNoise.cpp index 86ab9243b..2f2ae4f76 100644 --- a/src/Nazara/Noise/Abstract2DNoise.cpp +++ b/src/Nazara/Noise/Abstract2DNoise.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/Abstract3DNoise.cpp b/src/Nazara/Noise/Abstract3DNoise.cpp index 48a9c5ec9..654df62d6 100644 --- a/src/Nazara/Noise/Abstract3DNoise.cpp +++ b/src/Nazara/Noise/Abstract3DNoise.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/Abstract4DNoise.cpp b/src/Nazara/Noise/Abstract4DNoise.cpp index e8ca084e3..781e3b57e 100644 --- a/src/Nazara/Noise/Abstract4DNoise.cpp +++ b/src/Nazara/Noise/Abstract4DNoise.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/ComplexNoiseBase.cpp b/src/Nazara/Noise/ComplexNoiseBase.cpp index d94a7e350..7529efdb5 100644 --- a/src/Nazara/Noise/ComplexNoiseBase.cpp +++ b/src/Nazara/Noise/ComplexNoiseBase.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/FBM2D.cpp b/src/Nazara/Noise/FBM2D.cpp index 9d91e1a93..8d43e3a07 100644 --- a/src/Nazara/Noise/FBM2D.cpp +++ b/src/Nazara/Noise/FBM2D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/FBM3D.cpp b/src/Nazara/Noise/FBM3D.cpp index ea78d3155..6ac7afc07 100644 --- a/src/Nazara/Noise/FBM3D.cpp +++ b/src/Nazara/Noise/FBM3D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/FBM4D.cpp b/src/Nazara/Noise/FBM4D.cpp index a0fb382ae..c5a256a40 100644 --- a/src/Nazara/Noise/FBM4D.cpp +++ b/src/Nazara/Noise/FBM4D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/HybridMultiFractal3D.cpp b/src/Nazara/Noise/HybridMultiFractal3D.cpp index 20c169386..77df9e3d4 100644 --- a/src/Nazara/Noise/HybridMultiFractal3D.cpp +++ b/src/Nazara/Noise/HybridMultiFractal3D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/HybridMultiFractal4D.cpp b/src/Nazara/Noise/HybridMultiFractal4D.cpp index aa81c4730..7909d3c1e 100644 --- a/src/Nazara/Noise/HybridMultiFractal4D.cpp +++ b/src/Nazara/Noise/HybridMultiFractal4D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/HybridMultifractal2D.cpp b/src/Nazara/Noise/HybridMultifractal2D.cpp index 0bbc07c6f..6721fd981 100644 --- a/src/Nazara/Noise/HybridMultifractal2D.cpp +++ b/src/Nazara/Noise/HybridMultifractal2D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/MappedNoiseBase.cpp b/src/Nazara/Noise/MappedNoiseBase.cpp index cb5a2717f..27b8ece40 100644 --- a/src/Nazara/Noise/MappedNoiseBase.cpp +++ b/src/Nazara/Noise/MappedNoiseBase.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/Noise.cpp b/src/Nazara/Noise/Noise.cpp index cf53c644d..86fc17a6a 100644 --- a/src/Nazara/Noise/Noise.cpp +++ b/src/Nazara/Noise/Noise.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/NoiseBase.cpp b/src/Nazara/Noise/NoiseBase.cpp index 1927ba7fa..d394b7f9c 100644 --- a/src/Nazara/Noise/NoiseBase.cpp +++ b/src/Nazara/Noise/NoiseBase.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/Perlin2D.cpp b/src/Nazara/Noise/Perlin2D.cpp index 18eca6411..4622016d0 100644 --- a/src/Nazara/Noise/Perlin2D.cpp +++ b/src/Nazara/Noise/Perlin2D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/Perlin3D.cpp b/src/Nazara/Noise/Perlin3D.cpp index 253d90873..87d79622b 100644 --- a/src/Nazara/Noise/Perlin3D.cpp +++ b/src/Nazara/Noise/Perlin3D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/Perlin4D.cpp b/src/Nazara/Noise/Perlin4D.cpp index 388cbaef5..1c49c40f8 100644 --- a/src/Nazara/Noise/Perlin4D.cpp +++ b/src/Nazara/Noise/Perlin4D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/Simplex2D.cpp b/src/Nazara/Noise/Simplex2D.cpp index b4b62521d..78f9ceb43 100644 --- a/src/Nazara/Noise/Simplex2D.cpp +++ b/src/Nazara/Noise/Simplex2D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/Simplex3D.cpp b/src/Nazara/Noise/Simplex3D.cpp index 09b4c8c40..9a6138cff 100644 --- a/src/Nazara/Noise/Simplex3D.cpp +++ b/src/Nazara/Noise/Simplex3D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Noise/Simplex4D.cpp b/src/Nazara/Noise/Simplex4D.cpp index 05629bc68..9cc2b28a1 100644 --- a/src/Nazara/Noise/Simplex4D.cpp +++ b/src/Nazara/Noise/Simplex4D.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Rémi Bèges +// Copyright (C) 2015 Rémi Bèges // This file is part of the "Nazara Engine - Noise module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Physics/Geom.cpp b/src/Nazara/Physics/Geom.cpp index a7e348f07..8bb344ba4 100644 --- a/src/Nazara/Physics/Geom.cpp +++ b/src/Nazara/Physics/Geom.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Physics/PhysObject.cpp b/src/Nazara/Physics/PhysObject.cpp index 36b8f12c8..bde930811 100644 --- a/src/Nazara/Physics/PhysObject.cpp +++ b/src/Nazara/Physics/PhysObject.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Physics/PhysWorld.cpp b/src/Nazara/Physics/PhysWorld.cpp index 786151e6e..63ef5c886 100644 --- a/src/Nazara/Physics/PhysWorld.cpp +++ b/src/Nazara/Physics/PhysWorld.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Physics/Physics.cpp b/src/Nazara/Physics/Physics.cpp index fb4e4f9a1..c54023b2c 100644 --- a/src/Nazara/Physics/Physics.cpp +++ b/src/Nazara/Physics/Physics.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Physics module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/Context.cpp b/src/Nazara/Renderer/Context.cpp index 10654fcc3..3a897d7aa 100644 --- a/src/Nazara/Renderer/Context.cpp +++ b/src/Nazara/Renderer/Context.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/ContextParameters.cpp b/src/Nazara/Renderer/ContextParameters.cpp index 06051819e..a7dec4546 100644 --- a/src/Nazara/Renderer/ContextParameters.cpp +++ b/src/Nazara/Renderer/ContextParameters.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/DebugDrawer.cpp b/src/Nazara/Renderer/DebugDrawer.cpp index 5f7090a81..f6822e9b9 100644 --- a/src/Nazara/Renderer/DebugDrawer.cpp +++ b/src/Nazara/Renderer/DebugDrawer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/GpuQuery.cpp b/src/Nazara/Renderer/GpuQuery.cpp index f015c1a32..37b03ebe7 100644 --- a/src/Nazara/Renderer/GpuQuery.cpp +++ b/src/Nazara/Renderer/GpuQuery.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/HardwareBuffer.cpp b/src/Nazara/Renderer/HardwareBuffer.cpp index f4f3b8c95..891ef6289 100644 --- a/src/Nazara/Renderer/HardwareBuffer.cpp +++ b/src/Nazara/Renderer/HardwareBuffer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/HardwareBuffer.hpp b/src/Nazara/Renderer/HardwareBuffer.hpp index 7c53970d7..5a7c9c107 100644 --- a/src/Nazara/Renderer/HardwareBuffer.hpp +++ b/src/Nazara/Renderer/HardwareBuffer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index 3edf4e499..814cb75da 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/RenderBuffer.cpp b/src/Nazara/Renderer/RenderBuffer.cpp index 407a75a7d..c569742d5 100644 --- a/src/Nazara/Renderer/RenderBuffer.cpp +++ b/src/Nazara/Renderer/RenderBuffer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/RenderTarget.cpp b/src/Nazara/Renderer/RenderTarget.cpp index 2a72e88c1..47bd8db6d 100644 --- a/src/Nazara/Renderer/RenderTarget.cpp +++ b/src/Nazara/Renderer/RenderTarget.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/RenderTexture.cpp b/src/Nazara/Renderer/RenderTexture.cpp index c42d6c044..456f5671b 100644 --- a/src/Nazara/Renderer/RenderTexture.cpp +++ b/src/Nazara/Renderer/RenderTexture.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/RenderWindow.cpp b/src/Nazara/Renderer/RenderWindow.cpp index 9580ccc56..3da301254 100644 --- a/src/Nazara/Renderer/RenderWindow.cpp +++ b/src/Nazara/Renderer/RenderWindow.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index fff66de22..84e7cb163 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/Shader.cpp b/src/Nazara/Renderer/Shader.cpp index e9c4fd968..66eba9345 100644 --- a/src/Nazara/Renderer/Shader.cpp +++ b/src/Nazara/Renderer/Shader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/ShaderLibrary.cpp b/src/Nazara/Renderer/ShaderLibrary.cpp index 316a6019b..a474ae6d4 100644 --- a/src/Nazara/Renderer/ShaderLibrary.cpp +++ b/src/Nazara/Renderer/ShaderLibrary.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/ShaderStage.cpp b/src/Nazara/Renderer/ShaderStage.cpp index b3a3c421a..c45757192 100644 --- a/src/Nazara/Renderer/ShaderStage.cpp +++ b/src/Nazara/Renderer/ShaderStage.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index bee9c9ae8..f9ae3e810 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/TextureSampler.cpp b/src/Nazara/Renderer/TextureSampler.cpp index e304a5d49..3c36c61ff 100644 --- a/src/Nazara/Renderer/TextureSampler.cpp +++ b/src/Nazara/Renderer/TextureSampler.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/UberShader.cpp b/src/Nazara/Renderer/UberShader.cpp index 9ebc25e9c..6503a0450 100644 --- a/src/Nazara/Renderer/UberShader.cpp +++ b/src/Nazara/Renderer/UberShader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/UberShaderInstance.cpp b/src/Nazara/Renderer/UberShaderInstance.cpp index 9ad4d5043..367c96bf3 100644 --- a/src/Nazara/Renderer/UberShaderInstance.cpp +++ b/src/Nazara/Renderer/UberShaderInstance.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/UberShaderInstancePreprocessor.cpp b/src/Nazara/Renderer/UberShaderInstancePreprocessor.cpp index c349c41fe..422d936b4 100644 --- a/src/Nazara/Renderer/UberShaderInstancePreprocessor.cpp +++ b/src/Nazara/Renderer/UberShaderInstancePreprocessor.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/UberShaderLibrary.cpp b/src/Nazara/Renderer/UberShaderLibrary.cpp index 9afc9b516..cb5ca9ba8 100644 --- a/src/Nazara/Renderer/UberShaderLibrary.cpp +++ b/src/Nazara/Renderer/UberShaderLibrary.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/UberShaderPreprocessor.cpp b/src/Nazara/Renderer/UberShaderPreprocessor.cpp index 22790bbc4..7bac973d1 100644 --- a/src/Nazara/Renderer/UberShaderPreprocessor.cpp +++ b/src/Nazara/Renderer/UberShaderPreprocessor.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/Win32/ContextImpl.cpp b/src/Nazara/Renderer/Win32/ContextImpl.cpp index 65f9ef98e..5fbe85539 100644 --- a/src/Nazara/Renderer/Win32/ContextImpl.cpp +++ b/src/Nazara/Renderer/Win32/ContextImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Renderer module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Renderer/Win32/ContextImpl.hpp b/src/Nazara/Renderer/Win32/ContextImpl.hpp index cd17c9df2..07d88d44a 100644 --- a/src/Nazara/Renderer/Win32/ContextImpl.hpp +++ b/src/Nazara/Renderer/Win32/ContextImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Utility/AbstractBuffer.cpp b/src/Nazara/Utility/AbstractBuffer.cpp index 84661c25a..76b82b07d 100644 --- a/src/Nazara/Utility/AbstractBuffer.cpp +++ b/src/Nazara/Utility/AbstractBuffer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Algorithm.cpp b/src/Nazara/Utility/Algorithm.cpp index e22f937fa..777181331 100644 --- a/src/Nazara/Utility/Algorithm.cpp +++ b/src/Nazara/Utility/Algorithm.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Animation.cpp b/src/Nazara/Utility/Animation.cpp index 61e325f76..6b0d1b06e 100644 --- a/src/Nazara/Utility/Animation.cpp +++ b/src/Nazara/Utility/Animation.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Buffer.cpp b/src/Nazara/Utility/Buffer.cpp index 757b799a1..dae34312e 100644 --- a/src/Nazara/Utility/Buffer.cpp +++ b/src/Nazara/Utility/Buffer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Cursor.cpp b/src/Nazara/Utility/Cursor.cpp index 7f5534e9d..7a14fd921 100644 --- a/src/Nazara/Utility/Cursor.cpp +++ b/src/Nazara/Utility/Cursor.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index 055ae5ee4..6fe5bcd2c 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/FontData.cpp b/src/Nazara/Utility/FontData.cpp index a5f4b13bd..8a9f9d5b5 100644 --- a/src/Nazara/Utility/FontData.cpp +++ b/src/Nazara/Utility/FontData.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Icon.cpp b/src/Nazara/Utility/Icon.cpp index b52165262..ffd2b4f67 100644 --- a/src/Nazara/Utility/Icon.cpp +++ b/src/Nazara/Utility/Icon.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index e33ce619a..3559249fe 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/IndexBuffer.cpp b/src/Nazara/Utility/IndexBuffer.cpp index 5a4f5007a..7f5a25424 100644 --- a/src/Nazara/Utility/IndexBuffer.cpp +++ b/src/Nazara/Utility/IndexBuffer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/IndexMapper.cpp b/src/Nazara/Utility/IndexMapper.cpp index f006e35e1..ab7419374 100644 --- a/src/Nazara/Utility/IndexMapper.cpp +++ b/src/Nazara/Utility/IndexMapper.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Joint.cpp b/src/Nazara/Utility/Joint.cpp index 8a46ff227..0e83874ca 100644 --- a/src/Nazara/Utility/Joint.cpp +++ b/src/Nazara/Utility/Joint.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Keyboard.cpp b/src/Nazara/Utility/Keyboard.cpp index 3dcae6855..28faa4db7 100644 --- a/src/Nazara/Utility/Keyboard.cpp +++ b/src/Nazara/Utility/Keyboard.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Loaders/FreeType.hpp b/src/Nazara/Utility/Loaders/FreeType.hpp index 6ee1f60ab..3d24bfa93 100644 --- a/src/Nazara/Utility/Loaders/FreeType.hpp +++ b/src/Nazara/Utility/Loaders/FreeType.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Loaders/FreeType/Loader.cpp b/src/Nazara/Utility/Loaders/FreeType/Loader.cpp index 28a32b4b1..70f65bc89 100644 --- a/src/Nazara/Utility/Loaders/FreeType/Loader.cpp +++ b/src/Nazara/Utility/Loaders/FreeType/Loader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq - 2009 Cruden BV +// Copyright (C) 2015 Jérôme Leclercq - 2009 Cruden BV // This file is part of the "Nazara Engine - Utility module" // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/src/Nazara/Utility/Loaders/MD2.hpp b/src/Nazara/Utility/Loaders/MD2.hpp index 3c3d53f98..57dec180d 100644 --- a/src/Nazara/Utility/Loaders/MD2.hpp +++ b/src/Nazara/Utility/Loaders/MD2.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Loaders/MD2/Constants.cpp b/src/Nazara/Utility/Loaders/MD2/Constants.cpp index 9de6f1abb..aee90f183 100644 --- a/src/Nazara/Utility/Loaders/MD2/Constants.cpp +++ b/src/Nazara/Utility/Loaders/MD2/Constants.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Loaders/MD2/Constants.hpp b/src/Nazara/Utility/Loaders/MD2/Constants.hpp index e062c9d65..07e574b4c 100644 --- a/src/Nazara/Utility/Loaders/MD2/Constants.hpp +++ b/src/Nazara/Utility/Loaders/MD2/Constants.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Loaders/MD2/Loader.cpp b/src/Nazara/Utility/Loaders/MD2/Loader.cpp index f57c53340..0483e2dac 100644 --- a/src/Nazara/Utility/Loaders/MD2/Loader.cpp +++ b/src/Nazara/Utility/Loaders/MD2/Loader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Loaders/MD5Anim.hpp b/src/Nazara/Utility/Loaders/MD5Anim.hpp index 54571dd7c..642edb978 100644 --- a/src/Nazara/Utility/Loaders/MD5Anim.hpp +++ b/src/Nazara/Utility/Loaders/MD5Anim.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Loaders/MD5Anim/Loader.cpp b/src/Nazara/Utility/Loaders/MD5Anim/Loader.cpp index 7035c3de8..1fe7c6396 100644 --- a/src/Nazara/Utility/Loaders/MD5Anim/Loader.cpp +++ b/src/Nazara/Utility/Loaders/MD5Anim/Loader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Loaders/MD5Anim/Parser.cpp b/src/Nazara/Utility/Loaders/MD5Anim/Parser.cpp index 2e3abc7d3..1890f9d7f 100644 --- a/src/Nazara/Utility/Loaders/MD5Anim/Parser.cpp +++ b/src/Nazara/Utility/Loaders/MD5Anim/Parser.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Loaders/MD5Anim/Parser.hpp b/src/Nazara/Utility/Loaders/MD5Anim/Parser.hpp index e3b9e19c8..8dc57fe28 100644 --- a/src/Nazara/Utility/Loaders/MD5Anim/Parser.hpp +++ b/src/Nazara/Utility/Loaders/MD5Anim/Parser.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Loaders/MD5Mesh.hpp b/src/Nazara/Utility/Loaders/MD5Mesh.hpp index 7d1d8c805..2589ca068 100644 --- a/src/Nazara/Utility/Loaders/MD5Mesh.hpp +++ b/src/Nazara/Utility/Loaders/MD5Mesh.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp b/src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp index 4712cf9ab..925c589ab 100644 --- a/src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp +++ b/src/Nazara/Utility/Loaders/MD5Mesh/Loader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp b/src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp index 4bc76d018..19d64d103 100644 --- a/src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp +++ b/src/Nazara/Utility/Loaders/MD5Mesh/Parser.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Loaders/MD5Mesh/Parser.hpp b/src/Nazara/Utility/Loaders/MD5Mesh/Parser.hpp index cb63af487..647779b1c 100644 --- a/src/Nazara/Utility/Loaders/MD5Mesh/Parser.hpp +++ b/src/Nazara/Utility/Loaders/MD5Mesh/Parser.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Loaders/PCX.hpp b/src/Nazara/Utility/Loaders/PCX.hpp index 14cf1465c..c3836529f 100644 --- a/src/Nazara/Utility/Loaders/PCX.hpp +++ b/src/Nazara/Utility/Loaders/PCX.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Loaders/PCX/Loader.cpp b/src/Nazara/Utility/Loaders/PCX/Loader.cpp index d0b75dff2..48af53229 100644 --- a/src/Nazara/Utility/Loaders/PCX/Loader.cpp +++ b/src/Nazara/Utility/Loaders/PCX/Loader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Loaders/STB.hpp b/src/Nazara/Utility/Loaders/STB.hpp index 4c3838c66..83e0d9036 100644 --- a/src/Nazara/Utility/Loaders/STB.hpp +++ b/src/Nazara/Utility/Loaders/STB.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Loaders/STB/Loader.cpp b/src/Nazara/Utility/Loaders/STB/Loader.cpp index 0f78fcca2..dbf36e4b4 100644 --- a/src/Nazara/Utility/Loaders/STB/Loader.cpp +++ b/src/Nazara/Utility/Loaders/STB/Loader.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index 031329ef4..4d06ae00f 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Mouse.cpp b/src/Nazara/Utility/Mouse.cpp index 393453878..cdd8be2f1 100644 --- a/src/Nazara/Utility/Mouse.cpp +++ b/src/Nazara/Utility/Mouse.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Node.cpp b/src/Nazara/Utility/Node.cpp index b9105aece..6fb44b666 100644 --- a/src/Nazara/Utility/Node.cpp +++ b/src/Nazara/Utility/Node.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/PixelFormat.cpp b/src/Nazara/Utility/PixelFormat.cpp index b6679598d..a71e3f700 100644 --- a/src/Nazara/Utility/PixelFormat.cpp +++ b/src/Nazara/Utility/PixelFormat.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/SkeletalMesh.cpp b/src/Nazara/Utility/SkeletalMesh.cpp index 5926e7880..5604bb4d8 100644 --- a/src/Nazara/Utility/SkeletalMesh.cpp +++ b/src/Nazara/Utility/SkeletalMesh.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Skeleton.cpp b/src/Nazara/Utility/Skeleton.cpp index eeefc7d98..a28a124aa 100644 --- a/src/Nazara/Utility/Skeleton.cpp +++ b/src/Nazara/Utility/Skeleton.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/SoftwareBuffer.cpp b/src/Nazara/Utility/SoftwareBuffer.cpp index b91ca76d0..b21259dfa 100644 --- a/src/Nazara/Utility/SoftwareBuffer.cpp +++ b/src/Nazara/Utility/SoftwareBuffer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/SoftwareBuffer.hpp b/src/Nazara/Utility/SoftwareBuffer.hpp index 556eeaa0f..abe5419db 100644 --- a/src/Nazara/Utility/SoftwareBuffer.hpp +++ b/src/Nazara/Utility/SoftwareBuffer.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/StaticMesh.cpp b/src/Nazara/Utility/StaticMesh.cpp index 9e64eceea..229ce0cd0 100644 --- a/src/Nazara/Utility/StaticMesh.cpp +++ b/src/Nazara/Utility/StaticMesh.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/SubMesh.cpp b/src/Nazara/Utility/SubMesh.cpp index f44380a2f..69fcdb319 100644 --- a/src/Nazara/Utility/SubMesh.cpp +++ b/src/Nazara/Utility/SubMesh.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/TriangleIterator.cpp b/src/Nazara/Utility/TriangleIterator.cpp index e8bd7af08..7057d6d8f 100644 --- a/src/Nazara/Utility/TriangleIterator.cpp +++ b/src/Nazara/Utility/TriangleIterator.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Utility.cpp b/src/Nazara/Utility/Utility.cpp index 04f7af2c2..dab509037 100644 --- a/src/Nazara/Utility/Utility.cpp +++ b/src/Nazara/Utility/Utility.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/VertexBuffer.cpp b/src/Nazara/Utility/VertexBuffer.cpp index 12f72051f..dbf0426ab 100644 --- a/src/Nazara/Utility/VertexBuffer.cpp +++ b/src/Nazara/Utility/VertexBuffer.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/VertexDeclaration.cpp b/src/Nazara/Utility/VertexDeclaration.cpp index e65814660..a94a6280d 100644 --- a/src/Nazara/Utility/VertexDeclaration.cpp +++ b/src/Nazara/Utility/VertexDeclaration.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/VertexMapper.cpp b/src/Nazara/Utility/VertexMapper.cpp index 6b1b1ae42..e4b272803 100644 --- a/src/Nazara/Utility/VertexMapper.cpp +++ b/src/Nazara/Utility/VertexMapper.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/VideoMode.cpp b/src/Nazara/Utility/VideoMode.cpp index c3d2b81c1..69abdf4a1 100644 --- a/src/Nazara/Utility/VideoMode.cpp +++ b/src/Nazara/Utility/VideoMode.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/VideoModeImpl.hpp b/src/Nazara/Utility/VideoModeImpl.hpp index e58e82ce3..229a6de0a 100644 --- a/src/Nazara/Utility/VideoModeImpl.hpp +++ b/src/Nazara/Utility/VideoModeImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Win32/CursorImpl.cpp b/src/Nazara/Utility/Win32/CursorImpl.cpp index 68014b6ae..1b5f2ddf1 100644 --- a/src/Nazara/Utility/Win32/CursorImpl.cpp +++ b/src/Nazara/Utility/Win32/CursorImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Win32/CursorImpl.hpp b/src/Nazara/Utility/Win32/CursorImpl.hpp index 56ed97b00..d539886c8 100644 --- a/src/Nazara/Utility/Win32/CursorImpl.hpp +++ b/src/Nazara/Utility/Win32/CursorImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Win32/IconImpl.cpp b/src/Nazara/Utility/Win32/IconImpl.cpp index f356d206d..078a9fece 100644 --- a/src/Nazara/Utility/Win32/IconImpl.cpp +++ b/src/Nazara/Utility/Win32/IconImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Win32/IconImpl.hpp b/src/Nazara/Utility/Win32/IconImpl.hpp index 05c3495fa..a384fc852 100644 --- a/src/Nazara/Utility/Win32/IconImpl.hpp +++ b/src/Nazara/Utility/Win32/IconImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Win32/InputImpl.cpp b/src/Nazara/Utility/Win32/InputImpl.cpp index 62337423d..306f6b6ca 100644 --- a/src/Nazara/Utility/Win32/InputImpl.cpp +++ b/src/Nazara/Utility/Win32/InputImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Win32/InputImpl.hpp b/src/Nazara/Utility/Win32/InputImpl.hpp index 2c176377f..0d3f3fb19 100644 --- a/src/Nazara/Utility/Win32/InputImpl.hpp +++ b/src/Nazara/Utility/Win32/InputImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Win32/VideoModeImpl.cpp b/src/Nazara/Utility/Win32/VideoModeImpl.cpp index 638724485..b6d03bb96 100644 --- a/src/Nazara/Utility/Win32/VideoModeImpl.cpp +++ b/src/Nazara/Utility/Win32/VideoModeImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Win32/WindowImpl.cpp b/src/Nazara/Utility/Win32/WindowImpl.cpp index 1da1b9251..e1690def1 100644 --- a/src/Nazara/Utility/Win32/WindowImpl.cpp +++ b/src/Nazara/Utility/Win32/WindowImpl.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Win32/WindowImpl.hpp b/src/Nazara/Utility/Win32/WindowImpl.hpp index 1a726391d..309cd20e7 100644 --- a/src/Nazara/Utility/Win32/WindowImpl.hpp +++ b/src/Nazara/Utility/Win32/WindowImpl.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 diff --git a/src/Nazara/Utility/Window.cpp b/src/Nazara/Utility/Window.cpp index aa84c3607..673396889 100644 --- a/src/Nazara/Utility/Window.cpp +++ b/src/Nazara/Utility/Window.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Jérôme Leclercq +// 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 From 93b04476d1bf05d14507fd70a4016e5a81d10264 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 22 Jan 2015 22:47:01 +0100 Subject: [PATCH 213/233] Fixed POSIX DynLibImpl.hpp Former-commit-id: 6b1924e7f7631eb78743c57973443661f48776f1 --- src/Nazara/Core/Posix/DynLibImpl.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Core/Posix/DynLibImpl.hpp b/src/Nazara/Core/Posix/DynLibImpl.hpp index 96f8a08f3..d4c022dba 100644 --- a/src/Nazara/Core/Posix/DynLibImpl.hpp +++ b/src/Nazara/Core/Posix/DynLibImpl.hpp @@ -19,7 +19,7 @@ class NzDynLibImpl : NzNonCopyable NzDynLibImpl(NzDynLib* m_parent); ~NzDynLibImpl() = default; - NzDynLibFunc GetSymbol(const NzString& symbol, NzString& errorMessage) const; + NzDynLibFunc GetSymbol(const NzString& symbol, NzString* errorMessage) const; bool Load(const NzString& libraryPath, NzString* errorMessage); void Unload(); From b37ec10760911f01c60dbced98d4c30c314cc8b8 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 22 Jan 2015 23:45:32 +0100 Subject: [PATCH 214/233] Oops. Former-commit-id: 81a0e9f5e6cf26ed18633cabbd916881ef6559f3 --- examples/FirstScene/main.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/examples/FirstScene/main.cpp b/examples/FirstScene/main.cpp index 45395cec9..62a4425c8 100644 --- a/examples/FirstScene/main.cpp +++ b/examples/FirstScene/main.cpp @@ -225,11 +225,6 @@ int main() bool smoothMovement = true; NzVector3f targetPos = camera.GetPosition(); - NzTextSprite text; - text.SetParent(scene); - text.Update(NzSimpleTextDrawer::Draw("Hello world !", 72)); - text.Scale(0.1f); - // Début de la boucle de rendu du programme while (window.IsOpen()) { From a39988ac46839b431fbfefae26c26454a6a954e6 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 22 Jan 2015 23:46:55 +0100 Subject: [PATCH 215/233] Removed unused file Former-commit-id: 42b523c8da74800166935602755e554f26d7fa40 --- include/Nazara/Graphics/SceneLayer.hpp | 34 -------------------------- 1 file changed, 34 deletions(-) delete mode 100644 include/Nazara/Graphics/SceneLayer.hpp diff --git a/include/Nazara/Graphics/SceneLayer.hpp b/include/Nazara/Graphics/SceneLayer.hpp deleted file mode 100644 index 20fe359a2..000000000 --- a/include/Nazara/Graphics/SceneLayer.hpp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2014 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_SCENELAYER_HPP -#define NAZARA_SCENELAYER_HPP - -#include - -class NzAbstractRenderTechnique; -class NzAbstractViewer; - -class NAZARA_API NzSceneLayer -{ - public: - NzSceneLayer(); - ~NzSceneLayer(); - - void Draw(); - - nzUInt32 GetBufferClearFlags() const; - NzAbstractRenderQueue* GetRenderQueue() const; - NzAbstractRenderTechnique* GetRenderTechnique() const; - NzScene* GetScene() const; - NzAbstractViewer* GetViewer() const; - - void SetBufferClearFlags(nzUInt32 flags); - void SetRenderTechnique(NzAbstractRenderTechnique* renderTechnique); - void SetViewer(NzAbstractViewer* viewer); -}; - -#endif // NAZARA_SCENELAYER_HPP From c5ec2af361181a179750275d94dd95bc2669b751 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 23 Jan 2015 00:02:33 +0100 Subject: [PATCH 216/233] (Scene) Added RenderFrame method Former-commit-id: ba02b2f0d65858fdabdedf5f0a9f7f9b1baa7268 --- include/Nazara/Graphics/Scene.hpp | 2 ++ src/Nazara/Graphics/Scene.cpp | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/include/Nazara/Graphics/Scene.hpp b/include/Nazara/Graphics/Scene.hpp index 8a9b1b89c..cabe82ebf 100644 --- a/include/Nazara/Graphics/Scene.hpp +++ b/include/Nazara/Graphics/Scene.hpp @@ -57,6 +57,8 @@ class NAZARA_API NzScene void RegisterForUpdate(NzUpdatable* object); + void RenderFrame(); + void SetAmbientColor(const NzColor& color); void SetBackground(NzAbstractBackground* background); void SetRenderTechnique(NzAbstractRenderTechnique* renderTechnique); diff --git a/src/Nazara/Graphics/Scene.cpp b/src/Nazara/Graphics/Scene.cpp index e66a99f03..a89fc5d93 100644 --- a/src/Nazara/Graphics/Scene.cpp +++ b/src/Nazara/Graphics/Scene.cpp @@ -245,6 +245,22 @@ bool NzScene::IsBackgroundEnabled() const return m_impl->backgroundEnabled; } +void NzScene::RenderFrame() +{ + try + { + NzErrorFlags errFlags(nzErrorFlag_ThrowException, true); + Update(); + Cull(); + UpdateVisible(); + Draw(); + } + catch (const std::exception& e) + { + NazaraError("Failed to render frame: " + NzString(e.what())); + } +} + void NzScene::RegisterForUpdate(NzUpdatable* object) { #if NAZARA_GRAPHICS_SAFE From 1f043b61df95eba44721f57ddd44d1a875541c2f Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 23 Jan 2015 14:35:26 +0100 Subject: [PATCH 217/233] (Scene) Removed useless Pimpl idiom Former-commit-id: ffbca2a6b6e16792f58e77195a08911368f64f57 --- include/Nazara/Graphics/Scene.hpp | 25 ++- include/Nazara/Graphics/SceneNode.hpp | 2 +- include/Nazara/Graphics/SceneRoot.hpp | 4 +- .../Graphics/DeferredRenderTechnique.cpp | 1 + .../Graphics/ForwardRenderTechnique.cpp | 1 + src/Nazara/Graphics/ParticleSystem.cpp | 1 + src/Nazara/Graphics/Scene.cpp | 162 ++++++++---------- src/Nazara/Graphics/SkeletalModel.cpp | 1 + src/Nazara/Graphics/Sprite.cpp | 2 + src/Nazara/Graphics/TextSprite.cpp | 2 + 10 files changed, 103 insertions(+), 98 deletions(-) diff --git a/include/Nazara/Graphics/Scene.hpp b/include/Nazara/Graphics/Scene.hpp index cabe82ebf..f317207c0 100644 --- a/include/Nazara/Graphics/Scene.hpp +++ b/include/Nazara/Graphics/Scene.hpp @@ -8,11 +8,15 @@ #define NAZARA_SCENE_HPP #include +#include #include #include #include #include +#include #include +#include +#include class NzAbstractRenderQueue; class NzAbstractViewer; @@ -22,7 +26,6 @@ class NzModel; class NzNode; class NzRenderQueue; class NzSceneNode; -struct NzSceneImpl; class NAZARA_API NzScene { @@ -30,7 +33,7 @@ class NAZARA_API NzScene public: NzScene(); - ~NzScene(); + ~NzScene() = default; void AddToVisibilityList(NzUpdatable* object); @@ -47,7 +50,8 @@ class NAZARA_API NzScene NzVector3f GetLeft() const; NzAbstractRenderTechnique* GetRenderTechnique() const; NzVector3f GetRight() const; - NzSceneNode& GetRoot() const; + NzSceneNode& GetRoot(); + const NzSceneNode& GetRoot() const; NzAbstractViewer* GetViewer() const; NzVector3f GetUp() const; float GetUpdateTime() const; @@ -76,7 +80,20 @@ class NAZARA_API NzScene private: void RecursiveFrustumCull(NzAbstractRenderQueue* renderQueue, const NzFrustumf& frustum, NzNode* node); - NzSceneImpl* m_impl; + mutable std::unique_ptr m_background; + mutable std::unique_ptr m_renderTechnique; + std::vector m_updateList; + std::vector m_visibleUpdateList; + NzClock m_updateClock; + NzColor m_ambientColor; + NzSceneRoot m_root; + NzAbstractViewer* m_viewer; + bool m_backgroundEnabled; + bool m_update; + float m_frameTime; + float m_updateTime; + mutable int m_renderTechniqueRanking; + unsigned int m_updatePerSecond; }; #endif // NAZARA_SCENE_HPP diff --git a/include/Nazara/Graphics/SceneNode.hpp b/include/Nazara/Graphics/SceneNode.hpp index 3cbfde9e9..ccb62806e 100644 --- a/include/Nazara/Graphics/SceneNode.hpp +++ b/include/Nazara/Graphics/SceneNode.hpp @@ -9,11 +9,11 @@ #include #include -#include #include #include #include +class NzAbstractRenderQueue; class NzScene; class NAZARA_API NzSceneNode : public NzNode diff --git a/include/Nazara/Graphics/SceneRoot.hpp b/include/Nazara/Graphics/SceneRoot.hpp index 9e09281ac..28aa9b20e 100644 --- a/include/Nazara/Graphics/SceneRoot.hpp +++ b/include/Nazara/Graphics/SceneRoot.hpp @@ -10,9 +10,11 @@ #include #include +class NzScene; + class NAZARA_API NzSceneRoot : public NzSceneNode { - friend struct NzSceneImpl; + friend NzScene; public: void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; diff --git a/src/Nazara/Graphics/DeferredRenderTechnique.cpp b/src/Nazara/Graphics/DeferredRenderTechnique.cpp index d05b39fe7..cb86db239 100644 --- a/src/Nazara/Graphics/DeferredRenderTechnique.cpp +++ b/src/Nazara/Graphics/DeferredRenderTechnique.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 09e4e7910..d5de9bc65 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/src/Nazara/Graphics/ParticleSystem.cpp b/src/Nazara/Graphics/ParticleSystem.cpp index 1ded1113b..2fa2e9601 100644 --- a/src/Nazara/Graphics/ParticleSystem.cpp +++ b/src/Nazara/Graphics/ParticleSystem.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/src/Nazara/Graphics/Scene.cpp b/src/Nazara/Graphics/Scene.cpp index a89fc5d93..33624d6bd 100644 --- a/src/Nazara/Graphics/Scene.cpp +++ b/src/Nazara/Graphics/Scene.cpp @@ -9,57 +9,30 @@ #include #include #include -#include #include #include #include -#include -#include -#include #include -struct NzSceneImpl +NzScene::NzScene() : +m_ambientColor(25, 25, 25), +m_root(this), +m_viewer(nullptr), +m_backgroundEnabled(true), +m_update(false), +m_updatePerSecond(60) { - NzSceneImpl(NzScene* scene) : - root(scene) - { - } - - std::unique_ptr background; - std::unique_ptr renderTechnique; - std::vector updateList; - std::vector visibleUpdateList; - NzClock updateClock; - NzColor ambientColor = NzColor(25,25,25); - NzSceneRoot root; - NzAbstractViewer* viewer = nullptr; - bool backgroundEnabled = true; - bool update = false; - float frameTime; - float updateTime; - int renderTechniqueRanking; - unsigned int updatePerSecond = 60; -}; - -NzScene::NzScene() -{ - m_impl = new NzSceneImpl(this); -} - -NzScene::~NzScene() -{ - delete m_impl; } void NzScene::AddToVisibilityList(NzUpdatable* object) { - m_impl->visibleUpdateList.push_back(object); + m_visibleUpdateList.push_back(object); } void NzScene::Cull() { #if NAZARA_GRAPHICS_SAFE - if (!m_impl->viewer) + if (!m_viewer) { NazaraError("No viewer"); return; @@ -69,10 +42,10 @@ void NzScene::Cull() NzAbstractRenderQueue* renderQueue = GetRenderTechnique()->GetRenderQueue(); renderQueue->Clear(false); - m_impl->visibleUpdateList.clear(); + m_visibleUpdateList.clear(); // Frustum culling - RecursiveFrustumCull(renderQueue, m_impl->viewer->GetFrustum(), &m_impl->root); + RecursiveFrustumCull(renderQueue, m_viewer->GetFrustum(), &m_root); ///TODO: Occlusion culling @@ -82,29 +55,29 @@ void NzScene::Cull() void NzScene::Draw() { #if NAZARA_GRAPHICS_SAFE - if (!m_impl->viewer) + if (!m_viewer) { NazaraError("No viewer"); return; } #endif - m_impl->viewer->ApplyView(); + m_viewer->ApplyView(); try { - NzErrorFlags errFlags(nzErrorFlag_ThrowException); - m_impl->renderTechnique->Clear(this); - m_impl->renderTechnique->Draw(this); + NzErrorFlags errFlags(nzErrorFlag_ThrowException, true); + m_renderTechnique->Clear(this); + m_renderTechnique->Draw(this); } catch (const std::exception& e) { - NzString oldName = m_impl->renderTechnique->GetName(); + NzString oldName = m_renderTechnique->GetName(); - if (m_impl->renderTechniqueRanking > 0) + if (m_renderTechniqueRanking > 0) { - m_impl->renderTechnique.reset(NzRenderTechniques::GetByRanking(m_impl->renderTechniqueRanking-1, &m_impl->renderTechniqueRanking)); - NazaraError("Render technique \"" + oldName + "\" failed, fallback to \"" + m_impl->renderTechnique->GetName() + '"'); + m_renderTechnique.reset(NzRenderTechniques::GetByRanking(m_renderTechniqueRanking-1, &m_renderTechniqueRanking)); + NazaraError("Render technique \"" + oldName + "\" failed, fallback to \"" + m_renderTechnique->GetName() + '"'); } else { @@ -118,131 +91,136 @@ void NzScene::Draw() void NzScene::EnableBackground(bool enable) { - m_impl->backgroundEnabled = enable; + m_backgroundEnabled = enable; } NzColor NzScene::GetAmbientColor() const { - return m_impl->ambientColor; + return m_ambientColor; } NzAbstractBackground* NzScene::GetBackground() const { - if (!m_impl->background) - m_impl->background.reset(new NzColorBackground); + if (!m_background) + m_background.reset(new NzColorBackground); - return m_impl->background.get(); + return m_background.get(); } NzVector3f NzScene::GetBackward() const { #if NAZARA_GRAPHICS_SAFE - if (!m_impl->viewer) + if (!m_viewer) { NazaraError("No viewer"); return NzVector3f::Backward(); } #endif - return -m_impl->viewer->GetGlobalForward(); + return -m_viewer->GetGlobalForward(); } NzVector3f NzScene::GetDown() const { #if NAZARA_GRAPHICS_SAFE - if (!m_impl->viewer) + if (!m_viewer) { NazaraError("No viewer"); return NzVector3f::Down(); } #endif - return -m_impl->viewer->GetGlobalUp(); + return -m_viewer->GetGlobalUp(); } NzVector3f NzScene::GetForward() const { #if NAZARA_GRAPHICS_SAFE - if (!m_impl->viewer) + if (!m_viewer) { NazaraError("No viewer"); return NzVector3f::Forward(); } #endif - return m_impl->viewer->GetGlobalForward(); + return m_viewer->GetGlobalForward(); } NzVector3f NzScene::GetLeft() const { #if NAZARA_GRAPHICS_SAFE - if (!m_impl->viewer) + if (!m_viewer) { NazaraError("No viewer"); return NzVector3f::Left(); } #endif - return -m_impl->viewer->GetGlobalRight(); + return -m_viewer->GetGlobalRight(); } NzAbstractRenderTechnique* NzScene::GetRenderTechnique() const { - if (!m_impl->renderTechnique) - m_impl->renderTechnique.reset(NzRenderTechniques::GetByRanking(-1, &m_impl->renderTechniqueRanking)); + if (!m_renderTechnique) + m_renderTechnique.reset(NzRenderTechniques::GetByRanking(-1, &m_renderTechniqueRanking)); - return m_impl->renderTechnique.get(); + return m_renderTechnique.get(); } NzVector3f NzScene::GetRight() const { #if NAZARA_GRAPHICS_SAFE - if (!m_impl->viewer) + if (!m_viewer) { NazaraError("No viewer"); return NzVector3f::Right(); } #endif - return m_impl->viewer->GetGlobalRight(); + return m_viewer->GetGlobalRight(); } -NzSceneNode& NzScene::GetRoot() const +NzSceneNode& NzScene::GetRoot() { - return m_impl->root; + return m_root; +} + +const NzSceneNode& NzScene::GetRoot() const +{ + return m_root; } NzAbstractViewer* NzScene::GetViewer() const { - return m_impl->viewer; + return m_viewer; } NzVector3f NzScene::GetUp() const { #if NAZARA_GRAPHICS_SAFE - if (!m_impl->viewer) + if (!m_viewer) { NazaraError("No viewer"); return NzVector3f::Up(); } #endif - return m_impl->viewer->GetGlobalUp(); + return m_viewer->GetGlobalUp(); } float NzScene::GetUpdateTime() const { - return m_impl->updateTime; + return m_updateTime; } unsigned int NzScene::GetUpdatePerSecond() const { - return m_impl->updatePerSecond; + return m_updatePerSecond; } bool NzScene::IsBackgroundEnabled() const { - return m_impl->backgroundEnabled; + return m_backgroundEnabled; } void NzScene::RenderFrame() @@ -271,32 +249,32 @@ void NzScene::RegisterForUpdate(NzUpdatable* object) } #endif - m_impl->updateList.push_back(object); + m_updateList.push_back(object); } void NzScene::SetAmbientColor(const NzColor& color) { - m_impl->ambientColor = color; + m_ambientColor = color; } void NzScene::SetBackground(NzAbstractBackground* background) { - m_impl->background.reset(background); + m_background.reset(background); } void NzScene::SetRenderTechnique(NzAbstractRenderTechnique* renderTechnique) { - m_impl->renderTechnique.reset(renderTechnique); + m_renderTechnique.reset(renderTechnique); } void NzScene::SetViewer(NzAbstractViewer* viewer) { - if (m_impl->viewer != viewer) + if (m_viewer != viewer) { - m_impl->viewer = viewer; + m_viewer = viewer; // Invalidation de tous les nodes de la scène (utile pour la régénération des sommets dépendant du viewer) - m_impl->root.InvalidateNode(); + m_root.InvalidateNode(); } } @@ -307,7 +285,7 @@ void NzScene::SetViewer(NzAbstractViewer& viewer) void NzScene::SetUpdatePerSecond(unsigned int updatePerSecond) { - m_impl->updatePerSecond = updatePerSecond; + m_updatePerSecond = updatePerSecond; } void NzScene::UnregisterForUpdate(NzUpdatable* object) @@ -320,20 +298,20 @@ void NzScene::UnregisterForUpdate(NzUpdatable* object) } #endif - auto it = std::find(m_impl->updateList.begin(), m_impl->updateList.end(), object); - if (it != m_impl->updateList.end()) - m_impl->updateList.erase(it); + auto it = std::find(m_updateList.begin(), m_updateList.end(), object); + if (it != m_updateList.end()) + m_updateList.erase(it); } void NzScene::Update() { - m_impl->update = (m_impl->updatePerSecond == 0 || m_impl->updateClock.GetMilliseconds() > 1000/m_impl->updatePerSecond); - if (m_impl->update) + m_update = (m_updatePerSecond == 0 || m_updateClock.GetMilliseconds() > 1000/m_updatePerSecond); + if (m_update) { - m_impl->updateTime = m_impl->updateClock.GetSeconds(); - m_impl->updateClock.Restart(); + m_updateTime = m_updateClock.GetSeconds(); + m_updateClock.Restart(); - for (NzUpdatable* updatable : m_impl->updateList) + for (NzUpdatable* updatable : m_updateList) ///TODO: Multihreading updatable->Update(); } @@ -343,16 +321,16 @@ void NzScene::UpdateVisible() { NzSkinningManager::Skin(); - if (m_impl->update) + if (m_update) { - for (NzUpdatable* node : m_impl->visibleUpdateList) + for (NzUpdatable* node : m_visibleUpdateList) node->Update(); } } NzScene::operator const NzSceneNode&() const { - return m_impl->root; + return m_root; } void NzScene::RecursiveFrustumCull(NzAbstractRenderQueue* renderQueue, const NzFrustumf& frustum, NzNode* node) diff --git a/src/Nazara/Graphics/SkeletalModel.cpp b/src/Nazara/Graphics/SkeletalModel.cpp index 16b01f01f..07e8b76ef 100644 --- a/src/Nazara/Graphics/SkeletalModel.cpp +++ b/src/Nazara/Graphics/SkeletalModel.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include diff --git a/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index d660adc23..e3ec9752b 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -3,7 +3,9 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include +#include #include #include #include diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index ac3b67a35..fb0f64f1e 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -5,7 +5,9 @@ #include #include #include +#include #include +#include #include #include #include From f6df10dacf55227ffc441a12fdf8280abc23ffc9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 23 Jan 2015 20:07:24 +0100 Subject: [PATCH 218/233] Removed unused file Former-commit-id: 374fc27dca13c38dfa94928841cefb031e7b32ed --- include/Nazara/Graphics.hpp | 1 - include/Nazara/Graphics/SceneLayer.hpp | 34 -------------------------- 2 files changed, 35 deletions(-) delete mode 100644 include/Nazara/Graphics/SceneLayer.hpp diff --git a/include/Nazara/Graphics.hpp b/include/Nazara/Graphics.hpp index 7e3bf9370..202f07a8c 100644 --- a/include/Nazara/Graphics.hpp +++ b/include/Nazara/Graphics.hpp @@ -59,7 +59,6 @@ #include #include #include -#include #include #include #include diff --git a/include/Nazara/Graphics/SceneLayer.hpp b/include/Nazara/Graphics/SceneLayer.hpp deleted file mode 100644 index 20046057e..000000000 --- a/include/Nazara/Graphics/SceneLayer.hpp +++ /dev/null @@ -1,34 +0,0 @@ -// 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_SCENELAYER_HPP -#define NAZARA_SCENELAYER_HPP - -#include - -class NzAbstractRenderTechnique; -class NzAbstractViewer; - -class NAZARA_API NzSceneLayer -{ - public: - NzSceneLayer(); - ~NzSceneLayer(); - - void Draw(); - - nzUInt32 GetBufferClearFlags() const; - NzAbstractRenderQueue* GetRenderQueue() const; - NzAbstractRenderTechnique* GetRenderTechnique() const; - NzScene* GetScene() const; - NzAbstractViewer* GetViewer() const; - - void SetBufferClearFlags(nzUInt32 flags); - void SetRenderTechnique(NzAbstractRenderTechnique* renderTechnique); - void SetViewer(NzAbstractViewer* viewer); -}; - -#endif // NAZARA_SCENELAYER_HPP From 01a1badac7b0326c04ae776a8e2a1ad22a1a262b Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 23 Jan 2015 20:21:00 +0100 Subject: [PATCH 219/233] Removed useless std::function from rendering code Former-commit-id: eaba729d5047d326fb2e746cec0621bfcf2eb1c5 --- include/Nazara/Renderer/Renderer.hpp | 3 +++ src/Nazara/Graphics/DeferredGeometryPass.cpp | 12 ++++++------ src/Nazara/Graphics/ForwardRenderTechnique.cpp | 18 +++++++++--------- 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/include/Nazara/Renderer/Renderer.hpp b/include/Nazara/Renderer/Renderer.hpp index 2b5625ea2..50f8b0717 100644 --- a/include/Nazara/Renderer/Renderer.hpp +++ b/include/Nazara/Renderer/Renderer.hpp @@ -31,6 +31,9 @@ class NAZARA_API NzRenderer friend NzTexture; public: + using DrawCall = void (*)(nzPrimitiveMode, unsigned int, unsigned int); + using DrawCallInstanced = void (*)(unsigned int, nzPrimitiveMode, unsigned int, unsigned int); + NzRenderer() = delete; ~NzRenderer() = delete; diff --git a/src/Nazara/Graphics/DeferredGeometryPass.cpp b/src/Nazara/Graphics/DeferredGeometryPass.cpp index 93052d322..c38c45cdd 100644 --- a/src/Nazara/Graphics/DeferredGeometryPass.cpp +++ b/src/Nazara/Graphics/DeferredGeometryPass.cpp @@ -101,20 +101,20 @@ bool NzDeferredGeometryPass::Process(const NzScene* scene, unsigned int firstWor const NzVertexBuffer* vertexBuffer = meshData.vertexBuffer; // Gestion du draw call avant la boucle de rendu - std::function DrawFunc; - std::function InstancedDrawFunc; + NzRenderer::DrawCall drawFunc; + NzRenderer::DrawCallInstanced instancedDrawFunc; unsigned int indexCount; if (indexBuffer) { - DrawFunc = NzRenderer::DrawIndexedPrimitives; - InstancedDrawFunc = NzRenderer::DrawIndexedPrimitivesInstanced; + drawFunc = NzRenderer::DrawIndexedPrimitives; + instancedDrawFunc = NzRenderer::DrawIndexedPrimitivesInstanced; indexCount = indexBuffer->GetIndexCount(); } else { - DrawFunc = NzRenderer::DrawPrimitives; - InstancedDrawFunc = NzRenderer::DrawPrimitivesInstanced; + drawFunc = NzRenderer::DrawPrimitives; + instancedDrawFunc = NzRenderer::DrawPrimitivesInstanced; indexCount = vertexBuffer->GetVertexCount(); } diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 22f2a1234..2144d5803 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -470,20 +470,20 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const const NzVertexBuffer* vertexBuffer = meshData.vertexBuffer; // Gestion du draw call avant la boucle de rendu - std::function DrawFunc; - std::function InstancedDrawFunc; + NzRenderer::DrawCall drawFunc; + NzRenderer::DrawCallInstanced instancedDrawFunc; unsigned int indexCount; if (indexBuffer) { - DrawFunc = NzRenderer::DrawIndexedPrimitives; - InstancedDrawFunc = NzRenderer::DrawIndexedPrimitivesInstanced; + drawFunc = NzRenderer::DrawIndexedPrimitives; + instancedDrawFunc = NzRenderer::DrawIndexedPrimitivesInstanced; indexCount = indexBuffer->GetIndexCount(); } else { - DrawFunc = NzRenderer::DrawPrimitives; - InstancedDrawFunc = NzRenderer::DrawPrimitivesInstanced; + drawFunc = NzRenderer::DrawPrimitives; + instancedDrawFunc = NzRenderer::DrawPrimitivesInstanced; indexCount = vertexBuffer->GetVertexCount(); } @@ -672,17 +672,17 @@ void NzForwardRenderTechnique::DrawTransparentModels(const NzScene* scene) const const NzVertexBuffer* vertexBuffer = meshData.vertexBuffer; // Gestion du draw call avant la boucle de rendu - std::function DrawFunc; + NzRenderer::DrawCall drawFunc; unsigned int indexCount; if (indexBuffer) { - DrawFunc = NzRenderer::DrawIndexedPrimitives; + drawFunc = NzRenderer::DrawIndexedPrimitives; indexCount = indexBuffer->GetIndexCount(); } else { - DrawFunc = NzRenderer::DrawPrimitives; + drawFunc = NzRenderer::DrawPrimitives; indexCount = vertexBuffer->GetVertexCount(); } From d1f1906f370dc7c658ebb5ffd705632caf4e34c4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 23 Jan 2015 20:21:19 +0100 Subject: [PATCH 220/233] Fixed comment Former-commit-id: a587575ad7e7c651eaf9c5cb9483a002615e4d4a --- include/Nazara/Utility/PixelFormat.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/Nazara/Utility/PixelFormat.hpp b/include/Nazara/Utility/PixelFormat.hpp index c84f20d38..3e1aa254f 100644 --- a/include/Nazara/Utility/PixelFormat.hpp +++ b/include/Nazara/Utility/PixelFormat.hpp @@ -14,8 +14,8 @@ #include ///TODO: Permettre la conversion automatique entre les formats via des renseignements de bits et de type pour chaque format. -/// Ce serait plus lent que la conversion spécialisée (qui ne disparaît donc pas) mais ça permettrait au moteur de faire la conversion -/// entre n'importe quel formats non-compressés. +/// Ce serait plus lent que la conversion spécialisée (qui ne disparaîtra donc pas) mais ça permettrait au moteur de faire la conversion +/// entre n'importe quels formats non-compressés. class NzPixelFormat { From cf12552358b9bbedf833581de04e6d61f19cfc17 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 23 Jan 2015 21:04:29 +0100 Subject: [PATCH 221/233] (SceneNode) Added virtual constructor idiom (Light) Added default constructor Former-commit-id: 591e6a8435d2cea6238e70c0058d381b8d547f3e --- include/Nazara/Graphics/Light.hpp | 5 ++++- include/Nazara/Graphics/Model.hpp | 3 +++ include/Nazara/Graphics/SceneNode.hpp | 4 ++++ include/Nazara/Graphics/SceneRoot.hpp | 3 +++ include/Nazara/Graphics/Sprite.hpp | 3 +++ include/Nazara/Graphics/TextSprite.hpp | 3 +++ src/Nazara/Graphics/Light.cpp | 10 ++++++++++ src/Nazara/Graphics/Model.cpp | 10 ++++++++++ src/Nazara/Graphics/SceneRoot.cpp | 12 ++++++++++++ src/Nazara/Graphics/Sprite.cpp | 10 ++++++++++ src/Nazara/Graphics/TextSprite.cpp | 10 ++++++++++ 11 files changed, 72 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Graphics/Light.hpp b/include/Nazara/Graphics/Light.hpp index 9db57e7c6..40ec4e525 100644 --- a/include/Nazara/Graphics/Light.hpp +++ b/include/Nazara/Graphics/Light.hpp @@ -18,12 +18,15 @@ struct NzLightUniforms; class NAZARA_API NzLight : public NzSceneNode { public: - NzLight(nzLightType type); + NzLight(nzLightType type = nzLightType_Point); NzLight(const NzLight& light); ~NzLight() = default; void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; + NzLight* Clone() const; + NzLight* Create() const; + void Enable(const NzShader* shader, const NzLightUniforms& uniforms, int offset = 0) const; float GetAmbientFactor() const; diff --git a/include/Nazara/Graphics/Model.hpp b/include/Nazara/Graphics/Model.hpp index 5b193f5ee..d209530a1 100644 --- a/include/Nazara/Graphics/Model.hpp +++ b/include/Nazara/Graphics/Model.hpp @@ -41,6 +41,9 @@ class NAZARA_API NzModel : public NzSceneNode void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; void AdvanceAnimation(float elapsedTime); + NzModel* Clone() const; + NzModel* Create() const; + void EnableAnimation(bool animation); NzAnimation* GetAnimation() const; diff --git a/include/Nazara/Graphics/SceneNode.hpp b/include/Nazara/Graphics/SceneNode.hpp index ccb62806e..0a771a00e 100644 --- a/include/Nazara/Graphics/SceneNode.hpp +++ b/include/Nazara/Graphics/SceneNode.hpp @@ -28,6 +28,10 @@ class NAZARA_API NzSceneNode : public NzNode virtual void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const = 0; + // Idiôme "virtual constructor" + virtual NzSceneNode* Clone() const = 0; + virtual NzSceneNode* Create() const = 0; + void EnableDrawing(bool drawingEnabled); NzVector3f GetBackward() const; diff --git a/include/Nazara/Graphics/SceneRoot.hpp b/include/Nazara/Graphics/SceneRoot.hpp index 28aa9b20e..9e4f6b960 100644 --- a/include/Nazara/Graphics/SceneRoot.hpp +++ b/include/Nazara/Graphics/SceneRoot.hpp @@ -27,6 +27,9 @@ class NAZARA_API NzSceneRoot : public NzSceneNode NzSceneRoot(NzScene* scene); virtual ~NzSceneRoot(); + NzSceneRoot* Clone() const; + NzSceneRoot* Create() const; + void MakeBoundingVolume() const override; void Register(); void Unregister(); diff --git a/include/Nazara/Graphics/Sprite.hpp b/include/Nazara/Graphics/Sprite.hpp index 69c51fa90..2beb4c85d 100644 --- a/include/Nazara/Graphics/Sprite.hpp +++ b/include/Nazara/Graphics/Sprite.hpp @@ -22,6 +22,9 @@ class NAZARA_API NzSprite : public NzSceneNode void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; + NzSprite* Clone() const; + NzSprite* Create() const; + const NzColor& GetColor() const; NzMaterial* GetMaterial() const; nzSceneNodeType GetSceneNodeType() const override; diff --git a/include/Nazara/Graphics/TextSprite.hpp b/include/Nazara/Graphics/TextSprite.hpp index 23ce1a7f3..2b7f33e09 100644 --- a/include/Nazara/Graphics/TextSprite.hpp +++ b/include/Nazara/Graphics/TextSprite.hpp @@ -28,6 +28,9 @@ class NAZARA_API NzTextSprite : public NzSceneNode, NzAbstractAtlas::Listener void Clear(); + NzTextSprite* Clone() const; + NzTextSprite* Create() const; + const NzColor& GetColor() const; NzMaterial* GetMaterial() const; nzSceneNodeType GetSceneNodeType() const override; diff --git a/src/Nazara/Graphics/Light.cpp b/src/Nazara/Graphics/Light.cpp index 73df7e784..3f2e7ad2d 100644 --- a/src/Nazara/Graphics/Light.cpp +++ b/src/Nazara/Graphics/Light.cpp @@ -47,6 +47,16 @@ void NzLight::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const renderQueue->AddLight(this); } +NzLight* NzLight::Clone() const +{ + return new NzLight(*this); +} + +NzLight* NzLight::Create() const +{ + return new NzLight; +} + void NzLight::Enable(const NzShader* shader, const NzLightUniforms& uniforms, int offset) const { /* diff --git a/src/Nazara/Graphics/Model.cpp b/src/Nazara/Graphics/Model.cpp index 6bddc09cc..137dff795 100644 --- a/src/Nazara/Graphics/Model.cpp +++ b/src/Nazara/Graphics/Model.cpp @@ -66,6 +66,16 @@ void NzModel::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const } } +NzModel* NzModel::Clone() const +{ + return new NzModel(*this); +} + +NzModel* NzModel::Create() const +{ + return new NzModel; +} + NzMaterial* NzModel::GetMaterial(const NzString& subMeshName) const { #if NAZARA_GRAPHICS_SAFE diff --git a/src/Nazara/Graphics/SceneRoot.cpp b/src/Nazara/Graphics/SceneRoot.cpp index 5bb63f624..cdf9f5eb5 100644 --- a/src/Nazara/Graphics/SceneRoot.cpp +++ b/src/Nazara/Graphics/SceneRoot.cpp @@ -30,6 +30,18 @@ bool NzSceneRoot::IsDrawable() const return true; } +NzSceneRoot* NzSceneRoot::Clone() const +{ + NazaraInternalError("SceneNode::Clone() called on SceneRoot"); + return nullptr; +} + +NzSceneRoot* NzSceneRoot::Create() const +{ + NazaraInternalError("SceneNode::Create() called on SceneRoot"); + return nullptr; +} + void NzSceneRoot::MakeBoundingVolume() const { m_boundingVolume.MakeInfinite(); diff --git a/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index e3ec9752b..716bf9d5b 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -48,6 +48,16 @@ void NzSprite::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const renderQueue->AddSprites(m_material, m_vertices, 1); } +NzSprite* NzSprite::Clone() const +{ + return new NzSprite(*this); +} + +NzSprite* NzSprite::Create() const +{ + return new NzSprite; +} + const NzColor& NzSprite::GetColor() const { return m_color; diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index fb0f64f1e..f6fbb33fd 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -65,6 +65,16 @@ void NzTextSprite::Clear() m_vertices.clear(); } +NzTextSprite* NzTextSprite::Clone() const +{ + return new NzTextSprite(*this); +} + +NzTextSprite* NzTextSprite::Create() const +{ + return new NzTextSprite; +} + const NzColor& NzTextSprite::GetColor() const { return m_color; From 0a7711d85bec7ae6e9d2678a80a44d28a0044091 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 23 Jan 2015 22:35:41 +0100 Subject: [PATCH 222/233] (Scene) Added CreateNode and Clear methods Former-commit-id: de92f4a4be45e5cbd1d2d83191300e0b46764f0e --- examples/FirstScene/main.cpp | 23 +++---- include/Nazara/Graphics/Scene.hpp | 13 ++++ include/Nazara/Graphics/Scene.inl | 107 ++++++++++++++++++++++++++++++ src/Nazara/Graphics/Scene.cpp | 29 +++++++- 4 files changed, 154 insertions(+), 18 deletions(-) create mode 100644 include/Nazara/Graphics/Scene.inl diff --git a/examples/FirstScene/main.cpp b/examples/FirstScene/main.cpp index 62a4425c8..9ed702a69 100644 --- a/examples/FirstScene/main.cpp +++ b/examples/FirstScene/main.cpp @@ -84,7 +84,7 @@ int main() // Ensuite, nous allons rajouter un modèle à notre scène. // Les modèles représentent, globalement, tout ce qui est visible en trois dimensions. // Nous choisirons ici un vaisseau spatial (Quoi de mieux pour une scène spatiale ?) - NzModel spaceship; + NzModel* spaceship = scene.CreateNode(); // Création depuis la scène // Une structure permettant de paramétrer le chargement des modèles NzModelParameters params; @@ -101,7 +101,7 @@ int main() // On charge ensuite le modèle depuis son fichier // Le moteur va charger le fichier et essayer de retrouver les fichiers associés (comme les matériaux, textures, ...) - if (!spaceship.LoadFromFile("resources/Spaceship/spaceship.obj", params)) + if (!spaceship->LoadFromFile("resources/Spaceship/spaceship.obj", params)) { std::cout << "Failed to load spaceship" << std::endl; std::getchar(); @@ -111,7 +111,7 @@ int main() // Nous voulons afficher quelques statistiques relatives au modèle, comme le nombre de sommets et de triangles // Pour cela, nous devons accéder au mesh (maillage 3D) - NzMesh* mesh = spaceship.GetMesh(); + NzMesh* mesh = spaceship->GetMesh(); std::cout << mesh->GetVertexCount() << " sommets" << std::endl; std::cout << mesh->GetTriangleCount() << " triangles" << std::endl; @@ -119,7 +119,7 @@ int main() // En revanche, le format OBJ ne précise pas l'utilisation d'une normal map, nous devons donc la charger manuellement // Pour commencer on récupère le matériau du mesh, celui-ci en possède plusieurs mais celui qui nous intéresse, // celui de la coque, est le second (Cela est bien entendu lié au modèle en lui-même) - NzMaterial* material = spaceship.GetMaterial(1); + NzMaterial* material = spaceship->GetMaterial(1); // On lui indique ensuite le chemin vers la normal map if (!material->SetNormalMap("resources/Spaceship/Texture/normal.png")) @@ -129,10 +129,6 @@ int main() std::cout << "Failed to load normal map" << std::endl; } - // Il nous reste à attacher le modèle à la scène, ce qui se fait simplement via cet appel - spaceship.SetParent(scene); - // Et voilà, à partir de maintenant le modèle fait partie de la hiérarchie de la scène, et sera donc rendu avec cette dernière - // Nous avons besoin également d'une caméra, pour des raisons évidentes, celle-ci sera à l'écart du modèle // regardant dans sa direction. @@ -164,18 +160,15 @@ int main() // -PointLight: Lumière située à un endroit précis, envoyant de la lumière finie dans toutes les directions // -SpotLight: Lumière située à un endroit précis, envoyant de la lumière vers un endroit donné, avec un angle de diffusion - // Nous choisissons une lumière directionnelle représentant la nébuleuse de notre skybox - NzLight nebulaLight(nzLightType_Directional); + // Nous créons une lumière directionnelle pour représenter la nébuleuse de notre skybox + NzLight* nebulaLight = scene.CreateNode(nzLightType_Directional); // Il nous faut ensuite configurer la lumière // Pour commencer, sa couleur, la nébuleuse étant d'une couleur jaune, j'ai choisi ces valeurs - nebulaLight.SetColor(NzColor(255, 182, 90)); + nebulaLight->SetColor(NzColor(255, 182, 90)); // Nous appliquons ensuite une rotation de sorte que la lumière dans la même direction que la nébuleuse - nebulaLight.SetRotation(NzEulerAnglesf(0.f, 102.f, 0.f)); - - // Et nous ajoutons la lumière à la scène - nebulaLight.SetParent(scene); + nebulaLight->SetRotation(NzEulerAnglesf(0.f, 102.f, 0.f)); // Nous allons maintenant créer la fenêtre, dans laquelle nous ferons nos rendus // Celle-ci demande des paramètres plus complexes diff --git a/include/Nazara/Graphics/Scene.hpp b/include/Nazara/Graphics/Scene.hpp index f317207c0..03b37bfc4 100644 --- a/include/Nazara/Graphics/Scene.hpp +++ b/include/Nazara/Graphics/Scene.hpp @@ -10,12 +10,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include class NzAbstractRenderQueue; @@ -37,6 +39,12 @@ class NAZARA_API NzScene void AddToVisibilityList(NzUpdatable* object); + template T* CreateNode(Args&&... args); + template T* CreateNode(const NzString& name, Args&&... args); + template T* CreateNode(const NzString& name, const NzString& templateNodeName); + + void Clear(); + void Cull(); void Draw(); @@ -78,10 +86,13 @@ class NAZARA_API NzScene operator const NzSceneNode&() const; private: + bool RegisterSceneNode(const NzString& name, NzSceneNode* node); void RecursiveFrustumCull(NzAbstractRenderQueue* renderQueue, const NzFrustumf& frustum, NzNode* node); mutable std::unique_ptr m_background; mutable std::unique_ptr m_renderTechnique; + std::unordered_map m_nodeMap; + std::vector> m_nodes; std::vector m_updateList; std::vector m_visibleUpdateList; NzClock m_updateClock; @@ -96,4 +107,6 @@ class NAZARA_API NzScene unsigned int m_updatePerSecond; }; +#include + #endif // NAZARA_SCENE_HPP diff --git a/include/Nazara/Graphics/Scene.inl b/include/Nazara/Graphics/Scene.inl new file mode 100644 index 000000000..3ac7be7af --- /dev/null +++ b/include/Nazara/Graphics/Scene.inl @@ -0,0 +1,107 @@ +// 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 + +///TODO: Déplacer vers SceneNode et exposer + +// Pour être sûr que ce code soit à jour +static_assert(nzSceneNodeType_Max == 6, "Please update the code below"); + +class NzLight; +class NzModel; +class NzParticleEmitter; +class NzSceneRoot; +class NzSprite; +class NzTextSprite; + +template +constexpr nzSceneNodeType NzImplGetType() +{ + return nzSceneNodeType_User; +} + +template<> +inline constexpr nzSceneNodeType NzImplGetType() +{ + return nzSceneNodeType_Light; +} + +template<> +inline constexpr nzSceneNodeType NzImplGetType() +{ + return nzSceneNodeType_Model; +} + +template<> +inline constexpr nzSceneNodeType NzImplGetType() +{ + return nzSceneNodeType_ParticleEmitter; +} + +template<> +inline constexpr nzSceneNodeType NzImplGetType() +{ + return nzSceneNodeType_Root; +} + +template<> +inline constexpr nzSceneNodeType NzImplGetType() +{ + return nzSceneNodeType_Sprite; +} + +template<> +inline constexpr nzSceneNodeType NzImplGetType() +{ + return nzSceneNodeType_TextSprite; +} + + +template +T* NzScene::CreateNode(Args&&... args) +{ + std::unique_ptr node(new T(std::forward(args)...)); + if (!RegisterSceneNode(NzString(), node.get())) + return nullptr; + + return node.release(); +} + +template +T* NzScene::CreateNode(const NzString& name, Args&&... args) +{ + std::unique_ptr node(new T(std::forward(args)...)); + if (!RegisterSceneNode(name, node.get())) + return nullptr; + + return node.release(); +} + +template +T* NzScene::CreateNode(const NzString& name, const NzString& templateNodeName) +{ + auto it = m_nodeMap.find(templateNodeName); + if (it == m_nodeMap.end()) + { + NazaraError("Node \"" + templateNodeName + "\" is not registred"); + return nullptr; + } + + NzSceneNode* sceneNode = it->second; + if (NzImplGetType() != sceneNode->GetSceneNodeType()) + { + NazaraError("Scene node type of T (" + NzString::Number(NzImplGetType()) + ") doesn't match template scene node type (" + NzString::Number(sceneNode->GetSceneNodeType()) + ")"); + return nullptr; + } + + std::unique_ptr node(static_cast(sceneNode)->Copy()); + if (!RegisterSceneNode(name, node.get())) + return nullptr; + + return node.release(); +} + +#include diff --git a/src/Nazara/Graphics/Scene.cpp b/src/Nazara/Graphics/Scene.cpp index 33624d6bd..4b86cdda5 100644 --- a/src/Nazara/Graphics/Scene.cpp +++ b/src/Nazara/Graphics/Scene.cpp @@ -29,6 +29,12 @@ void NzScene::AddToVisibilityList(NzUpdatable* object) m_visibleUpdateList.push_back(object); } +void NzScene::Clear() +{ + m_nodeMap.clear(); + m_nodes.clear(); +} + void NzScene::Cull() { #if NAZARA_GRAPHICS_SAFE @@ -48,8 +54,6 @@ void NzScene::Cull() RecursiveFrustumCull(renderQueue, m_viewer->GetFrustum(), &m_root); ///TODO: Occlusion culling - - ///TODO: Light culling } void NzScene::Draw() @@ -77,7 +81,7 @@ void NzScene::Draw() if (m_renderTechniqueRanking > 0) { m_renderTechnique.reset(NzRenderTechniques::GetByRanking(m_renderTechniqueRanking-1, &m_renderTechniqueRanking)); - NazaraError("Render technique \"" + oldName + "\" failed, fallback to \"" + m_renderTechnique->GetName() + '"'); + NazaraError("Render technique \"" + oldName + "\" failed, falling back to \"" + m_renderTechnique->GetName() + '"'); } else { @@ -333,6 +337,25 @@ NzScene::operator const NzSceneNode&() const return m_root; } +bool NzScene::RegisterSceneNode(const NzString& name, NzSceneNode* node) +{ + if (!name.IsEmpty()) + { + if (m_nodeMap.find(name) != m_nodeMap.end()) + { + NazaraError("Node " + name + " is already registred"); + return false; + } + + m_nodeMap[name] = node; + } + + node->SetParent(m_root, true); + + m_nodes.emplace_back(node); + return true; +} + void NzScene::RecursiveFrustumCull(NzAbstractRenderQueue* renderQueue, const NzFrustumf& frustum, NzNode* node) { for (NzNode* child : node->GetChilds()) From e46cb43ef556d56e4a7bd62616d5eca5ccab08d8 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 24 Jan 2015 12:03:24 +0100 Subject: [PATCH 223/233] Removed useless code Former-commit-id: 8e65848eed8c3ceb829a7c556f4686676ea946f4 --- include/Nazara/Graphics/Scene.hpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/include/Nazara/Graphics/Scene.hpp b/include/Nazara/Graphics/Scene.hpp index 03b37bfc4..e07e3086b 100644 --- a/include/Nazara/Graphics/Scene.hpp +++ b/include/Nazara/Graphics/Scene.hpp @@ -22,17 +22,11 @@ class NzAbstractRenderQueue; class NzAbstractViewer; -class NzCamera; -class NzLight; -class NzModel; class NzNode; -class NzRenderQueue; class NzSceneNode; class NAZARA_API NzScene { - friend NzCamera; - public: NzScene(); ~NzScene() = default; From 090263d847b9fa1ad5af8f91535a576b3dbdd033 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 24 Jan 2015 14:13:11 +0100 Subject: [PATCH 224/233] Moved name attribute from Node to SceneNode Former-commit-id: 6f920af67cd6c339d132a67b364742fdf172d5e9 --- include/Nazara/Graphics/SceneNode.hpp | 7 ++++++- include/Nazara/Utility/Node.hpp | 3 --- src/Nazara/Graphics/SceneNode.cpp | 10 ++++++++++ src/Nazara/Utility/Node.cpp | 11 ----------- 4 files changed, 16 insertions(+), 15 deletions(-) diff --git a/include/Nazara/Graphics/SceneNode.hpp b/include/Nazara/Graphics/SceneNode.hpp index 0a771a00e..8c99787ad 100644 --- a/include/Nazara/Graphics/SceneNode.hpp +++ b/include/Nazara/Graphics/SceneNode.hpp @@ -18,7 +18,7 @@ class NzScene; class NAZARA_API NzSceneNode : public NzNode { - friend class NzScene; + friend NzScene; public: NzSceneNode(); @@ -39,6 +39,7 @@ class NAZARA_API NzSceneNode : public NzNode NzVector3f GetDown() const; NzVector3f GetForward() const; NzVector3f GetLeft() const; + const NzString& GetName() const; nzNodeType GetNodeType() const final; NzVector3f GetRight() const; NzScene* GetScene() const; @@ -51,6 +52,8 @@ class NAZARA_API NzSceneNode : public NzNode bool IsDrawingEnabled() const; bool IsVisible() const; + void SetName(const NzString& name); + NzSceneNode& operator=(const NzSceneNode& sceneNode); NzSceneNode& operator=(NzSceneNode&& sceneNode) = delete; @@ -75,6 +78,8 @@ class NAZARA_API NzSceneNode : public NzNode private: void UpdateVisibility(const NzFrustumf& frustum); + + NzString m_name; }; #endif // NAZARA_SCENENODE_HPP diff --git a/include/Nazara/Utility/Node.hpp b/include/Nazara/Utility/Node.hpp index 11f9d1f15..44ec8dd84 100644 --- a/include/Nazara/Utility/Node.hpp +++ b/include/Nazara/Utility/Node.hpp @@ -35,7 +35,6 @@ class NAZARA_API NzNode NzQuaternionf GetInitialRotation() const; NzVector3f GetInitialScale() const; virtual NzVector3f GetLeft() const; - const NzString& GetName() const; virtual nzNodeType GetNodeType() const; const NzNode* GetParent() const; NzVector3f GetPosition(nzCoordSys coordSys = nzCoordSys_Global) const; @@ -67,7 +66,6 @@ class NAZARA_API NzNode void SetInitialScale(float scaleX, float scaleY, float scaleZ = 1.f); void SetInitialPosition(const NzVector3f& translation); void SetInitialPosition(float translationX, float translationXY, float translationZ = 0.f); - void SetName(const NzString& name); void SetParent(const NzNode* node = nullptr, bool keepDerived = false); void SetParent(const NzNode& node, bool keepDerived = false); void SetPosition(const NzVector3f& translation, nzCoordSys coordSys = nzCoordSys_Local); @@ -103,7 +101,6 @@ class NAZARA_API NzNode mutable NzQuaternionf m_derivedRotation; NzQuaternionf m_initialRotation; NzQuaternionf m_rotation; - NzString m_name; mutable NzVector3f m_derivedPosition; mutable NzVector3f m_derivedScale; NzVector3f m_initialPosition; diff --git a/src/Nazara/Graphics/SceneNode.cpp b/src/Nazara/Graphics/SceneNode.cpp index 29a343531..0c795d956 100644 --- a/src/Nazara/Graphics/SceneNode.cpp +++ b/src/Nazara/Graphics/SceneNode.cpp @@ -93,6 +93,11 @@ NzVector3f NzSceneNode::GetLeft() const return NzNode::GetLeft(); } +const NzString& NzSceneNode::GetName() const +{ + return m_name; +} + nzNodeType NzSceneNode::GetNodeType() const { return nzNodeType_Scene; @@ -139,6 +144,11 @@ bool NzSceneNode::IsVisible() const return m_visible; } +void NzSceneNode::SetName(const NzString& name) +{ + m_name = name; +} + NzSceneNode& NzSceneNode::operator=(const NzSceneNode& sceneNode) { NzNode::operator=(sceneNode); diff --git a/src/Nazara/Utility/Node.cpp b/src/Nazara/Utility/Node.cpp index b9105aece..85a2ca168 100644 --- a/src/Nazara/Utility/Node.cpp +++ b/src/Nazara/Utility/Node.cpp @@ -125,11 +125,6 @@ NzVector3f NzNode::GetLeft() const return m_derivedRotation * NzVector3f::Left(); } -const NzString& NzNode::GetName() const -{ - return m_name; -} - nzNodeType NzNode::GetNodeType() const { return nzNodeType_Default; @@ -413,11 +408,6 @@ void NzNode::SetInitialScale(float scaleX, float scaleY, float scaleZ) InvalidateNode(); } -void NzNode::SetName(const NzString& name) -{ - m_name = name; -} - void NzNode::SetParent(const NzNode* node, bool keepDerived) { #if NAZARA_UTILITY_SAFE @@ -621,7 +611,6 @@ NzNode& NzNode::operator=(const NzNode& node) m_initialPosition = node.m_initialPosition; m_initialRotation = node.m_initialRotation; m_initialScale = node.m_initialScale; - m_name = node.m_name; m_position = node.m_position; m_rotation = node.m_rotation; m_scale = node.m_scale; From 0e48f052e5841ef9b832de7a8f0204ceee1eb93b Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 24 Jan 2015 14:34:36 +0100 Subject: [PATCH 225/233] Fixed GetNearestPowerOfTwo function Returning the next POT even if the number was a POT itself Former-commit-id: 812f35d13a99985ca5c12517cd84de22292e52c7 --- include/Nazara/Math/Algorithm.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Math/Algorithm.inl b/include/Nazara/Math/Algorithm.inl index 8a1a0b91e..dc95dbba8 100644 --- a/include/Nazara/Math/Algorithm.inl +++ b/include/Nazara/Math/Algorithm.inl @@ -61,7 +61,7 @@ inline unsigned int NzGetNearestPowerOfTwo(unsigned int number) ///TODO: Marquer comme constexpr en C++14 unsigned int x = 1; // Tant que x est plus petit que n, on décale ses bits vers la gauche, ce qui revient à multiplier par deux - while (x <= number) + while (x < number) x <<= 1; return x; From cdff68940397e32c39a2b95c84ddb28c6b76ef38 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 24 Jan 2015 16:18:06 +0100 Subject: [PATCH 226/233] (Ray) Fixed Intersect(Plane, T) method Former-commit-id: 5acfae80d778087a2e2b423d34da8a218a802cd4 --- include/Nazara/Math/Ray.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Math/Ray.inl b/include/Nazara/Math/Ray.inl index 035a7bc06..6ee22ad4e 100644 --- a/include/Nazara/Math/Ray.inl +++ b/include/Nazara/Math/Ray.inl @@ -225,7 +225,7 @@ bool NzRay::Intersect(const NzPlane& plane, T* hit) const if (NzNumberEquals(divisor, F(0.0))) return false; // perpendicular - T lambda = -(plane.normal.DotProduct(origin) - plane.distance) / divisor; // The plane is ax+by+cz=d + T lambda = -(plane.normal.DotProduct(origin) + plane.distance) / divisor; // The plane is ax+by+cz=d if (lambda < F(0.0)) return false; // Le plan est derrière le rayon From d0bd62705bd6b799c94aae66314562b7a7fe7b01 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 24 Jan 2015 16:20:11 +0100 Subject: [PATCH 227/233] Fixed FaceFilling bug introduced with 38a3c1455187e72e8fced0b92debc87288c8c770 [formerly f16751c0d98bcc87ad6f976c7b7052cdb4b16a05] Former-commit-id: 8cb2b02c3f960a74827ec81aa36f76c349cc5dda --- src/Nazara/Renderer/OpenGL.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index 814cb75da..01f60a39f 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -2035,9 +2035,9 @@ static_assert(nzCubemapFace_Max+1 == 6, "Cubemap face array is incomplete"); GLenum NzOpenGL::FaceFilling[] = { - GL_POINT, // nzFaceFilling_Point + GL_FILL, // nzFaceFilling_Fill GL_LINE, // nzFaceFilling_Line - GL_FILL // nzFaceFilling_Fill + GL_POINT // nzFaceFilling_Point }; static_assert(nzFaceFilling_Max+1 == 3, "Face filling array is incomplete"); From 9ebd023848db5f2f311289eb184521e0cc6db46b Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 24 Jan 2015 16:42:49 +0100 Subject: [PATCH 228/233] (SkeletalModel) Added virtual constructor implementation Former-commit-id: 4a7f356e14f629a728a77f94db7e26c6c4af3b72 --- include/Nazara/Graphics/SkeletalModel.hpp | 4 +++- src/Nazara/Graphics/SkeletalModel.cpp | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Graphics/SkeletalModel.hpp b/include/Nazara/Graphics/SkeletalModel.hpp index 84c8e0f88..157b3dd1c 100644 --- a/include/Nazara/Graphics/SkeletalModel.hpp +++ b/include/Nazara/Graphics/SkeletalModel.hpp @@ -31,7 +31,6 @@ using NzSkeletalModelLoader = NzResourceLoader Date: Sat, 24 Jan 2015 17:50:48 +0100 Subject: [PATCH 229/233] Fixed SkeletalModel registering itself for update multiple times Former-commit-id: 9c7ff03a70b65c2ace3b7929b78f486621797dd4 --- src/Nazara/Graphics/SkeletalModel.cpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/Nazara/Graphics/SkeletalModel.cpp b/src/Nazara/Graphics/SkeletalModel.cpp index 958f66ed3..1f9cba729 100644 --- a/src/Nazara/Graphics/SkeletalModel.cpp +++ b/src/Nazara/Graphics/SkeletalModel.cpp @@ -43,7 +43,7 @@ m_nextFrame(model.m_nextFrame) NzSkeletalModel::~NzSkeletalModel() { - Reset(); + m_scene->UnregisterForUpdate(this); } void NzSkeletalModel::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const @@ -168,9 +168,6 @@ void NzSkeletalModel::Reset() NzModel::Reset(); m_skeleton.Destroy(); - - if (m_scene) - m_scene->UnregisterForUpdate(this); } bool NzSkeletalModel::SetAnimation(NzAnimation* animation) @@ -211,12 +208,7 @@ bool NzSkeletalModel::SetAnimation(NzAnimation* animation) m_interpolation = 0.f; SetSequence(0); - - if (m_scene) - m_scene->RegisterForUpdate(this); } - else if (m_scene) - m_scene->UnregisterForUpdate(this); return true; } @@ -327,8 +319,7 @@ NzSkeletalModel& NzSkeletalModel::operator=(NzSkeletalModel&& node) void NzSkeletalModel::Register() { - if (m_animation) - m_scene->RegisterForUpdate(this); + m_scene->RegisterForUpdate(this); } void NzSkeletalModel::Unregister() From 6d8b266b4c3919361a8f84c91e5ffa2bdc2f4018 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 24 Jan 2015 22:00:55 +0100 Subject: [PATCH 230/233] (Scene) Added FindNode(As) and RemoveNode methods Former-commit-id: 35b0d6a61e99383fffa8048b3c0f6a48b8f0f66c --- include/Nazara/Graphics/Scene.hpp | 8 ++++ include/Nazara/Graphics/Scene.inl | 34 ++++++++++++++- src/Nazara/Graphics/Scene.cpp | 72 +++++++++++++++++++++++++------ 3 files changed, 100 insertions(+), 14 deletions(-) diff --git a/include/Nazara/Graphics/Scene.hpp b/include/Nazara/Graphics/Scene.hpp index e07e3086b..60dd21d43 100644 --- a/include/Nazara/Graphics/Scene.hpp +++ b/include/Nazara/Graphics/Scene.hpp @@ -44,6 +44,11 @@ class NAZARA_API NzScene void EnableBackground(bool enable); + NzSceneNode* FindNode(const NzString& name); + const NzSceneNode* FindNode(const NzString& name) const; + template T* FindNodeAs(const NzString& name); + template const T* FindNodeAs(const NzString& name) const; + NzColor GetAmbientColor() const; NzAbstractBackground* GetBackground() const; NzVector3f GetBackward() const; @@ -63,6 +68,9 @@ class NAZARA_API NzScene void RegisterForUpdate(NzUpdatable* object); + void RemoveNode(NzSceneNode* node); + void RemoveNode(const NzString& name); + void RenderFrame(); void SetAmbientColor(const NzColor& color); diff --git a/include/Nazara/Graphics/Scene.inl b/include/Nazara/Graphics/Scene.inl index 3ac7be7af..2231d1364 100644 --- a/include/Nazara/Graphics/Scene.inl +++ b/include/Nazara/Graphics/Scene.inl @@ -91,7 +91,7 @@ T* NzScene::CreateNode(const NzString& name, const NzString& templateNodeName) } NzSceneNode* sceneNode = it->second; - if (NzImplGetType() != sceneNode->GetSceneNodeType()) + if (sceneNode->GetSceneNodeType() != NzImplGetType()) { NazaraError("Scene node type of T (" + NzString::Number(NzImplGetType()) + ") doesn't match template scene node type (" + NzString::Number(sceneNode->GetSceneNodeType()) + ")"); return nullptr; @@ -104,4 +104,36 @@ T* NzScene::CreateNode(const NzString& name, const NzString& templateNodeName) return node.release(); } +template +T* NzScene::FindNodeAs(const NzString& name) +{ + NzSceneNode* sceneNode = FindNode(name); + if (!sceneNode) + return nullptr; + + if (sceneNode->GetSceneNodeType() != NzImplGetType()) + { + NazaraError("Scene node type of T (" + NzString::Number(NzImplGetType()) + ") doesn't match \"" + name + "\" scene node type (" + NzString::Number(sceneNode->GetSceneNodeType()) + ")"); + return nullptr; + } + + return static_cast(sceneNode); +} + +template +const T* NzScene::FindNodeAs(const NzString& name) const +{ + const NzSceneNode* sceneNode = FindNode(name); + if (!sceneNode) + return nullptr; + + if (sceneNode->GetSceneNodeType() != NzImplGetType()) + { + NazaraError("Scene node type of T (" + NzString::Number(NzImplGetType()) + ") doesn't match \"" + name + "\" scene node type (" + NzString::Number(sceneNode->GetSceneNodeType()) + ")"); + return nullptr; + } + + return static_cast(sceneNode); +} + #include diff --git a/src/Nazara/Graphics/Scene.cpp b/src/Nazara/Graphics/Scene.cpp index 4b86cdda5..55c2165fe 100644 --- a/src/Nazara/Graphics/Scene.cpp +++ b/src/Nazara/Graphics/Scene.cpp @@ -98,6 +98,24 @@ void NzScene::EnableBackground(bool enable) m_backgroundEnabled = enable; } +NzSceneNode* NzScene::FindNode(const NzString& name) +{ + auto it = m_nodeMap.find(name); + if (it == m_nodeMap.end()) + return nullptr; + + return it->second; +} + +const NzSceneNode* NzScene::FindNode(const NzString& name) const +{ + auto it = m_nodeMap.find(name); + if (it == m_nodeMap.end()) + return nullptr; + + return it->second; +} + NzColor NzScene::GetAmbientColor() const { return m_ambientColor; @@ -227,6 +245,47 @@ bool NzScene::IsBackgroundEnabled() const return m_backgroundEnabled; } +void NzScene::RegisterForUpdate(NzUpdatable* object) +{ + #if NAZARA_GRAPHICS_SAFE + if (!object) + { + NazaraError("Invalid object"); + return; + } + #endif + + m_updateList.push_back(object); +} + +void NzScene::RemoveNode(NzSceneNode* node) +{ + if (!node) + return; + + // C'est moche mais je n'ai pas d'autre choix que d'utiliser un std::unique_ptr pour utiliser std::find + std::unique_ptr ptr(node); + auto it = std::find(m_nodes.begin(), m_nodes.end(), ptr); + ptr.release(); + + if (it == m_nodes.end()) + { + NazaraError("This scene node doesn't belong to this scene"); + return; + } + + NzString nodeName = node->GetName(); + if (!nodeName.IsEmpty()) + m_nodeMap.erase(nodeName); + + m_nodes.erase(it); +} + +void NzScene::RemoveNode(const NzString& name) +{ + RemoveNode(FindNode(name)); +} + void NzScene::RenderFrame() { try @@ -243,19 +302,6 @@ void NzScene::RenderFrame() } } -void NzScene::RegisterForUpdate(NzUpdatable* object) -{ - #if NAZARA_GRAPHICS_SAFE - if (!object) - { - NazaraError("Invalid object"); - return; - } - #endif - - m_updateList.push_back(object); -} - void NzScene::SetAmbientColor(const NzColor& color) { m_ambientColor = color; From bc6dd440099a04aefac61f84d6797e40bba08d73 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 25 Jan 2015 16:34:19 +0100 Subject: [PATCH 231/233] Made SceneNode name change reflect on the Scene Former-commit-id: b924b0b9d103e4fce6ab2faf952b9153d49cce06 --- include/Nazara/Graphics/Scene.hpp | 3 +++ include/Nazara/Graphics/SceneNode.hpp | 3 ++- src/Nazara/Graphics/Scene.cpp | 33 +++++++++++++++++++++++++++ src/Nazara/Graphics/SceneNode.cpp | 17 ++++++++++++-- 4 files changed, 53 insertions(+), 3 deletions(-) diff --git a/include/Nazara/Graphics/Scene.hpp b/include/Nazara/Graphics/Scene.hpp index 60dd21d43..b0e51575d 100644 --- a/include/Nazara/Graphics/Scene.hpp +++ b/include/Nazara/Graphics/Scene.hpp @@ -27,6 +27,8 @@ class NzSceneNode; class NAZARA_API NzScene { + friend NzSceneNode; + public: NzScene(); ~NzScene() = default; @@ -88,6 +90,7 @@ class NAZARA_API NzScene operator const NzSceneNode&() const; private: + bool ChangeNodeName(NzSceneNode* node, const NzString& newName); bool RegisterSceneNode(const NzString& name, NzSceneNode* node); void RecursiveFrustumCull(NzAbstractRenderQueue* renderQueue, const NzFrustumf& frustum, NzNode* node); diff --git a/include/Nazara/Graphics/SceneNode.hpp b/include/Nazara/Graphics/SceneNode.hpp index 8c99787ad..b695a5d57 100644 --- a/include/Nazara/Graphics/SceneNode.hpp +++ b/include/Nazara/Graphics/SceneNode.hpp @@ -52,7 +52,7 @@ class NAZARA_API NzSceneNode : public NzNode bool IsDrawingEnabled() const; bool IsVisible() const; - void SetName(const NzString& name); + bool SetName(const NzString& name); NzSceneNode& operator=(const NzSceneNode& sceneNode); NzSceneNode& operator=(NzSceneNode&& sceneNode) = delete; @@ -65,6 +65,7 @@ class NAZARA_API NzSceneNode : public NzNode virtual void OnVisibilityChange(bool visibility); void RecursiveSetScene(NzScene* scene, NzNode* node); virtual void Register(); + void SetNameInternal(const NzString& name); void SetScene(NzScene* scene); virtual void Unregister(); virtual void Update(); diff --git a/src/Nazara/Graphics/Scene.cpp b/src/Nazara/Graphics/Scene.cpp index 55c2165fe..d40344810 100644 --- a/src/Nazara/Graphics/Scene.cpp +++ b/src/Nazara/Graphics/Scene.cpp @@ -383,6 +383,38 @@ NzScene::operator const NzSceneNode&() const return m_root; } +bool NzScene::ChangeNodeName(NzSceneNode* node, const NzString& newName) +{ + #ifdef NAZARA_DEBUG + std::unique_ptr ptr(node); + auto it = std::find(m_nodes.begin(), m_nodes.end(), ptr); + ptr.release(); + + if (it == m_nodes.end()) + { + NazaraInternalError("Node isn't part of the scene"); + return false; + } + #endif + + if (!newName.IsEmpty()) + { + auto pair = m_nodeMap.insert(std::make_pair(newName, node)); + if (!pair.second) + { + NazaraError("Name \"" + newName + "\" is already in use"); + return false; + } + } + + NzString oldName = node->GetName(); + if (!oldName.IsEmpty()) + m_nodeMap.erase(oldName); + + node->SetNameInternal(newName); + return true; +} + bool NzScene::RegisterSceneNode(const NzString& name, NzSceneNode* node) { if (!name.IsEmpty()) @@ -396,6 +428,7 @@ bool NzScene::RegisterSceneNode(const NzString& name, NzSceneNode* node) m_nodeMap[name] = node; } + node->SetNameInternal(name); node->SetParent(m_root, true); m_nodes.emplace_back(node); diff --git a/src/Nazara/Graphics/SceneNode.cpp b/src/Nazara/Graphics/SceneNode.cpp index 0c795d956..bace91038 100644 --- a/src/Nazara/Graphics/SceneNode.cpp +++ b/src/Nazara/Graphics/SceneNode.cpp @@ -144,9 +144,17 @@ bool NzSceneNode::IsVisible() const return m_visible; } -void NzSceneNode::SetName(const NzString& name) +bool NzSceneNode::SetName(const NzString& name) { - m_name = name; + if (m_scene) + // On demande à la scène de changer notre nom + return m_scene->ChangeNodeName(this, name); + else + { + // Pas de scène ? Changeons notre nom nous-même + SetNameInternal(name); + return true; + } } NzSceneNode& NzSceneNode::operator=(const NzSceneNode& sceneNode) @@ -211,6 +219,11 @@ void NzSceneNode::Register() { } +void NzSceneNode::SetNameInternal(const NzString& name) +{ + m_name = name; +} + void NzSceneNode::SetScene(NzScene* scene) { if (m_scene != scene) From 4a2f386c8010ebab069d59ba0d50270fef354bfb Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 25 Jan 2015 16:34:34 +0100 Subject: [PATCH 232/233] (Drawable) Made destructor virtual Former-commit-id: ab35592cf015a3056de5d533b29d3c469cb29d29 --- include/Nazara/Graphics/Drawable.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Graphics/Drawable.hpp b/include/Nazara/Graphics/Drawable.hpp index 97841eebb..3c45939df 100644 --- a/include/Nazara/Graphics/Drawable.hpp +++ b/include/Nazara/Graphics/Drawable.hpp @@ -13,7 +13,7 @@ class NAZARA_API NzDrawable { public: NzDrawable() = default; - ~NzDrawable(); + virtual ~NzDrawable(); virtual void Draw() const = 0; }; From 9e96a2061fb00ee228842b86dc591852a23e45be Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 25 Jan 2015 17:19:35 +0100 Subject: [PATCH 233/233] Fixed compile errors introducted in 228ecfe7e5f59d8c4091c3ebfee8190f66cf62ed [formerly 837c414856dbb7b5be20fd745359b3f1e7791c20] Former-commit-id: efe88a0a209916b0aeea2813ec074182ab3a7adf --- src/Nazara/Graphics/DeferredGeometryPass.cpp | 4 ++-- src/Nazara/Graphics/ForwardRenderTechnique.cpp | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Nazara/Graphics/DeferredGeometryPass.cpp b/src/Nazara/Graphics/DeferredGeometryPass.cpp index c38c45cdd..0b2616cc4 100644 --- a/src/Nazara/Graphics/DeferredGeometryPass.cpp +++ b/src/Nazara/Graphics/DeferredGeometryPass.cpp @@ -142,7 +142,7 @@ bool NzDeferredGeometryPass::Process(const NzScene* scene, unsigned int firstWor instanceMatrices += renderedInstanceCount; // Et on affiche - InstancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount); + instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount); } } else @@ -153,7 +153,7 @@ bool NzDeferredGeometryPass::Process(const NzScene* scene, unsigned int firstWor for (const NzMatrix4f& matrix : instances) { NzRenderer::SetMatrix(nzMatrixType_World, matrix); - DrawFunc(meshData.primitiveMode, 0, indexCount); + drawFunc(meshData.primitiveMode, 0, indexCount); } } diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 534ecf449..5605812ec 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -544,7 +544,7 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const instanceMatrices += renderedInstanceCount; // Et on affiche - InstancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount); + instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount); } } @@ -598,7 +598,7 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const NzLight::Disable(shader, shaderUniforms->lightUniforms, shaderUniforms->lightOffset*i); // Et on passe à l'affichage - DrawFunc(meshData.primitiveMode, 0, indexCount); + drawFunc(meshData.primitiveMode, 0, indexCount); } NzRenderer::Enable(nzRendererParameter_Blend, false); @@ -613,7 +613,7 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const for (const NzMatrix4f& matrix : instances) { NzRenderer::SetMatrix(nzMatrixType_World, matrix); - DrawFunc(meshData.primitiveMode, 0, indexCount); + drawFunc(meshData.primitiveMode, 0, indexCount); } } } @@ -706,7 +706,7 @@ void NzForwardRenderTechnique::DrawTransparentModels(const NzScene* scene) const NzLight::Disable(shader, shaderUniforms->lightUniforms, shaderUniforms->lightOffset*i); NzRenderer::SetMatrix(nzMatrixType_World, matrix); - DrawFunc(meshData.primitiveMode, 0, indexCount); + drawFunc(meshData.primitiveMode, 0, indexCount); } }