|
3 | 3 | // For conditions of distribution and use, see copyright notice in LICENSE |
4 | 4 |
|
5 | 5 | #include <ClientLib/ClientChunkEntities.hpp> |
| 6 | +#include <ClientLib/ClientConfigs.hpp> |
6 | 7 | #include <ClientLib/RenderConstants.hpp> |
7 | 8 | #include <ClientLib/Components/VisualEntityComponent.hpp> |
8 | 9 | #include <CommonLib/ChunkLock.hpp> |
| 10 | +#include <CommonLib/ConfigFile.hpp> |
9 | 11 | #include <CommonLib/Components/EntityOwnerComponent.hpp> |
10 | 12 | #include <Nazara/Core/ApplicationBase.hpp> |
11 | 13 | #include <Nazara/Core/EnttWorld.hpp> |
12 | 14 | #include <Nazara/Core/FilesystemAppComponent.hpp> |
13 | 15 | #include <Nazara/Core/IndexBuffer.hpp> |
14 | 16 | #include <Nazara/Core/TaskSchedulerAppComponent.hpp> |
15 | 17 | #include <Nazara/Core/VertexBuffer.hpp> |
| 18 | +#include <Nazara/Core/VertexMapper.hpp> |
16 | 19 | #include <Nazara/Core/Components/NodeComponent.hpp> |
17 | 20 | #include <Nazara/Graphics/GraphicalMesh.hpp> |
18 | 21 | #include <Nazara/Graphics/Graphics.hpp> |
|
26 | 29 |
|
27 | 30 | namespace tsom |
28 | 31 | { |
29 | | - ClientChunkEntities::ClientChunkEntities(Nz::ApplicationBase& app, Nz::EnttWorld& world, ChunkContainer& chunkContainer, const ClientBlockLibrary& blockLibrary, std::size_t layerIndex) : |
| 32 | + ClientChunkEntities::ClientChunkEntities(Nz::ApplicationBase& app, ConfigFile& config, Nz::EnttWorld& world, ChunkContainer& chunkContainer, const ClientBlockLibrary& blockLibrary, std::size_t layerIndex) : |
30 | 33 | ChunkEntities(app, world, chunkContainer, blockLibrary, layerIndex, NoInit{}), |
| 34 | + m_configFile(config), |
31 | 35 | m_isCollisionGenerationEnabled(true) |
32 | 36 | { |
33 | 37 | auto& filesystem = app.GetComponent<Nz::FilesystemAppComponent>(); |
@@ -145,6 +149,11 @@ namespace tsom |
145 | 149 | } |
146 | 150 | }); |
147 | 151 |
|
| 152 | + m_onVisualChunkNormalSmoothAngleUpdatedSlot.Connect(m_configFile.GetFloatUpdateSignal(Config::Visual_ChunkNormalSmoothAngle), [this](double /*newValue*/) |
| 153 | + { |
| 154 | + RebuildAllChunks(); |
| 155 | + }); |
| 156 | + |
148 | 157 | FillChunks(); |
149 | 158 | } |
150 | 159 |
|
@@ -177,6 +186,47 @@ namespace tsom |
177 | 186 | std::shared_ptr<Nz::StaticMesh> staticMesh = std::make_shared<Nz::StaticMesh>(std::move(vertexBuffer), std::move(indexBuffer)); |
178 | 187 | staticMesh->GenerateAABB(); |
179 | 188 |
|
| 189 | + Nz::DegreeAnglef smoothLimitAngle = m_configFile.GetFloatValue<float>(Config::Visual_ChunkNormalSmoothAngle); |
| 190 | + if (smoothLimitAngle > 0.0f) |
| 191 | + { |
| 192 | + Nz::VertexMapper mapper(*staticMesh); |
| 193 | + Nz::UInt32 vertexCount = mapper.GetVertexCount(); |
| 194 | + |
| 195 | + Nz::SparsePtr<Nz::Vector3f> normals = mapper.GetComponentPtr<Nz::Vector3f>(Nz::VertexComponent::Normal); |
| 196 | + Nz::SparsePtr<Nz::Vector3f> positions = mapper.GetComponentPtr<Nz::Vector3f>(Nz::VertexComponent::Position); |
| 197 | + |
| 198 | + // TODO: Replace by a vertex finder-like |
| 199 | + std::map<Nz::Vector3i, Nz::HybridVector<Nz::UInt32, 6>> posToVerts; |
| 200 | + for (Nz::UInt32 i = 0; i < vertexCount; ++i) |
| 201 | + { |
| 202 | + Nz::Vector3i p = Nz::Vector3i(Nz::Vector3f::Apply(positions[i] * 100.f, std::roundf)); |
| 203 | + posToVerts[p].push_back(i); |
| 204 | + } |
| 205 | + |
| 206 | + float fLimit = smoothLimitAngle.GetCos(); |
| 207 | + for (Nz::UInt32 i = 0; i < vertexCount; ++i) |
| 208 | + { |
| 209 | + Nz::Vector3i p = Nz::Vector3i(Nz::Vector3f::Apply(positions[i] * 100.f, std::roundf)); |
| 210 | + |
| 211 | + Nz::Vector3f vr = normals[i]; |
| 212 | + |
| 213 | + auto& verticesFound = posToVerts[p]; |
| 214 | + Nz::Vector3f pcNor; |
| 215 | + for (Nz::UInt32 j : verticesFound) |
| 216 | + { |
| 217 | + Nz::Vector3f v = normals[j]; |
| 218 | + |
| 219 | + // Check whether the angle between the two normals is not too large. |
| 220 | + // Skip the angle check on our own normal to avoid false negatives |
| 221 | + // (v*v is not guaranteed to be 1.0 for all unit vectors v) |
| 222 | + if ((j == i || (Nz::Vector3f::DotProduct(v, vr) >= fLimit))) |
| 223 | + pcNor += v; |
| 224 | + } |
| 225 | + |
| 226 | + normals[i] = pcNor.Normalize(); |
| 227 | + } |
| 228 | + } |
| 229 | + |
180 | 230 | std::shared_ptr<Nz::Mesh> chunkMesh = std::make_shared<Nz::Mesh>(); |
181 | 231 | chunkMesh->CreateStatic(); |
182 | 232 | chunkMesh->AddSubMesh(std::move(staticMesh)); |
|
0 commit comments