Add new radiusSpread entity particle property

This commit is contained in:
David Rowe 2015-09-03 12:43:36 -07:00
parent a701ae0553
commit 45ff118249
8 changed files with 69 additions and 30 deletions

View file

@ -168,52 +168,63 @@ void RenderableParticleEffectEntityItem::update(const quint64& now) {
updateRenderItem(); updateRenderItem();
} }
static glm::vec3 zSortAxis;
static bool zSort(const glm::vec3& rhs, const glm::vec3& lhs) {
return glm::dot(rhs, ::zSortAxis) > glm::dot(lhs, ::zSortAxis);
}
uint32_t toRGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a) { 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);
} }
class PositionAndRadius {
public:
PositionAndRadius(glm::vec3 position, float radius) : position(position), radius(radius) { }
glm::vec3 position;
float radius;
};
static glm::vec3 zSortAxis;
static bool zSort(const PositionAndRadius& rhs, const PositionAndRadius& lhs) {
return glm::dot(rhs.position, ::zSortAxis) > glm::dot(lhs.position, ::zSortAxis);
}
void RenderableParticleEffectEntityItem::updateRenderItem() { void RenderableParticleEffectEntityItem::updateRenderItem() {
if (!_scene) { if (!_scene) {
return; return;
} }
float particleRadius = getParticleRadius(); //float particleRadius = _particleRadiuses[i];
auto xcolor = getXColor(); auto xcolor = getXColor();
auto alpha = (uint8_t)(glm::clamp(getLocalRenderAlpha(), 0.0f, 1.0f) * 255.0f); auto alpha = (uint8_t)(glm::clamp(getLocalRenderAlpha(), 0.0f, 1.0f) * 255.0f);
auto rgba = toRGBA(xcolor.red, xcolor.green, xcolor.blue, alpha); auto rgba = toRGBA(xcolor.red, xcolor.green, xcolor.blue, alpha);
// make a copy of each particle position // make a copy of each particle position and radius
std::vector<glm::vec3> positions; std::vector<PositionAndRadius> positionsAndRadiuses;
positions.reserve(getLivingParticleCount()); positionsAndRadiuses.reserve(getLivingParticleCount());
for (quint32 i = _particleHeadIndex; i != _particleTailIndex; i = (i + 1) % _maxParticles) { for (quint32 i = _particleHeadIndex; i != _particleTailIndex; i = (i + 1) % _maxParticles) {
positions.push_back(_particlePositions[i]); positionsAndRadiuses.push_back(PositionAndRadius(_particlePositions[i], _particleRadiuses[i]));
} }
// sort particles back to front // sort particles back to front
// NOTE: this is view frustum might be one frame out of date. // NOTE: this is view frustum might be one frame out of date.
auto frustum = AbstractViewStateInterface::instance()->getCurrentViewFrustum(); auto frustum = AbstractViewStateInterface::instance()->getCurrentViewFrustum();
::zSortAxis = frustum->getDirection(); ::zSortAxis = frustum->getDirection();
qSort(positions.begin(), positions.end(), zSort); qSort(positionsAndRadiuses.begin(), positionsAndRadiuses.end(), zSort);
// allocate vertices // allocate vertices
_vertices.clear(); _vertices.clear();
// build vertices from particle positions // build vertices from particle positions
const glm::vec3 upOffset = frustum->getUp() * particleRadius; const glm::vec3 up = frustum->getUp();
const glm::vec3 rightOffset = frustum->getRight() * particleRadius; const glm::vec3 right = frustum->getRight();
for (auto&& pos : positions) { for (auto&& particle : positionsAndRadiuses) {
glm::vec3 upOffset = up * particle.radius;
glm::vec3 rightOffset = right * particle.radius;
// generate corners of quad aligned to face the camera. // generate corners of quad aligned to face the camera.
_vertices.emplace_back(pos + rightOffset + upOffset, glm::vec2(1.0f, 1.0f), rgba); _vertices.emplace_back(particle.position + rightOffset + upOffset, glm::vec2(1.0f, 1.0f), rgba);
_vertices.emplace_back(pos - rightOffset + upOffset, glm::vec2(0.0f, 1.0f), rgba); _vertices.emplace_back(particle.position - rightOffset + upOffset, glm::vec2(0.0f, 1.0f), rgba);
_vertices.emplace_back(pos - rightOffset - upOffset, glm::vec2(0.0f, 0.0f), rgba); _vertices.emplace_back(particle.position - rightOffset - upOffset, glm::vec2(0.0f, 0.0f), rgba);
_vertices.emplace_back(pos + rightOffset - upOffset, glm::vec2(1.0f, 0.0f), rgba); _vertices.emplace_back(particle.position + rightOffset - upOffset, glm::vec2(1.0f, 0.0f), rgba);
} }
render::PendingChanges pendingChanges; render::PendingChanges pendingChanges;
pendingChanges.updateItem<ParticlePayload>(_renderItemId, [this](ParticlePayload& payload) { pendingChanges.updateItem<ParticlePayload>(_renderItemId, [this](ParticlePayload& payload) {
// update vertex buffer // update vertex buffer

View file

@ -89,6 +89,7 @@ CONSTRUCT_PROPERTY(velocitySpread, ParticleEffectEntityItem::DEFAULT_VELOCITY_SP
CONSTRUCT_PROPERTY(emitAcceleration, ParticleEffectEntityItem::DEFAULT_EMIT_ACCELERATION), CONSTRUCT_PROPERTY(emitAcceleration, ParticleEffectEntityItem::DEFAULT_EMIT_ACCELERATION),
CONSTRUCT_PROPERTY(accelerationSpread, ParticleEffectEntityItem::DEFAULT_ACCELERATION_SPREAD), CONSTRUCT_PROPERTY(accelerationSpread, ParticleEffectEntityItem::DEFAULT_ACCELERATION_SPREAD),
CONSTRUCT_PROPERTY(particleRadius, ParticleEffectEntityItem::DEFAULT_PARTICLE_RADIUS), CONSTRUCT_PROPERTY(particleRadius, ParticleEffectEntityItem::DEFAULT_PARTICLE_RADIUS),
CONSTRUCT_PROPERTY(radiusSpread, ParticleEffectEntityItem::DEFAULT_RADIUS_SPREAD),
CONSTRUCT_PROPERTY(marketplaceID, ENTITY_ITEM_DEFAULT_MARKETPLACE_ID), CONSTRUCT_PROPERTY(marketplaceID, ENTITY_ITEM_DEFAULT_MARKETPLACE_ID),
CONSTRUCT_PROPERTY(keyLightColor, ZoneEntityItem::DEFAULT_KEYLIGHT_COLOR), CONSTRUCT_PROPERTY(keyLightColor, ZoneEntityItem::DEFAULT_KEYLIGHT_COLOR),
CONSTRUCT_PROPERTY(keyLightIntensity, ZoneEntityItem::DEFAULT_KEYLIGHT_INTENSITY), CONSTRUCT_PROPERTY(keyLightIntensity, ZoneEntityItem::DEFAULT_KEYLIGHT_INTENSITY),
@ -355,6 +356,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
CHECK_PROPERTY_CHANGE(PROP_EMIT_ACCELERATION, emitAcceleration); CHECK_PROPERTY_CHANGE(PROP_EMIT_ACCELERATION, emitAcceleration);
CHECK_PROPERTY_CHANGE(PROP_ACCELERATION_SPREAD, accelerationSpread); CHECK_PROPERTY_CHANGE(PROP_ACCELERATION_SPREAD, accelerationSpread);
CHECK_PROPERTY_CHANGE(PROP_PARTICLE_RADIUS, particleRadius); CHECK_PROPERTY_CHANGE(PROP_PARTICLE_RADIUS, particleRadius);
CHECK_PROPERTY_CHANGE(PROP_RADIUS_SPREAD, radiusSpread);
CHECK_PROPERTY_CHANGE(PROP_MARKETPLACE_ID, marketplaceID); CHECK_PROPERTY_CHANGE(PROP_MARKETPLACE_ID, marketplaceID);
CHECK_PROPERTY_CHANGE(PROP_NAME, name); CHECK_PROPERTY_CHANGE(PROP_NAME, name);
CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_COLOR, keyLightColor); CHECK_PROPERTY_CHANGE(PROP_KEYLIGHT_COLOR, keyLightColor);
@ -458,6 +460,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
COPY_PROPERTY_TO_QSCRIPTVALUE(emitAcceleration); COPY_PROPERTY_TO_QSCRIPTVALUE(emitAcceleration);
COPY_PROPERTY_TO_QSCRIPTVALUE(accelerationSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(accelerationSpread);
COPY_PROPERTY_TO_QSCRIPTVALUE(particleRadius); COPY_PROPERTY_TO_QSCRIPTVALUE(particleRadius);
COPY_PROPERTY_TO_QSCRIPTVALUE(radiusSpread);
COPY_PROPERTY_TO_QSCRIPTVALUE(marketplaceID); COPY_PROPERTY_TO_QSCRIPTVALUE(marketplaceID);
COPY_PROPERTY_TO_QSCRIPTVALUE(name); COPY_PROPERTY_TO_QSCRIPTVALUE(name);
COPY_PROPERTY_TO_QSCRIPTVALUE(collisionSoundURL); COPY_PROPERTY_TO_QSCRIPTVALUE(collisionSoundURL);
@ -579,6 +582,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
COPY_PROPERTY_FROM_QSCRIPTVALUE(emitAcceleration, glmVec3, setEmitAcceleration); COPY_PROPERTY_FROM_QSCRIPTVALUE(emitAcceleration, glmVec3, setEmitAcceleration);
COPY_PROPERTY_FROM_QSCRIPTVALUE(accelerationSpread, glmVec3, setAccelerationSpread); COPY_PROPERTY_FROM_QSCRIPTVALUE(accelerationSpread, glmVec3, setAccelerationSpread);
COPY_PROPERTY_FROM_QSCRIPTVALUE(particleRadius, float, setParticleRadius); COPY_PROPERTY_FROM_QSCRIPTVALUE(particleRadius, float, setParticleRadius);
COPY_PROPERTY_FROM_QSCRIPTVALUE(radiusSpread, float, setRadiusSpread);
COPY_PROPERTY_FROM_QSCRIPTVALUE(marketplaceID, QString, setMarketplaceID); COPY_PROPERTY_FROM_QSCRIPTVALUE(marketplaceID, QString, setMarketplaceID);
COPY_PROPERTY_FROM_QSCRIPTVALUE(name, QString, setName); COPY_PROPERTY_FROM_QSCRIPTVALUE(name, QString, setName);
COPY_PROPERTY_FROM_QSCRIPTVALUE(collisionSoundURL, QString, setCollisionSoundURL); COPY_PROPERTY_FROM_QSCRIPTVALUE(collisionSoundURL, QString, setCollisionSoundURL);
@ -821,7 +825,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType::Value command, Ent
APPEND_ENTITY_PROPERTY(PROP_EMIT_ACCELERATION, properties.getEmitAcceleration()); APPEND_ENTITY_PROPERTY(PROP_EMIT_ACCELERATION, properties.getEmitAcceleration());
APPEND_ENTITY_PROPERTY(PROP_ACCELERATION_SPREAD, properties.getAccelerationSpread()); APPEND_ENTITY_PROPERTY(PROP_ACCELERATION_SPREAD, properties.getAccelerationSpread());
APPEND_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, properties.getParticleRadius()); APPEND_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, properties.getParticleRadius());
APPEND_ENTITY_PROPERTY(PROP_RADIUS_SPREAD, properties.getRadiusSpread());
} }
if (properties.getType() == EntityTypes::Zone) { if (properties.getType() == EntityTypes::Zone) {
@ -1091,6 +1095,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_ACCELERATION, glm::vec3, setEmitAcceleration); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_ACCELERATION, glm::vec3, setEmitAcceleration);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ACCELERATION_SPREAD, glm::vec3, setAccelerationSpread); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ACCELERATION_SPREAD, glm::vec3, setAccelerationSpread);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARTICLE_RADIUS, float, setParticleRadius); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARTICLE_RADIUS, float, setParticleRadius);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_RADIUS_SPREAD, float, setRadiusSpread);
} }
if (properties.getType() == EntityTypes::Zone) { if (properties.getType() == EntityTypes::Zone) {
@ -1223,6 +1228,7 @@ void EntityItemProperties::markAllChanged() {
_emitAccelerationChanged = true; _emitAccelerationChanged = true;
_accelerationSpreadChanged = true; _accelerationSpreadChanged = true;
_particleRadiusChanged = true; _particleRadiusChanged = true;
_radiusSpreadChanged = true;
_marketplaceIDChanged = true; _marketplaceIDChanged = true;

View file

@ -136,6 +136,7 @@ public:
DEFINE_PROPERTY(PROP_EMIT_ACCELERATION, EmitAcceleration, emitAcceleration, glm::vec3); DEFINE_PROPERTY(PROP_EMIT_ACCELERATION, EmitAcceleration, emitAcceleration, glm::vec3);
DEFINE_PROPERTY(PROP_ACCELERATION_SPREAD, AccelerationSpread, accelerationSpread, glm::vec3); DEFINE_PROPERTY(PROP_ACCELERATION_SPREAD, AccelerationSpread, accelerationSpread, glm::vec3);
DEFINE_PROPERTY(PROP_PARTICLE_RADIUS, ParticleRadius, particleRadius, float); DEFINE_PROPERTY(PROP_PARTICLE_RADIUS, ParticleRadius, particleRadius, float);
DEFINE_PROPERTY(PROP_RADIUS_SPREAD, RadiusSpread, radiusSpread, float);
DEFINE_PROPERTY_REF(PROP_MARKETPLACE_ID, MarketplaceID, marketplaceID, QString); DEFINE_PROPERTY_REF(PROP_MARKETPLACE_ID, MarketplaceID, marketplaceID, QString);
DEFINE_PROPERTY_REF(PROP_KEYLIGHT_COLOR, KeyLightColor, keyLightColor, xColor); DEFINE_PROPERTY_REF(PROP_KEYLIGHT_COLOR, KeyLightColor, keyLightColor, xColor);
DEFINE_PROPERTY(PROP_KEYLIGHT_INTENSITY, KeyLightIntensity, keyLightIntensity, float); DEFINE_PROPERTY(PROP_KEYLIGHT_INTENSITY, KeyLightIntensity, keyLightIntensity, float);
@ -316,6 +317,7 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) {
DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitAcceleration, emitAcceleration, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitAcceleration, emitAcceleration, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, AccelerationSpread, accelerationSpread, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, AccelerationSpread, accelerationSpread, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, ParticleRadius, particleRadius, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, ParticleRadius, particleRadius, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, RadiusSpread, radiusSpread, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, MarketplaceID, marketplaceID, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, MarketplaceID, marketplaceID, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, BackgroundMode, backgroundMode, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, BackgroundMode, backgroundMode, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, VoxelVolumeSize, voxelVolumeSize, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, VoxelVolumeSize, voxelVolumeSize, "");

View file

@ -138,6 +138,7 @@ enum EntityPropertyList {
// used by particles // used by particles
PROP_VELOCITY_SPREAD, PROP_VELOCITY_SPREAD,
PROP_ACCELERATION_SPREAD, PROP_ACCELERATION_SPREAD,
PROP_RADIUS_SPREAD,
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
// ATTENTION: add new properties to end of list just ABOVE this line // ATTENTION: add new properties to end of list just ABOVE this line

View file

@ -54,6 +54,7 @@ const glm::vec3 ParticleEffectEntityItem::DEFAULT_VELOCITY_SPREAD(3.0f, 0.0f, 3.
const glm::vec3 ParticleEffectEntityItem::DEFAULT_EMIT_ACCELERATION(0.0f, -9.8f, 0.0f); const glm::vec3 ParticleEffectEntityItem::DEFAULT_EMIT_ACCELERATION(0.0f, -9.8f, 0.0f);
const glm::vec3 ParticleEffectEntityItem::DEFAULT_ACCELERATION_SPREAD(0.0f, 0.0f, 0.0f); const glm::vec3 ParticleEffectEntityItem::DEFAULT_ACCELERATION_SPREAD(0.0f, 0.0f, 0.0f);
const float ParticleEffectEntityItem::DEFAULT_PARTICLE_RADIUS = 0.025f; const float ParticleEffectEntityItem::DEFAULT_PARTICLE_RADIUS = 0.025f;
const float ParticleEffectEntityItem::DEFAULT_RADIUS_SPREAD = 0.0f;
const QString ParticleEffectEntityItem::DEFAULT_TEXTURES = ""; const QString ParticleEffectEntityItem::DEFAULT_TEXTURES = "";
@ -72,6 +73,7 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte
_emitAcceleration(DEFAULT_EMIT_ACCELERATION), _emitAcceleration(DEFAULT_EMIT_ACCELERATION),
_accelerationSpread(DEFAULT_ACCELERATION_SPREAD), _accelerationSpread(DEFAULT_ACCELERATION_SPREAD),
_particleRadius(DEFAULT_PARTICLE_RADIUS), _particleRadius(DEFAULT_PARTICLE_RADIUS),
_radiusSpread(DEFAULT_RADIUS_SPREAD),
_lastAnimated(usecTimestampNow()), _lastAnimated(usecTimestampNow()),
_animationLoop(), _animationLoop(),
_animationSettings(), _animationSettings(),
@ -82,6 +84,7 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte
_particlePositions(DEFAULT_MAX_PARTICLES, glm::vec3(0.0f, 0.0f, 0.0f)), _particlePositions(DEFAULT_MAX_PARTICLES, glm::vec3(0.0f, 0.0f, 0.0f)),
_particleVelocities(DEFAULT_MAX_PARTICLES, glm::vec3(0.0f, 0.0f, 0.0f)), _particleVelocities(DEFAULT_MAX_PARTICLES, glm::vec3(0.0f, 0.0f, 0.0f)),
_particleAccelerations(DEFAULT_MAX_PARTICLES, glm::vec3(0.0f, 0.0f, 0.0f)), _particleAccelerations(DEFAULT_MAX_PARTICLES, glm::vec3(0.0f, 0.0f, 0.0f)),
_particleRadiuses(DEFAULT_MAX_PARTICLES, DEFAULT_PARTICLE_RADIUS),
_timeUntilNextEmit(0.0f), _timeUntilNextEmit(0.0f),
_particleHeadIndex(0), _particleHeadIndex(0),
_particleTailIndex(0), _particleTailIndex(0),
@ -111,7 +114,6 @@ void ParticleEffectEntityItem::setVelocitySpread(const glm::vec3& velocitySpread
computeAndUpdateDimensions(); computeAndUpdateDimensions();
} }
void ParticleEffectEntityItem::setEmitAcceleration(const glm::vec3& emitAcceleration) { void ParticleEffectEntityItem::setEmitAcceleration(const glm::vec3& emitAcceleration) {
_emitAcceleration = emitAcceleration; _emitAcceleration = emitAcceleration;
computeAndUpdateDimensions(); computeAndUpdateDimensions();
@ -126,6 +128,10 @@ void ParticleEffectEntityItem::setParticleRadius(float particleRadius) {
_particleRadius = particleRadius; _particleRadius = particleRadius;
} }
void ParticleEffectEntityItem::setRadiusSpread(float radiusSpread) {
_radiusSpread = radiusSpread;
}
void ParticleEffectEntityItem::computeAndUpdateDimensions() { void ParticleEffectEntityItem::computeAndUpdateDimensions() {
const float time = _lifespan * 1.1f; // add 10% extra time to account for incremental timer accumulation error const float time = _lifespan * 1.1f; // add 10% extra time to account for incremental timer accumulation error
@ -163,9 +169,9 @@ EntityItemProperties ParticleEffectEntityItem::getProperties() const {
COPY_ENTITY_PROPERTY_TO_PROPERTIES(lifespan, getLifespan); COPY_ENTITY_PROPERTY_TO_PROPERTIES(lifespan, getLifespan);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitRate, getEmitRate); COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitRate, getEmitRate);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitVelocity, getEmitVelocity); COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitVelocity, getEmitVelocity);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitAcceleration, getEmitAcceleration); COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitAcceleration, getEmitAcceleration);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(particleRadius, getParticleRadius); COPY_ENTITY_PROPERTY_TO_PROPERTIES(particleRadius, getParticleRadius);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(radiusSpread, getRadiusSpread);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures); COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures);
return properties; return properties;
@ -185,11 +191,12 @@ bool ParticleEffectEntityItem::setProperties(const EntityItemProperties& propert
SET_ENTITY_PROPERTY_FROM_PROPERTIES(lifespan, setLifespan); SET_ENTITY_PROPERTY_FROM_PROPERTIES(lifespan, setLifespan);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitRate, setEmitRate); SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitRate, setEmitRate);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitVelocity, setEmitVelocity); SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitVelocity, setEmitVelocity);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(velocitySpread, setVelocitySpread);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitAcceleration, setEmitAcceleration); SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitAcceleration, setEmitAcceleration);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(accelerationSpread, setAccelerationSpread); SET_ENTITY_PROPERTY_FROM_PROPERTIES(accelerationSpread, setAccelerationSpread);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(particleRadius, setParticleRadius); SET_ENTITY_PROPERTY_FROM_PROPERTIES(particleRadius, setParticleRadius);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(radiusSpread, setRadiusSpread);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures); SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(velocitySpread, setVelocitySpread);
if (somethingChanged) { if (somethingChanged) {
bool wantDebug = false; bool wantDebug = false;
@ -257,6 +264,10 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch
READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures); READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures);
} }
if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLE_RADIUS_SPREAD) {
READ_ENTITY_PROPERTY(PROP_RADIUS_SPREAD, float, setRadiusSpread);
}
return bytesRead; return bytesRead;
} }
@ -280,6 +291,7 @@ EntityPropertyFlags ParticleEffectEntityItem::getEntityProperties(EncodeBitstrea
requestedProperties += PROP_PARTICLE_RADIUS; requestedProperties += PROP_PARTICLE_RADIUS;
requestedProperties += PROP_TEXTURES; requestedProperties += PROP_TEXTURES;
requestedProperties += PROP_VELOCITY_SPREAD; requestedProperties += PROP_VELOCITY_SPREAD;
requestedProperties += PROP_RADIUS_SPREAD;
return requestedProperties; return requestedProperties;
} }
@ -308,6 +320,7 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData,
APPEND_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, getParticleRadius()); APPEND_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, getParticleRadius());
APPEND_ENTITY_PROPERTY(PROP_TEXTURES, getTextures()); APPEND_ENTITY_PROPERTY(PROP_TEXTURES, getTextures());
APPEND_ENTITY_PROPERTY(PROP_VELOCITY_SPREAD, getVelocitySpread()); APPEND_ENTITY_PROPERTY(PROP_VELOCITY_SPREAD, getVelocitySpread());
APPEND_ENTITY_PROPERTY(PROP_RADIUS_SPREAD, getRadiusSpread());
} }
bool ParticleEffectEntityItem::isAnimatingSomething() const { bool ParticleEffectEntityItem::isAnimatingSomething() const {
@ -514,7 +527,7 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) {
} }
} }
// emit new particles, but only if animaiton is playing // emit new particles, but only if animation is playing
if (getAnimationIsPlaying()) { if (getAnimationIsPlaying()) {
float timeLeftInFrame = deltaTime; float timeLeftInFrame = deltaTime;
@ -527,12 +540,12 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) {
quint32 i = _particleTailIndex; quint32 i = _particleTailIndex;
_particleLifetimes[i] = _lifespan; _particleLifetimes[i] = _lifespan;
_particleRadiuses[i] = _particleRadius + (2.0f * randFloat() - 1) * _radiusSpread;
glm::vec3 spreadOffset; glm::vec3 spreadOffset;
spreadOffset.x = -_velocitySpread.x + randFloat() * (_velocitySpread.x * 2.0f); spreadOffset.x = -_velocitySpread.x + randFloat() * (_velocitySpread.x * 2.0f);
spreadOffset.y = -_velocitySpread.y + randFloat() * (_velocitySpread.y * 2.0f); spreadOffset.y = -_velocitySpread.y + randFloat() * (_velocitySpread.y * 2.0f);
spreadOffset.z = -_velocitySpread.z + randFloat() * (_velocitySpread.z * 2.0f); spreadOffset.z = -_velocitySpread.z + randFloat() * (_velocitySpread.z * 2.0f);
// set initial conditions // set initial conditions
_particlePositions[i] = getPosition(); _particlePositions[i] = getPosition();
@ -571,8 +584,9 @@ void ParticleEffectEntityItem::setMaxParticles(quint32 maxParticles) {
_particleLifetimes.resize(_maxParticles); _particleLifetimes.resize(_maxParticles);
_particlePositions.resize(_maxParticles); _particlePositions.resize(_maxParticles);
_particleVelocities.resize(_maxParticles); _particleVelocities.resize(_maxParticles);
_particleRadiuses.resize(_maxParticles);
// effectivly clear all particles and start emitting new ones from scratch. // effectively clear all particles and start emitting new ones from scratch.
_particleHeadIndex = 0; _particleHeadIndex = 0;
_particleTailIndex = 0; _particleTailIndex = 0;
_timeUntilNextEmit = 0.0f; _timeUntilNextEmit = 0.0f;

View file

@ -102,12 +102,10 @@ public:
void setEmitVelocity(const glm::vec3& emitVelocity); void setEmitVelocity(const glm::vec3& emitVelocity);
const glm::vec3& getEmitVelocity() const { return _emitVelocity; } const glm::vec3& getEmitVelocity() const { return _emitVelocity; }
static const glm::vec3 DEFAULT_VELOCITY_SPREAD; static const glm::vec3 DEFAULT_VELOCITY_SPREAD;
void setVelocitySpread(const glm::vec3& velocitySpread); void setVelocitySpread(const glm::vec3& velocitySpread);
const glm::vec3& getVelocitySpread() const { return _velocitySpread; } const glm::vec3& getVelocitySpread() const { return _velocitySpread; }
static const glm::vec3 DEFAULT_EMIT_ACCELERATION; static const glm::vec3 DEFAULT_EMIT_ACCELERATION;
void setEmitAcceleration(const glm::vec3& emitAcceleration); void setEmitAcceleration(const glm::vec3& emitAcceleration);
const glm::vec3& getEmitAcceleration() const { return _emitAcceleration; } const glm::vec3& getEmitAcceleration() const { return _emitAcceleration; }
@ -119,7 +117,11 @@ public:
static const float DEFAULT_PARTICLE_RADIUS; static const float DEFAULT_PARTICLE_RADIUS;
void setParticleRadius(float particleRadius); void setParticleRadius(float particleRadius);
float getParticleRadius() const { return _particleRadius; } float getParticleRadius() const { return _particleRadius; }
static const float DEFAULT_RADIUS_SPREAD;
void setRadiusSpread(float radiusSpread);
float getRadiusSpread() const { return _radiusSpread; }
void computeAndUpdateDimensions(); void computeAndUpdateDimensions();
@ -155,6 +157,7 @@ protected:
glm::vec3 _emitAcceleration; glm::vec3 _emitAcceleration;
glm::vec3 _accelerationSpread; glm::vec3 _accelerationSpread;
float _particleRadius; float _particleRadius;
float _radiusSpread;
quint64 _lastAnimated; quint64 _lastAnimated;
AnimationLoop _animationLoop; AnimationLoop _animationLoop;
QString _animationSettings; QString _animationSettings;
@ -167,6 +170,7 @@ protected:
QVector<glm::vec3> _particlePositions; QVector<glm::vec3> _particlePositions;
QVector<glm::vec3> _particleVelocities; QVector<glm::vec3> _particleVelocities;
QVector<glm::vec3> _particleAccelerations; QVector<glm::vec3> _particleAccelerations;
QVector<float> _particleRadiuses;
float _timeUntilNextEmit; float _timeUntilNextEmit;
// particle arrays are a ring buffer, use these indicies // particle arrays are a ring buffer, use these indicies

View file

@ -67,7 +67,7 @@ PacketVersion versionForPacketType(PacketType::Value packetType) {
case EntityAdd: case EntityAdd:
case EntityEdit: case EntityEdit:
case EntityData: case EntityData:
return VERSION_ENTITIES_PARTICLE_MODIFICATIONS; return VERSION_ENTITIES_PARTICLE_RADIUS_SPREAD;
case AvatarData: case AvatarData:
return 13; return 13;
default: default:

View file

@ -144,5 +144,6 @@ const PacketVersion VERSION_POLYVOX_TEXTURES = 36;
const PacketVersion VERSION_ENTITIES_POLYLINE = 37; const PacketVersion VERSION_ENTITIES_POLYLINE = 37;
const PacketVersion VERSION_OCTREE_CENTERED_ORIGIN = 38; const PacketVersion VERSION_OCTREE_CENTERED_ORIGIN = 38;
const PacketVersion VERSION_ENTITIES_PARTICLE_MODIFICATIONS = 39; const PacketVersion VERSION_ENTITIES_PARTICLE_MODIFICATIONS = 39;
const PacketVersion VERSION_ENTITIES_PARTICLE_RADIUS_SPREAD = 40;
#endif // hifi_PacketHeaders_h #endif // hifi_PacketHeaders_h