layers moved to culling

This commit is contained in:
Mikulas Florek 2014-11-24 22:59:50 +01:00
parent fae00d6cc8
commit dd42f036d6
7 changed files with 66 additions and 34 deletions

View file

@ -24,7 +24,7 @@ namespace Lumix
virtual void endArray() = 0;
virtual void serializeArrayItem(uint32_t value) = 0;
virtual void serializeArrayItem(int32_t value) = 0;
virtual void serializeArrayItem(int64_t& value) = 0;
virtual void serializeArrayItem(int64_t value) = 0;
virtual void serializeArrayItem(float value) = 0;
virtual void serializeArrayItem(bool value) = 0;
virtual void serializeArrayItem(const char* value) = 0;

View file

@ -161,7 +161,7 @@ void JsonSerializer::serializeArrayItem(int value)
}
void JsonSerializer::serializeArrayItem(int64_t& value)
void JsonSerializer::serializeArrayItem(int64_t value)
{
writeBlockComma();
char tmp[30];

View file

@ -41,7 +41,7 @@ namespace Lumix
virtual void endArray() override;
virtual void serializeArrayItem(uint32_t value) override;
virtual void serializeArrayItem(int32_t value) override;
virtual void serializeArrayItem(int64_t& value) override;
virtual void serializeArrayItem(int64_t value) override;
virtual void serializeArrayItem(float value) override;
virtual void serializeArrayItem(bool value) override;
virtual void serializeArrayItem(const char* value) override;

View file

@ -13,6 +13,7 @@
namespace Lumix
{
typedef BinaryArray VisibilityFlags;
typedef Array<int64_t> LayerMasks;
static const int MIN_ENTITIES_PER_THREAD = 50;
@ -22,6 +23,8 @@ namespace Lumix
const Sphere* LUMIX_RESTRICT end,
const VisibilityFlags& visiblity_flags,
const Frustum* LUMIX_RESTRICT frustum,
const int64_t* LUMIX_RESTRICT layer_masks,
int64_t layer_mask,
CullingSystem::Subresults& results
)
{
@ -29,7 +32,7 @@ namespace Lumix
ASSERT(results.empty());
for (const Sphere* sphere = start; sphere <= end; sphere++, ++i)
{
if (frustum->isSphereInside(sphere->m_position, sphere->m_radius) && visiblity_flags[i])
if (frustum->isSphereInside(sphere->m_position, sphere->m_radius) && visiblity_flags[i] && ((layer_masks[i] & layer_mask) != 0))
{
results.push(i);
}
@ -39,7 +42,9 @@ namespace Lumix
class CullingJob : public MTJD::Job
{
public:
CullingJob(const CullingSystem::InputSpheres& spheres, const VisibilityFlags& visibility_flags, CullingSystem::Subresults& results, int start, int end, const Frustum& frustum, MTJD::Manager& manager, IAllocator& allocator)
CullingJob(const CullingSystem::InputSpheres& spheres, const VisibilityFlags& visibility_flags, const LayerMasks& layer_masks, int64_t layer_mask,
CullingSystem::Subresults& results, int start, int end, const Frustum& frustum, MTJD::Manager& manager, IAllocator& allocator
)
: Job(true, MTJD::Priority::Default, false, manager, allocator)
, m_spheres(spheres)
, m_results(results)
@ -47,6 +52,8 @@ namespace Lumix
, m_end(end)
, m_frustum(frustum)
, m_visibility_flags(visibility_flags)
, m_layer_masks(layer_masks)
, m_layer_mask(layer_mask)
{
setJobName("CullingJob");
m_results.reserve(end - start);
@ -61,7 +68,7 @@ namespace Lumix
virtual void execute() override
{
ASSERT(m_results.empty() && !m_is_executed);
doCulling(m_start, &m_spheres[m_start], &m_spheres[m_end], m_visibility_flags, &m_frustum, m_results);
doCulling(m_start, &m_spheres[m_start], &m_spheres[m_end], m_visibility_flags, &m_frustum, &m_layer_masks[0], m_layer_mask, m_results);
m_is_executed = true;
}
@ -69,6 +76,8 @@ namespace Lumix
const CullingSystem::InputSpheres& m_spheres;
CullingSystem::Subresults& m_results;
const VisibilityFlags& m_visibility_flags;
const LayerMasks& m_layer_masks;
int64_t m_layer_mask;
int m_start;
int m_end;
const Frustum& m_frustum;
@ -86,6 +95,7 @@ namespace Lumix
, m_spheres(m_allocator)
, m_result(m_allocator)
, m_visibility_flags(m_allocator)
, m_layer_masks(m_allocator)
{
m_result.emplace(m_allocator);
int cpu_count = (int)m_mtjd_manager.getCpuThreadsCount();
@ -106,6 +116,7 @@ namespace Lumix
{
m_spheres.clear();
m_visibility_flags.clear();
m_layer_masks.clear();
}
@ -125,18 +136,18 @@ namespace Lumix
}
virtual void cullToFrustum(const Frustum& frustum) override
virtual void cullToFrustum(const Frustum& frustum, int64_t layer_mask) override
{
for (int i = 0; i < m_result.size(); ++i)
{
m_result[i].clear();
}
doCulling(0, &m_spheres[0], &m_spheres.back(), m_visibility_flags, &frustum, m_result[0]);
doCulling(0, &m_spheres[0], &m_spheres.back(), m_visibility_flags, &frustum, &m_layer_masks[0], layer_mask, m_result[0]);
m_is_async_result = false;
}
virtual void cullToFrustumAsync(const Frustum& frustum) override
virtual void cullToFrustumAsync(const Frustum& frustum, int64_t layer_mask) override
{
int count = m_spheres.size();
@ -145,7 +156,7 @@ namespace Lumix
if (count < m_result.size() * MIN_ENTITIES_PER_THREAD)
{
cullToFrustum(frustum);
cullToFrustum(frustum, layer_mask);
return;
}
m_is_async_result = true;
@ -158,13 +169,17 @@ namespace Lumix
for (; i < cpu_count - 1; i++)
{
m_result[i].clear();
CullingJob* cj = m_allocator.newObject<CullingJob>(m_spheres, m_visibility_flags, m_result[i], i * step, (i + 1) * step - 1, frustum, m_mtjd_manager, m_allocator);
CullingJob* cj = m_allocator.newObject<CullingJob>(m_spheres, m_visibility_flags, m_layer_masks
, layer_mask, m_result[i], i * step, (i + 1) * step - 1, frustum, m_mtjd_manager, m_allocator
);
cj->addDependency(&m_sync_point);
jobs[i] = cj;
}
m_result[i].clear();
CullingJob* cj = m_allocator.newObject<CullingJob>(m_spheres, m_visibility_flags, m_result[i], i * step, count - 1, frustum, m_mtjd_manager, m_allocator);
CullingJob* cj = m_allocator.newObject<CullingJob>(m_spheres, m_visibility_flags, m_layer_masks
, layer_mask, m_result[i], i * step, count - 1, frustum, m_mtjd_manager, m_allocator
);
cj->addDependency(&m_sync_point);
jobs[i] = cj;
@ -175,6 +190,18 @@ namespace Lumix
}
virtual void setLayerMask(int index, int64_t layer) override
{
m_layer_masks[index] = layer;
}
virtual int64_t getLayerMask(int index) override
{
return m_layer_masks[index];
}
virtual void enableStatic(int index) override
{
m_visibility_flags[index] = true;
@ -191,6 +218,7 @@ namespace Lumix
{
m_spheres.push(sphere);
m_visibility_flags.push(true);
m_layer_masks.push(1);
}
@ -200,6 +228,7 @@ namespace Lumix
m_spheres.erase(index);
m_visibility_flags.erase(index);
m_layer_masks.erase(index);
}
@ -221,6 +250,7 @@ namespace Lumix
{
m_spheres.push(spheres[i]);
m_visibility_flags.push(true);
m_layer_masks.push(1);
}
}
@ -236,6 +266,7 @@ namespace Lumix
VisibilityFlags m_visibility_flags;
InputSpheres m_spheres;
Results m_result;
LayerMasks m_layer_masks;
MTJD::Manager& m_mtjd_manager;
MTJD::Group m_sync_point;

View file

@ -27,12 +27,15 @@ namespace Lumix
virtual void clear() = 0;
virtual const Results& getResult() = 0;
virtual void cullToFrustum(const Frustum& frustum) = 0;
virtual void cullToFrustumAsync(const Frustum& frustum) = 0;
virtual void cullToFrustum(const Frustum& frustum, int64_t layer_mask) = 0;
virtual void cullToFrustumAsync(const Frustum& frustum, int64_t layer_mask) = 0;
virtual void addStatic(const Sphere& sphere) = 0;
virtual void removeStatic(int index) = 0;
virtual void setLayerMask(int index, int64_t layer) = 0;
virtual int64_t getLayerMask(int index) = 0;
virtual void enableStatic(int index) = 0;
virtual void disableStatic(int index) = 0;

View file

@ -47,7 +47,6 @@ namespace Lumix
{
Renderable(IAllocator& allocator) : m_pose(allocator), m_meshes(allocator) {}
int64_t m_layer_mask;
Array<RenderableMesh> m_meshes;
int32_t m_component_index;
Pose m_pose;
@ -309,7 +308,7 @@ namespace Lumix
serializer.serializeArrayItem(m_renderables[i]->m_is_always_visible);
serializer.serializeArrayItem(m_renderables[i]->m_component_index);
serializer.serializeArrayItem(m_renderables[i]->m_entity.index);
serializer.serializeArrayItem(m_renderables[i]->m_layer_mask);
serializer.serializeArrayItem(m_culling_system->getLayerMask(i));
if (m_renderables[i]->m_model)
{
serializer.serializeArrayItem(m_renderables[i]->m_model->getPath().c_str());
@ -409,11 +408,13 @@ namespace Lumix
serializer.deserializeArrayItem(m_renderables[i]->m_entity.index, 0);
m_renderables[i]->m_model = NULL;
m_renderables[i]->m_entity.universe = &m_universe;
serializer.deserializeArrayItem(m_renderables[i]->m_layer_mask, 0);
int64_t layer_mask;
serializer.deserializeArrayItem(layer_mask, 1);
char path[LUMIX_MAX_PATH];
serializer.deserializeArrayItem(path, LUMIX_MAX_PATH, "");
serializer.deserializeArrayItem(m_renderables[i]->m_scale, 0);
m_culling_system->addStatic(Sphere(m_renderables[i]->m_entity.getPosition(), 1.0f));
m_culling_system->setLayerMask(i, layer_mask);
setModel(i, static_cast<Model*>(m_engine.getResourceManager().get(ResourceManager::MODEL)->load(path)));
for (int j = 0; j < 16; ++j)
{
@ -583,7 +584,6 @@ namespace Lumix
Renderable& r = *m_allocator.newObject<Renderable>(m_allocator);
m_renderables.push(&r);
r.m_entity = entity;
r.m_layer_mask = 1;
r.m_scale = 1;
r.m_model = NULL;
r.m_component_index = new_index;
@ -793,7 +793,7 @@ namespace Lumix
virtual void setRenderableLayer(Component cmp, const int32_t& layer) override
{
m_renderables[getRenderable(cmp.index)]->m_layer_mask = ((int64_t)1 << (int64_t)layer);
m_culling_system->setLayerMask(getRenderable(cmp.index), (int64_t)1 << (int64_t)layer);
}
virtual void setRenderableScale(Component cmp, float scale) override
@ -956,13 +956,13 @@ namespace Lumix
}
const CullingSystem::Results* cull(const Frustum& frustum)
const CullingSystem::Results* cull(const Frustum& frustum, int64_t layer_mask)
{
PROFILE_FUNCTION();
if (m_renderables.empty())
return NULL;
m_culling_system->cullToFrustumAsync(frustum);
m_culling_system->cullToFrustumAsync(frustum, layer_mask);
return &m_culling_system->getResult();
}
@ -1021,14 +1021,11 @@ namespace Lumix
for (int i = 0, c = subresults.size(); i < c; ++i)
{
const Renderable* LUMIX_RESTRICT renderable = m_renderables[subresults[i]];
if ((renderable->m_layer_mask & layer_mask) != 0)
for (int j = 0, c = renderable->m_meshes.size(); j < c; ++j)
{
for (int j = 0, c = renderable->m_meshes.size(); j < c; ++j)
{
RenderableInfo& info = subinfos.pushEmpty();
info.m_mesh = &renderable->m_meshes[j];
info.m_key = (int64_t)renderable->m_meshes[j].m_mesh;
}
RenderableInfo& info = subinfos.pushEmpty();
info.m_mesh = &renderable->m_meshes[j];
info.m_key = (int64_t)renderable->m_meshes[j].m_mesh;
}
}
});
@ -1043,7 +1040,7 @@ namespace Lumix
{
PROFILE_FUNCTION();
const CullingSystem::Results* results = cull(frustum);
const CullingSystem::Results* results = cull(frustum, layer_mask);
if (!results)
{
return;
@ -1054,8 +1051,9 @@ namespace Lumix
for (int i = 0, c = m_always_visible.size(); i < c; ++i)
{
const Renderable* LUMIX_RESTRICT renderable = m_renderables[getRenderable(m_always_visible[i])];
if ((renderable->m_layer_mask & layer_mask) != 0)
int renderable_index = getRenderable(m_always_visible[i]);
const Renderable* LUMIX_RESTRICT renderable = m_renderables[renderable_index];
if ((m_culling_system->getLayerMask(renderable_index) & layer_mask) != 0)
{
for (int j = 0, c = renderable->m_meshes.size(); j < c; ++j)
{
@ -1079,7 +1077,7 @@ namespace Lumix
for (int i = 0, c = m_renderables.size(); i < c; ++i)
{
const Renderable* LUMIX_RESTRICT renderable = m_renderables[i];
if ((renderable->m_layer_mask & layer_mask) != 0)
if ((m_culling_system->getLayerMask(i) & layer_mask) != 0)
{
for (int j = 0, c = renderable->m_meshes.size(); j < c; ++j)
{

View file

@ -63,7 +63,7 @@ namespace
Lumix::ScopedTimer timer("Culling System", allocator);
culling_system->cullToFrustum(clipping_frustum);
culling_system->cullToFrustum(clipping_frustum, 1);
const Lumix::CullingSystem::Results& result = culling_system->getResult();
//Lumix::g_log_info.log("unit") << "Culling system test took: " << timer.getTimeSinceStart();
@ -110,7 +110,7 @@ namespace
Lumix::ScopedTimer timer("Culling System Async", allocator);
culling_system->cullToFrustumAsync(clipping_frustum);
culling_system->cullToFrustumAsync(clipping_frustum, 1);
const Lumix::CullingSystem::Results& result = culling_system->getResult();