particle system - spawn shape - closes #634
This commit is contained in:
parent
f3e9da4f0b
commit
ebff4da0c8
5 changed files with 141 additions and 3 deletions
|
@ -40,7 +40,8 @@ static ParticleEmitter::ModuleBase* createModule(uint32 type, ParticleEmitter& e
|
|||
{ ParticleEmitter::AlphaModule::s_type, create<ParticleEmitter::AlphaModule> },
|
||||
{ ParticleEmitter::RandomRotationModule::s_type, create<ParticleEmitter::RandomRotationModule> },
|
||||
{ ParticleEmitter::SizeModule::s_type, create<ParticleEmitter::SizeModule> },
|
||||
{ ParticleEmitter::AttractorModule::s_type, create<ParticleEmitter::AttractorModule> }
|
||||
{ ParticleEmitter::AttractorModule::s_type, create<ParticleEmitter::AttractorModule> },
|
||||
{ ParticleEmitter::SpawnShapeModule::s_type, create<ParticleEmitter::SpawnShapeModule> }
|
||||
};
|
||||
|
||||
for(auto& i : creators)
|
||||
|
@ -257,6 +258,54 @@ void ParticleEmitter::PlaneModule::deserialize(InputBlob& blob)
|
|||
const uint32 ParticleEmitter::PlaneModule::s_type = Lumix::crc32("plane");
|
||||
|
||||
|
||||
ParticleEmitter::SpawnShapeModule::SpawnShapeModule(ParticleEmitter& emitter)
|
||||
: ModuleBase(emitter)
|
||||
, m_radius(1.0f)
|
||||
, m_shape(SPHERE)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ParticleEmitter::SpawnShapeModule::spawnParticle(int index)
|
||||
{
|
||||
static const float INV = 1.0f / RAND_MAX;
|
||||
// ugly and ~0.1% from uniform distribution, but still faster than the correct solution
|
||||
float r2 = m_radius * m_radius;
|
||||
for (int i = 0; i < 10; ++i)
|
||||
{
|
||||
Vec3 v
|
||||
(
|
||||
m_radius * (2 * rand() * INV - 1.0f),
|
||||
m_radius * (2 * rand() * INV - 1.0f),
|
||||
m_radius * (2 * rand() * INV - 1.0f)
|
||||
);
|
||||
|
||||
if (v.squaredLength() < r2)
|
||||
{
|
||||
m_emitter.m_position[index] += v;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ParticleEmitter::SpawnShapeModule::serialize(OutputBlob& blob)
|
||||
{
|
||||
blob.write(m_shape);
|
||||
blob.write(m_radius);
|
||||
}
|
||||
|
||||
|
||||
void ParticleEmitter::SpawnShapeModule::deserialize(InputBlob& blob)
|
||||
{
|
||||
blob.read(m_shape);
|
||||
blob.read(m_radius);
|
||||
}
|
||||
|
||||
|
||||
const uint32 ParticleEmitter::SpawnShapeModule::s_type = Lumix::crc32("spawn_shape");
|
||||
|
||||
|
||||
ParticleEmitter::LinearMovementModule::LinearMovementModule(ParticleEmitter& emitter)
|
||||
: ModuleBase(emitter)
|
||||
{
|
||||
|
|
|
@ -75,6 +75,25 @@ public:
|
|||
};
|
||||
|
||||
|
||||
struct LUMIX_RENDERER_API SpawnShapeModule : public ModuleBase
|
||||
{
|
||||
SpawnShapeModule(ParticleEmitter& emitter);
|
||||
void spawnParticle(int index) override;
|
||||
void serialize(OutputBlob& blob) override;
|
||||
void deserialize(InputBlob& blob) override;
|
||||
uint32 getType() const override { return s_type; }
|
||||
|
||||
static const uint32 s_type;
|
||||
enum Shape : uint8
|
||||
{
|
||||
SPHERE
|
||||
};
|
||||
float m_radius;
|
||||
Shape m_shape;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct LUMIX_RENDERER_API LinearMovementModule : public ModuleBase
|
||||
{
|
||||
LinearMovementModule(ParticleEmitter& emitter);
|
||||
|
|
|
@ -48,6 +48,8 @@ static const uint32 PARTICLE_EMITTER_FORCE_HASH = crc32("particle_emitter_force"
|
|||
static const uint32 PARTICLE_EMITTER_ATTRACTOR_HASH = crc32("particle_emitter_attractor");
|
||||
static const uint32 PARTICLE_EMITTER_LINEAR_MOVEMENT_HASH =
|
||||
crc32("particle_emitter_linear_movement");
|
||||
static const uint32 PARTICLE_EMITTER_SPAWN_SHAPE_HASH =
|
||||
crc32("particle_emitter_spawn_shape");
|
||||
static const uint32 PARTICLE_EMITTER_PLANE_HASH =
|
||||
crc32("particle_emitter_plane");
|
||||
static const uint32 PARTICLE_EMITTER_RANDOM_ROTATION_HASH =
|
||||
|
@ -520,12 +522,17 @@ public:
|
|||
m_universe.addComponent(
|
||||
emitter->m_entity, PARTICLE_EMITTER_FADE_HASH, this, i);
|
||||
}
|
||||
else if(module->getType() == ParticleEmitter::ForceModule::s_type)
|
||||
else if (module->getType() == ParticleEmitter::ForceModule::s_type)
|
||||
{
|
||||
m_universe.addComponent(
|
||||
emitter->m_entity, PARTICLE_EMITTER_FORCE_HASH, this, i);
|
||||
}
|
||||
else if(module->getType() == ParticleEmitter::AttractorModule::s_type)
|
||||
else if (module->getType() == ParticleEmitter::SpawnShapeModule::s_type)
|
||||
{
|
||||
m_universe.addComponent(
|
||||
emitter->m_entity, PARTICLE_EMITTER_SPAWN_SHAPE_HASH, this, i);
|
||||
}
|
||||
else if (module->getType() == ParticleEmitter::AttractorModule::s_type)
|
||||
{
|
||||
m_universe.addComponent(
|
||||
emitter->m_entity, PARTICLE_EMITTER_ATTRACTOR_HASH, this, i);
|
||||
|
@ -996,6 +1003,23 @@ public:
|
|||
}
|
||||
|
||||
|
||||
void destroyParticleEmitterSpawnShape(ComponentIndex component)
|
||||
{
|
||||
auto* emitter = m_particle_emitters[component];
|
||||
for (auto* module : emitter->m_modules)
|
||||
{
|
||||
if (module->getType() == ParticleEmitter::SpawnShapeModule::s_type)
|
||||
{
|
||||
LUMIX_DELETE(m_allocator, module);
|
||||
emitter->m_modules.eraseItem(module);
|
||||
m_universe.destroyComponent(
|
||||
emitter->m_entity, PARTICLE_EMITTER_SPAWN_SHAPE_HASH, this, component);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void destroyParticleEmitterRandomRotation(ComponentIndex component)
|
||||
{
|
||||
auto* emitter = m_particle_emitters[component];
|
||||
|
@ -1275,6 +1299,23 @@ public:
|
|||
}
|
||||
|
||||
|
||||
ComponentIndex createParticleEmitterSpawnShape(Entity entity)
|
||||
{
|
||||
for (int i = 0; i < m_particle_emitters.size(); ++i)
|
||||
{
|
||||
auto* emitter = m_particle_emitters[i];
|
||||
if (emitter->m_entity == entity)
|
||||
{
|
||||
auto module = LUMIX_NEW(m_allocator, ParticleEmitter::SpawnShapeModule)(*emitter);
|
||||
emitter->addModule(module);
|
||||
m_universe.addComponent(entity, PARTICLE_EMITTER_SPAWN_SHAPE_HASH, this, i);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return INVALID_COMPONENT;
|
||||
}
|
||||
|
||||
|
||||
ComponentIndex createParticleEmitterFade(Entity entity)
|
||||
{
|
||||
for (int i = 0; i < m_particle_emitters.size(); ++i)
|
||||
|
@ -2911,6 +2952,20 @@ public:
|
|||
}
|
||||
|
||||
|
||||
float getParticleEmitterShapeRadius(ComponentIndex cmp) override
|
||||
{
|
||||
auto* module = getEmitterModule<ParticleEmitter::SpawnShapeModule>(cmp);
|
||||
return module ? module->m_radius : 0.0f;
|
||||
}
|
||||
|
||||
|
||||
void setParticleEmitterShapeRadius(ComponentIndex cmp, float value) override
|
||||
{
|
||||
auto* module = getEmitterModule<ParticleEmitter::SpawnShapeModule>(cmp);
|
||||
if (module) module->m_radius = value;
|
||||
}
|
||||
|
||||
|
||||
int getParticleEmitterPlaneCount(ComponentIndex cmp) override
|
||||
{
|
||||
auto* module = getEmitterModule<ParticleEmitter::PlaneModule>(cmp);
|
||||
|
@ -3151,6 +3206,9 @@ static struct
|
|||
{PARTICLE_EMITTER_LINEAR_MOVEMENT_HASH,
|
||||
&RenderSceneImpl::createParticleEmitterLinearMovement,
|
||||
&RenderSceneImpl::destroyParticleEmitterLinearMovement},
|
||||
{PARTICLE_EMITTER_SPAWN_SHAPE_HASH,
|
||||
&RenderSceneImpl::createParticleEmitterSpawnShape,
|
||||
&RenderSceneImpl::destroyParticleEmitterSpawnShape },
|
||||
{PARTICLE_EMITTER_RANDOM_ROTATION_HASH,
|
||||
&RenderSceneImpl::createParticleEmitterRandomRotation,
|
||||
&RenderSceneImpl::destroyParticleEmitterRandomRotation},
|
||||
|
|
|
@ -218,6 +218,8 @@ public:
|
|||
virtual void setParticleEmitterPlaneEntity(ComponentIndex cmp, int index, Entity entity) = 0;
|
||||
virtual float getParticleEmitterPlaneBounce(ComponentIndex cmp) = 0;
|
||||
virtual void setParticleEmitterPlaneBounce(ComponentIndex cmp, float value) = 0;
|
||||
virtual float getParticleEmitterShapeRadius(ComponentIndex cmp) = 0;
|
||||
virtual void setParticleEmitterShapeRadius(ComponentIndex cmp, float value) = 0;
|
||||
|
||||
virtual int getParticleEmitterAttractorCount(ComponentIndex cmp) = 0;
|
||||
virtual void addParticleEmitterAttractor(ComponentIndex cmp, int index) = 0;
|
||||
|
|
|
@ -245,6 +245,7 @@ void registerRendererProperties(Lumix::WorldEditor& editor)
|
|||
PropertyRegister::registerComponentType("global_light", "Global light");
|
||||
PropertyRegister::registerComponentType("renderable", "Mesh");
|
||||
PropertyRegister::registerComponentType("particle_emitter", "Particle emitter");
|
||||
PropertyRegister::registerComponentType("particle_emitter_spawn_shape", "Particle emitter - spawn shape");
|
||||
PropertyRegister::registerComponentType("particle_emitter_fade", "Particle emitter - fade");
|
||||
PropertyRegister::registerComponentType("particle_emitter_plane", "Particle emitter - plane");
|
||||
PropertyRegister::registerComponentType("particle_emitter_force", "Particle emitter - force");
|
||||
|
@ -264,6 +265,15 @@ void registerRendererProperties(Lumix::WorldEditor& editor)
|
|||
PropertyRegister::registerComponentDependency(
|
||||
"particle_emitter_random_rotation", "particle_emitter");
|
||||
|
||||
PropertyRegister::add("particle_emitter_spawn_shape",
|
||||
LUMIX_NEW(allocator, DecimalPropertyDescriptor<RenderScene>)("Radius",
|
||||
&RenderScene::getParticleEmitterShapeRadius,
|
||||
&RenderScene::setParticleEmitterShapeRadius,
|
||||
0.0f,
|
||||
FLT_MAX,
|
||||
0.01f,
|
||||
allocator));
|
||||
|
||||
PropertyRegister::add("particle_emitter_plane",
|
||||
LUMIX_NEW(allocator, DecimalPropertyDescriptor<RenderScene>)("Bounce",
|
||||
&RenderScene::getParticleEmitterPlaneBounce,
|
||||
|
|
Loading…
Reference in a new issue