Save one array traversal

This commit is contained in:
Atlante45 2015-11-18 16:07:01 -08:00
parent cb14fbf4a1
commit ca17c75631
3 changed files with 10 additions and 32 deletions

View file

@ -171,27 +171,18 @@ uint32_t toRGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
return ((uint32_t)r | (uint32_t)g << 8 | (uint32_t)b << 16 | (uint32_t)a << 24); return ((uint32_t)r | (uint32_t)g << 8 | (uint32_t)b << 16 | (uint32_t)a << 24);
} }
struct ParticleDetails {
ParticleDetails(glm::vec3 position, float radius, uint32_t rgba) : position(position), radius(radius), rgba(rgba) { }
glm::vec3 position;
float radius;
uint32_t rgba;
};
void RenderableParticleEffectEntityItem::updateRenderItem() { void RenderableParticleEffectEntityItem::updateRenderItem() {
if (!_scene) { if (!_scene) {
return; return;
} }
// make a copy of each particle's details // build primitives from particle positions and radiuses
std::vector<ParticleDetails> particleDetails; _particlePrimitives.clear(); // clear primitives
particleDetails.reserve(getLivingParticleCount()); _particlePrimitives.reserve(_particles.size()); // Reserve space
for (auto& particle : _particles) { for (auto& particle : _particles) {
auto xcolor = particle.color; auto alpha = glm::clamp(particle.alpha * getLocalRenderAlpha(), 0.0f, 1.0f) * 255;
auto alpha = (uint8_t)(glm::clamp(particle.alpha * getLocalRenderAlpha(), 0.0f, 1.0f) * 255.0f); auto rgba = toRGBA(particle.color.red, particle.color.green, particle.color.blue, alpha);
auto rgba = toRGBA(xcolor.red, xcolor.green, xcolor.blue, alpha); _particlePrimitives.emplace_back(glm::vec4(particle.position, particle.radius), rgba);
particleDetails.emplace_back(particle.position, particle.radius, rgba);
} }
// No need to sort if we're doing additive blending // No need to sort if we're doing additive blending
@ -202,19 +193,12 @@ void RenderableParticleEffectEntityItem::updateRenderItem() {
// Get direction in the entity space // Get direction in the entity space
direction = glm::inverse(getRotation()) * direction; direction = glm::inverse(getRotation()) * direction;
std::sort(particleDetails.begin(), particleDetails.end(), std::sort(_particlePrimitives.begin(), _particlePrimitives.end(),
[&](const ParticleDetails& lhs, const ParticleDetails& rhs) { [&](const ParticlePrimitive& lhs, const ParticlePrimitive& rhs) {
return glm::dot(lhs.position, direction) > glm::dot(rhs.position, direction); return glm::dot(glm::vec3(lhs.xyzw), direction) > glm::dot(glm::vec3(rhs.xyzw), direction);
}); });
} }
// build primitives from particle positions and radiuses
_particlePrimitives.clear(); // clear primitives
_particlePrimitives.reserve(particleDetails.size()); // Reserve space
for (const auto& particle : particleDetails) {
_particlePrimitives.emplace_back(glm::vec4(particle.position, particle.radius), particle.rgba);
}
render::PendingChanges pendingChanges; render::PendingChanges pendingChanges;
pendingChanges.updateItem<ParticlePayload>(_renderItemId, [this](ParticlePayload& payload) { pendingChanges.updateItem<ParticlePayload>(_renderItemId, [this](ParticlePayload& payload) {
// update particle buffer // update particle buffer

View file

@ -549,7 +549,7 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData,
bool ParticleEffectEntityItem::isEmittingParticles() const { bool ParticleEffectEntityItem::isEmittingParticles() const {
// keep emitting if there are particles still alive. // keep emitting if there are particles still alive.
return (getIsEmitting() || getLivingParticleCount() > 0); return (getIsEmitting() || !_particles.empty());
} }
bool ParticleEffectEntityItem::needsToCallUpdate() const { bool ParticleEffectEntityItem::needsToCallUpdate() const {
@ -804,8 +804,3 @@ void ParticleEffectEntityItem::setMaxParticles(quint32 maxParticles) {
_timeUntilNextEmit = 0.0f; _timeUntilNextEmit = 0.0f;
} }
} }
// because particles are in a ring buffer, this isn't trivial
quint32 ParticleEffectEntityItem::getLivingParticleCount() const {
return _particles.size();
}

View file

@ -221,7 +221,6 @@ protected:
using Particles = std::deque<Particle>; using Particles = std::deque<Particle>;
bool isAnimatingSomething() const; bool isAnimatingSomething() const;
quint32 getLivingParticleCount() const;
Particle createParticle(); Particle createParticle();
void stepSimulation(float deltaTime); void stepSimulation(float deltaTime);