fixed world space particles rubber banding

This commit is contained in:
Mikulas Florek 2023-10-14 16:38:32 +02:00
parent a2567f98db
commit 698799fb40
3 changed files with 35 additions and 24 deletions

View file

@ -1060,7 +1060,35 @@ void ParticleSystem::processChunk(ChunkProcessorContext& ctx) {
}
}
void ParticleSystem::update(float dt, u32 emitter_idx, const Transform& delta_tr, PageAllocator& page_allocator) {
void ParticleSystem::applyTransform(const Transform& new_tr) {
PROFILE_FUNCTION();
if (m_total_time == 0) {
m_prev_frame_transform = new_tr;
}
const Transform delta_tr = new_tr.inverted() * m_prev_frame_transform;
for (i32 emitter_idx = 0; emitter_idx < m_emitters.size(); ++emitter_idx) {
Emitter& emitter = m_emitters[emitter_idx];
if ((u32)m_resource->getFlags() & (u32)ParticleSystemResource::Flags::WORLD_SPACE) {
jobs::forEach(emitter.particles_count, 4096, [&](u32 from, u32 to){
PROFILE_BLOCK("to world space");
// TODO make sure first 3 channels are position
float* LUMIX_RESTRICT x = emitter.channels[0].data;
float* LUMIX_RESTRICT y = emitter.channels[1].data;
float* LUMIX_RESTRICT z = emitter.channels[2].data;
for (u32 i = from; i < to; ++i) {
Vec3 p{x[i], y[i], z[i]};
p = Vec3(delta_tr.transform(p));
x[i] = p.x;
y[i] = p.y;
z[i] = p.z;
}
});
}
}
m_prev_frame_transform = new_tr;
}
void ParticleSystem::update(float dt, u32 emitter_idx, PageAllocator& page_allocator) {
PROFILE_FUNCTION();
Emitter& emitter = m_emitters[emitter_idx];
@ -1168,23 +1196,6 @@ void ParticleSystem::update(float dt, u32 emitter_idx, const Transform& delta_tr
profiler::pushInt("count", dst_emitter.resource_emitter.init_emit_count);
emit(emitter_idx, Span(outputs, outputs_count), dst_emitter.resource_emitter.init_emit_count, 0);
}
if ((u32)m_resource->getFlags() & (u32)ParticleSystemResource::Flags::WORLD_SPACE) {
jobs::forEach(emitter.particles_count, 4096, [&](u32 from, u32 to){
PROFILE_BLOCK("to world space");
// TODO make sure first 3 channels are position
float* LUMIX_RESTRICT x = emitter.channels[0].data;
float* LUMIX_RESTRICT y = emitter.channels[1].data;
float* LUMIX_RESTRICT z = emitter.channels[2].data;
for (u32 i = from; i < to; ++i) {
Vec3 p{x[i], y[i], z[i]};
p = Vec3(delta_tr.transform(p));
x[i] = p.x;
y[i] = p.y;
z[i] = p.z;
}
});
}
}
bool ParticleSystem::update(float dt, PageAllocator& page_allocator)
@ -1197,7 +1208,6 @@ bool ParticleSystem::update(float dt, PageAllocator& page_allocator)
m_constants[1] = m_total_time;
if (m_total_time == 0) {
m_prev_frame_transform = m_world.getTransform(*m_entity);
for (i32 emitter_idx = 0; emitter_idx < m_emitters.size(); ++emitter_idx) {
const ParticleSystemResource::Emitter& emitter = m_resource->getEmitters()[emitter_idx];
if (emitter.emit_inputs_count == 0) {
@ -1208,17 +1218,14 @@ bool ParticleSystem::update(float dt, PageAllocator& page_allocator)
m_total_time += dt;
const Transform world_tr = m_world.getTransform(*m_entity);
const Transform delta_tr = world_tr.inverted() * m_prev_frame_transform;
for (i32 emitter_idx = 0; emitter_idx < m_emitters.size(); ++emitter_idx) {
update(dt, emitter_idx, delta_tr, page_allocator);
update(dt, emitter_idx, page_allocator);
}
u32 c = 0;
for (const Emitter& emitter : m_emitters) {
c += emitter.particles_count;
}
m_prev_frame_transform = world_tr;
return c == 0 && m_autodestroy;
}

View file

@ -178,6 +178,7 @@ struct LUMIX_RENDERER_API ParticleSystem {
void serialize(OutputMemoryStream& blob) const;
void deserialize(InputMemoryStream& blob, bool has_autodestroy, bool emit_rate_removed, ResourceManagerHub& manager);
void applyTransform(const Transform& new_tr);
bool update(float dt, PageAllocator& page_allocator);
ParticleSystemResource* getResource() const { return m_resource; }
void setResource(ParticleSystemResource* res);
@ -198,7 +199,7 @@ private:
void operator =(ParticleSystem&& rhs) = delete;
void onResourceChanged(Resource::State old_state, Resource::State new_state, Resource&);
void update(float dt, u32 emitter_idx, const Transform& delta_transform, PageAllocator& page_allocator);
void update(float dt, u32 emitter_idx, PageAllocator& page_allocator);
void emit(u32 emitter_idx, Span<const float> emit_data, u32 count, float time_step);
void ensureCapacity(Emitter& emitter, u32 num_new_particles);
void run(RunningContext& ctx);

View file

@ -1493,6 +1493,9 @@ struct RenderModuleImpl final : RenderModule {
m_culling_system->setPosition(entity, pos);
}
}
else if (m_world.hasComponent(entity, PARTICLE_EMITTER_TYPE)) {
m_particle_emitters[entity].applyTransform(m_world.getTransform(entity));
}
bool was_updating = m_is_updating_attachments;
m_is_updating_attachments = true;