Загрузчик двоичных ресурсов на сервере (Alpha)
This commit is contained in:
119
Src/Client/FrustumCull.h
Normal file
119
Src/Client/FrustumCull.h
Normal file
@@ -0,0 +1,119 @@
|
||||
// https://gist.github.com/podgorskiy/e698d18879588ada9014768e3e82a644
|
||||
|
||||
#include <glm/matrix.hpp>
|
||||
|
||||
class Frustum
|
||||
{
|
||||
public:
|
||||
Frustum() {}
|
||||
|
||||
// m = ProjectionMatrix * ViewMatrix
|
||||
Frustum(glm::mat4 m);
|
||||
|
||||
// http://iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm
|
||||
bool IsBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const;
|
||||
|
||||
private:
|
||||
enum Planes
|
||||
{
|
||||
Left = 0,
|
||||
Right,
|
||||
Bottom,
|
||||
Top,
|
||||
Near,
|
||||
Far,
|
||||
Count,
|
||||
Combinations = Count * (Count - 1) / 2
|
||||
};
|
||||
|
||||
template<Planes i, Planes j>
|
||||
struct ij2k
|
||||
{
|
||||
enum { k = i * (9 - i) / 2 + j - 1 };
|
||||
};
|
||||
|
||||
template<Planes a, Planes b, Planes c>
|
||||
glm::vec3 intersection(const glm::vec3* crosses) const;
|
||||
|
||||
glm::vec4 m_planes[Count];
|
||||
glm::vec3 m_points[8];
|
||||
};
|
||||
|
||||
inline Frustum::Frustum(glm::mat4 m)
|
||||
{
|
||||
m = glm::transpose(m);
|
||||
m_planes[Left] = m[3] + m[0];
|
||||
m_planes[Right] = m[3] - m[0];
|
||||
m_planes[Bottom] = m[3] + m[1];
|
||||
m_planes[Top] = m[3] - m[1];
|
||||
m_planes[Near] = m[3] + m[2];
|
||||
m_planes[Far] = m[3] - m[2];
|
||||
|
||||
glm::vec3 crosses[Combinations] = {
|
||||
glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Right])),
|
||||
glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Bottom])),
|
||||
glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Top])),
|
||||
glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Near])),
|
||||
glm::cross(glm::vec3(m_planes[Left]), glm::vec3(m_planes[Far])),
|
||||
glm::cross(glm::vec3(m_planes[Right]), glm::vec3(m_planes[Bottom])),
|
||||
glm::cross(glm::vec3(m_planes[Right]), glm::vec3(m_planes[Top])),
|
||||
glm::cross(glm::vec3(m_planes[Right]), glm::vec3(m_planes[Near])),
|
||||
glm::cross(glm::vec3(m_planes[Right]), glm::vec3(m_planes[Far])),
|
||||
glm::cross(glm::vec3(m_planes[Bottom]), glm::vec3(m_planes[Top])),
|
||||
glm::cross(glm::vec3(m_planes[Bottom]), glm::vec3(m_planes[Near])),
|
||||
glm::cross(glm::vec3(m_planes[Bottom]), glm::vec3(m_planes[Far])),
|
||||
glm::cross(glm::vec3(m_planes[Top]), glm::vec3(m_planes[Near])),
|
||||
glm::cross(glm::vec3(m_planes[Top]), glm::vec3(m_planes[Far])),
|
||||
glm::cross(glm::vec3(m_planes[Near]), glm::vec3(m_planes[Far]))
|
||||
};
|
||||
|
||||
m_points[0] = intersection<Left, Bottom, Near>(crosses);
|
||||
m_points[1] = intersection<Left, Top, Near>(crosses);
|
||||
m_points[2] = intersection<Right, Bottom, Near>(crosses);
|
||||
m_points[3] = intersection<Right, Top, Near>(crosses);
|
||||
m_points[4] = intersection<Left, Bottom, Far>(crosses);
|
||||
m_points[5] = intersection<Left, Top, Far>(crosses);
|
||||
m_points[6] = intersection<Right, Bottom, Far>(crosses);
|
||||
m_points[7] = intersection<Right, Top, Far>(crosses);
|
||||
|
||||
}
|
||||
|
||||
// http://iquilezles.org/www/articles/frustumcorrect/frustumcorrect.htm
|
||||
inline bool Frustum::IsBoxVisible(const glm::vec3& minp, const glm::vec3& maxp) const
|
||||
{
|
||||
// check box outside/inside of frustum
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
if ((glm::dot(m_planes[i], glm::vec4(minp.x, minp.y, minp.z, 1.0f)) < 0.0) &&
|
||||
(glm::dot(m_planes[i], glm::vec4(maxp.x, minp.y, minp.z, 1.0f)) < 0.0) &&
|
||||
(glm::dot(m_planes[i], glm::vec4(minp.x, maxp.y, minp.z, 1.0f)) < 0.0) &&
|
||||
(glm::dot(m_planes[i], glm::vec4(maxp.x, maxp.y, minp.z, 1.0f)) < 0.0) &&
|
||||
(glm::dot(m_planes[i], glm::vec4(minp.x, minp.y, maxp.z, 1.0f)) < 0.0) &&
|
||||
(glm::dot(m_planes[i], glm::vec4(maxp.x, minp.y, maxp.z, 1.0f)) < 0.0) &&
|
||||
(glm::dot(m_planes[i], glm::vec4(minp.x, maxp.y, maxp.z, 1.0f)) < 0.0) &&
|
||||
(glm::dot(m_planes[i], glm::vec4(maxp.x, maxp.y, maxp.z, 1.0f)) < 0.0))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// check frustum outside/inside box
|
||||
int out;
|
||||
out = 0; for (int i = 0; i<8; i++) out += ((m_points[i].x > maxp.x) ? 1 : 0); if (out == 8) return false;
|
||||
out = 0; for (int i = 0; i<8; i++) out += ((m_points[i].x < minp.x) ? 1 : 0); if (out == 8) return false;
|
||||
out = 0; for (int i = 0; i<8; i++) out += ((m_points[i].y > maxp.y) ? 1 : 0); if (out == 8) return false;
|
||||
out = 0; for (int i = 0; i<8; i++) out += ((m_points[i].y < minp.y) ? 1 : 0); if (out == 8) return false;
|
||||
out = 0; for (int i = 0; i<8; i++) out += ((m_points[i].z > maxp.z) ? 1 : 0); if (out == 8) return false;
|
||||
out = 0; for (int i = 0; i<8; i++) out += ((m_points[i].z < minp.z) ? 1 : 0); if (out == 8) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<Frustum::Planes a, Frustum::Planes b, Frustum::Planes c>
|
||||
inline glm::vec3 Frustum::intersection(const glm::vec3* crosses) const
|
||||
{
|
||||
float D = glm::dot(glm::vec3(m_planes[a]), crosses[ij2k<b, c>::k]);
|
||||
glm::vec3 res = glm::mat3(crosses[ij2k<b, c>::k], -crosses[ij2k<a, c>::k], crosses[ij2k<a, b>::k]) *
|
||||
glm::vec3(m_planes[a].w, m_planes[b].w, m_planes[c].w);
|
||||
return res * (-1.0f / D);
|
||||
}
|
||||
@@ -1190,7 +1190,11 @@ void VulkanRenderSession::drawWorld(GlobalTime gTime, float dTime, VkCommandBuff
|
||||
MainAtlas_LightMap_PipelineLayout, 0, 2,
|
||||
(const VkDescriptorSet[]) {MainAtlasDescriptor, VoxelLightMapDescriptor}, 0, nullptr);
|
||||
|
||||
PCO.Model = glm::mat4(1);
|
||||
{
|
||||
// glm::vec4 offset = glm::inverse(Quat)*glm::vec4(0, 0, -64, 1);
|
||||
// PCO.Model = glm::translate(glm::mat4(1), glm::vec3(offset));
|
||||
PCO.Model = glm::mat4(1);
|
||||
}
|
||||
VkBuffer vkBuffer = VKCTX->TestQuad;
|
||||
VkDeviceSize vkOffsets = 0;
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include "Abstract.hpp"
|
||||
#include "TOSLib.hpp"
|
||||
#include "VertexPool.hpp"
|
||||
#include "glm/fwd.hpp"
|
||||
#include "../FrustumCull.h"
|
||||
|
||||
/*
|
||||
У движка есть один текстурный атлас VK_IMAGE_VIEW_TYPE_2D_ARRAY(RGBA_UINT) и к нему Storage с инфой о положении текстур
|
||||
@@ -192,28 +194,16 @@ class VulkanRenderSession : public IRenderSession, public IVulkanDependent {
|
||||
if(iterWorld == ChunkMesh.end())
|
||||
return {};
|
||||
|
||||
Frustum fr(projView);
|
||||
|
||||
for(int z = -distance; z <= distance; z++) {
|
||||
for(int y = -distance; y <= distance; y++) {
|
||||
for(int x = -distance; x <= distance; x++) {
|
||||
Pos::GlobalRegion region = center + Pos::GlobalRegion(x, y, z);
|
||||
glm::vec3 begin = glm::vec3(region - x64offset);
|
||||
glm::vec3 begin = glm::vec3(region - x64offset) * 64.f;
|
||||
glm::vec3 end = begin + glm::vec3(64.f);
|
||||
|
||||
bool isVisible = false;
|
||||
for(int index = 0; index < 8; index++) {
|
||||
glm::vec4 vec((begin+glm::vec3(index&1, (index>>1)&1, (index>>2)&1))*64.f, 1);
|
||||
glm::vec4 temp = projView * vec;
|
||||
temp /= temp.w;
|
||||
|
||||
if(temp.x >= -1 && temp.x <= 1
|
||||
&& temp.y >= -1 && temp.y <= 1
|
||||
&& temp.z >= 0 && temp.z <= 1
|
||||
) {
|
||||
isVisible = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!isVisible)
|
||||
if(!fr.IsBoxVisible(begin, end))
|
||||
continue;
|
||||
|
||||
auto iterRegion = iterWorld->second.find(region);
|
||||
@@ -223,12 +213,19 @@ class VulkanRenderSession : public IRenderSession, public IVulkanDependent {
|
||||
Pos::GlobalChunk local = Pos::GlobalChunk(region) << 2;
|
||||
|
||||
for(size_t index = 0; index < iterRegion->second.size(); index++) {
|
||||
Pos::bvec4u localPos;
|
||||
localPos.unpack(index);
|
||||
|
||||
glm::vec3 chunkPos = begin+glm::vec3(localPos)*16.f;
|
||||
if(!fr.IsBoxVisible(chunkPos, chunkPos+glm::vec3(16)))
|
||||
continue;
|
||||
|
||||
auto &chunk = iterRegion->second[index];
|
||||
|
||||
if(chunk.VoxelPointer)
|
||||
vertexVoxels.emplace_back(local+Pos::GlobalChunk(Pos::bvec4u().unpack(index)), VertexPool_Voxels.map(chunk.VoxelPointer), chunk.VoxelPointer.VertexCount);
|
||||
vertexVoxels.emplace_back(local+Pos::GlobalChunk(localPos), VertexPool_Voxels.map(chunk.VoxelPointer), chunk.VoxelPointer.VertexCount);
|
||||
if(chunk.NodePointer)
|
||||
vertexNodes.emplace_back(local+Pos::GlobalChunk(Pos::bvec4u().unpack(index)), VertexPool_Nodes.map(chunk.NodePointer), chunk.NodePointer.VertexCount);
|
||||
vertexNodes.emplace_back(local+Pos::GlobalChunk(localPos), VertexPool_Nodes.map(chunk.NodePointer), chunk.NodePointer.VertexCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user