Merge pull request #5561 from ericrius1/particleExtensions

Extended Particle entity to allow for more varied effects
This commit is contained in:
Brad Hefta-Gaub 2015-08-27 10:45:03 -07:00
commit 7b2f944f48
10 changed files with 164 additions and 135 deletions

View file

@ -39,10 +39,11 @@
this.entity = Entities.addEntity({ type: "ParticleEffect", this.entity = Entities.addEntity({ type: "ParticleEffect",
animationSettings: animationSettings, animationSettings: animationSettings,
position: spawnPoint, position: spawnPoint,
textures: "http://www.hyperlogic.org/images/particle.png", dimensions: {x: 2, y: 2, z: 2},
emitRate: emitRate, emitVelocity: {x: 0, y: 5, z: 0},
emitStrength: emitStrength, velocitySpread: {x: 2, y: 0, z: 2},
emitDirection: emitDirection, emitAcceleration: {x: 0, y: -9.8, z: 0},
textures: "https://raw.githubusercontent.com/ericrius1/SantasLair/santa/assets/smokeparticle.png",
color: color, color: color,
lifespan: 1.0, lifespan: 1.0,
visible: true, visible: true,

View file

@ -247,7 +247,6 @@ void RenderableParticleEffectEntityItem::updateRenderItem() {
glm::vec3 pos = _transform.getTranslation(); glm::vec3 pos = _transform.getTranslation();
Transform t; Transform t;
t.setRotation(rot); t.setRotation(rot);
t.setTranslation(pos);
payload.setModelTransform(t); payload.setModelTransform(t);
// transform _particleMinBound and _particleMaxBound corners into world coords // transform _particleMinBound and _particleMaxBound corners into world coords
@ -285,7 +284,7 @@ void RenderableParticleEffectEntityItem::updateRenderItem() {
payload.setPipeline(_untexturedPipeline); payload.setPipeline(_untexturedPipeline);
} }
}); });
_scene->enqueuePendingChanges(pendingChanges); _scene->enqueuePendingChanges(pendingChanges);
} }
@ -295,7 +294,7 @@ void RenderableParticleEffectEntityItem::createPipelines() {
state->setCullMode(gpu::State::CULL_BACK); state->setCullMode(gpu::State::CULL_BACK);
state->setDepthTest(true, true, gpu::LESS_EQUAL); state->setDepthTest(true, true, gpu::LESS_EQUAL);
state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD,
gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA, gpu::State::ONE, gpu::State::FACTOR_ALPHA,
gpu::State::BLEND_OP_ADD, gpu::State::ONE); gpu::State::BLEND_OP_ADD, gpu::State::ONE);
auto vertShader = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(untextured_particle_vert))); auto vertShader = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(untextured_particle_vert)));
auto fragShader = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(untextured_particle_frag))); auto fragShader = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(untextured_particle_frag)));

View file

@ -610,6 +610,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef
auto nodeList = DependencyManager::get<NodeList>(); auto nodeList = DependencyManager::get<NodeList>();
const QUuid& myNodeID = nodeList->getSessionUUID(); const QUuid& myNodeID = nodeList->getSessionUUID();
bool weOwnSimulation = _simulationOwner.matchesValidID(myNodeID); bool weOwnSimulation = _simulationOwner.matchesValidID(myNodeID);
if (args.bitstreamVersion >= VERSION_ENTITIES_HAVE_SIMULATION_OWNER_AND_ACTIONS_OVER_WIRE) { if (args.bitstreamVersion >= VERSION_ENTITIES_HAVE_SIMULATION_OWNER_AND_ACTIONS_OVER_WIRE) {
// pack SimulationOwner and terse update properties near each other // pack SimulationOwner and terse update properties near each other

View file

@ -84,9 +84,10 @@ CONSTRUCT_PROPERTY(shapeType, SHAPE_TYPE_NONE),
CONSTRUCT_PROPERTY(maxParticles, ParticleEffectEntityItem::DEFAULT_MAX_PARTICLES), CONSTRUCT_PROPERTY(maxParticles, ParticleEffectEntityItem::DEFAULT_MAX_PARTICLES),
CONSTRUCT_PROPERTY(lifespan, ParticleEffectEntityItem::DEFAULT_LIFESPAN), CONSTRUCT_PROPERTY(lifespan, ParticleEffectEntityItem::DEFAULT_LIFESPAN),
CONSTRUCT_PROPERTY(emitRate, ParticleEffectEntityItem::DEFAULT_EMIT_RATE), CONSTRUCT_PROPERTY(emitRate, ParticleEffectEntityItem::DEFAULT_EMIT_RATE),
CONSTRUCT_PROPERTY(emitDirection, ParticleEffectEntityItem::DEFAULT_EMIT_DIRECTION), CONSTRUCT_PROPERTY(emitVelocity, ParticleEffectEntityItem::DEFAULT_EMIT_VELOCITY),
CONSTRUCT_PROPERTY(emitStrength, ParticleEffectEntityItem::DEFAULT_EMIT_STRENGTH), CONSTRUCT_PROPERTY(velocitySpread, ParticleEffectEntityItem::DEFAULT_VELOCITY_SPREAD),
CONSTRUCT_PROPERTY(localGravity, ParticleEffectEntityItem::DEFAULT_LOCAL_GRAVITY), CONSTRUCT_PROPERTY(emitAcceleration, ParticleEffectEntityItem::DEFAULT_EMIT_ACCELERATION),
CONSTRUCT_PROPERTY(accelerationSpread, ParticleEffectEntityItem::DEFAULT_ACCELERATION_SPREAD),
CONSTRUCT_PROPERTY(particleRadius, ParticleEffectEntityItem::DEFAULT_PARTICLE_RADIUS), CONSTRUCT_PROPERTY(particleRadius, ParticleEffectEntityItem::DEFAULT_PARTICLE_RADIUS),
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),
@ -349,9 +350,10 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
CHECK_PROPERTY_CHANGE(PROP_MAX_PARTICLES, maxParticles); CHECK_PROPERTY_CHANGE(PROP_MAX_PARTICLES, maxParticles);
CHECK_PROPERTY_CHANGE(PROP_LIFESPAN, lifespan); CHECK_PROPERTY_CHANGE(PROP_LIFESPAN, lifespan);
CHECK_PROPERTY_CHANGE(PROP_EMIT_RATE, emitRate); CHECK_PROPERTY_CHANGE(PROP_EMIT_RATE, emitRate);
CHECK_PROPERTY_CHANGE(PROP_EMIT_DIRECTION, emitDirection); CHECK_PROPERTY_CHANGE(PROP_EMIT_VELOCITY, emitVelocity);
CHECK_PROPERTY_CHANGE(PROP_EMIT_STRENGTH, emitStrength); CHECK_PROPERTY_CHANGE(PROP_VELOCITY_SPREAD, velocitySpread);
CHECK_PROPERTY_CHANGE(PROP_LOCAL_GRAVITY, localGravity); CHECK_PROPERTY_CHANGE(PROP_EMIT_ACCELERATION, emitAcceleration);
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_MARKETPLACE_ID, marketplaceID); CHECK_PROPERTY_CHANGE(PROP_MARKETPLACE_ID, marketplaceID);
CHECK_PROPERTY_CHANGE(PROP_NAME, name); CHECK_PROPERTY_CHANGE(PROP_NAME, name);
@ -451,9 +453,10 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
COPY_PROPERTY_TO_QSCRIPTVALUE(maxParticles); COPY_PROPERTY_TO_QSCRIPTVALUE(maxParticles);
COPY_PROPERTY_TO_QSCRIPTVALUE(lifespan); COPY_PROPERTY_TO_QSCRIPTVALUE(lifespan);
COPY_PROPERTY_TO_QSCRIPTVALUE(emitRate); COPY_PROPERTY_TO_QSCRIPTVALUE(emitRate);
COPY_PROPERTY_TO_QSCRIPTVALUE(emitDirection); COPY_PROPERTY_TO_QSCRIPTVALUE(emitVelocity);
COPY_PROPERTY_TO_QSCRIPTVALUE(emitStrength); COPY_PROPERTY_TO_QSCRIPTVALUE(velocitySpread);
COPY_PROPERTY_TO_QSCRIPTVALUE(localGravity); COPY_PROPERTY_TO_QSCRIPTVALUE(emitAcceleration);
COPY_PROPERTY_TO_QSCRIPTVALUE(accelerationSpread);
COPY_PROPERTY_TO_QSCRIPTVALUE(particleRadius); COPY_PROPERTY_TO_QSCRIPTVALUE(particleRadius);
COPY_PROPERTY_TO_QSCRIPTVALUE(marketplaceID); COPY_PROPERTY_TO_QSCRIPTVALUE(marketplaceID);
COPY_PROPERTY_TO_QSCRIPTVALUE(name); COPY_PROPERTY_TO_QSCRIPTVALUE(name);
@ -571,9 +574,10 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
COPY_PROPERTY_FROM_QSCRIPTVALUE(maxParticles, float, setMaxParticles); COPY_PROPERTY_FROM_QSCRIPTVALUE(maxParticles, float, setMaxParticles);
COPY_PROPERTY_FROM_QSCRIPTVALUE(lifespan, float, setLifespan); COPY_PROPERTY_FROM_QSCRIPTVALUE(lifespan, float, setLifespan);
COPY_PROPERTY_FROM_QSCRIPTVALUE(emitRate, float, setEmitRate); COPY_PROPERTY_FROM_QSCRIPTVALUE(emitRate, float, setEmitRate);
COPY_PROPERTY_FROM_QSCRIPTVALUE(emitDirection, glmVec3, setEmitDirection); COPY_PROPERTY_FROM_QSCRIPTVALUE(emitVelocity, glmVec3, setEmitVelocity);
COPY_PROPERTY_FROM_QSCRIPTVALUE(emitStrength, float, setEmitStrength); COPY_PROPERTY_FROM_QSCRIPTVALUE(velocitySpread, glmVec3, setVelocitySpread);
COPY_PROPERTY_FROM_QSCRIPTVALUE(localGravity, float, setLocalGravity); COPY_PROPERTY_FROM_QSCRIPTVALUE(emitAcceleration, glmVec3, setEmitAcceleration);
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(marketplaceID, QString, setMarketplaceID); COPY_PROPERTY_FROM_QSCRIPTVALUE(marketplaceID, QString, setMarketplaceID);
COPY_PROPERTY_FROM_QSCRIPTVALUE(name, QString, setName); COPY_PROPERTY_FROM_QSCRIPTVALUE(name, QString, setName);
@ -812,10 +816,12 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType::Value command, Ent
APPEND_ENTITY_PROPERTY(PROP_MAX_PARTICLES, properties.getMaxParticles()); APPEND_ENTITY_PROPERTY(PROP_MAX_PARTICLES, properties.getMaxParticles());
APPEND_ENTITY_PROPERTY(PROP_LIFESPAN, properties.getLifespan()); APPEND_ENTITY_PROPERTY(PROP_LIFESPAN, properties.getLifespan());
APPEND_ENTITY_PROPERTY(PROP_EMIT_RATE, properties.getEmitRate()); APPEND_ENTITY_PROPERTY(PROP_EMIT_RATE, properties.getEmitRate());
APPEND_ENTITY_PROPERTY(PROP_EMIT_DIRECTION, properties.getEmitDirection()); APPEND_ENTITY_PROPERTY(PROP_EMIT_VELOCITY, properties.getEmitVelocity());
APPEND_ENTITY_PROPERTY(PROP_EMIT_STRENGTH, properties.getEmitStrength()); APPEND_ENTITY_PROPERTY(PROP_VELOCITY_SPREAD, properties.getVelocitySpread());
APPEND_ENTITY_PROPERTY(PROP_LOCAL_GRAVITY, properties.getLocalGravity()); APPEND_ENTITY_PROPERTY(PROP_EMIT_ACCELERATION, properties.getEmitAcceleration());
APPEND_ENTITY_PROPERTY(PROP_ACCELERATION_SPREAD, properties.getAccelerationSpread());
APPEND_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, properties.getParticleRadius()); APPEND_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, properties.getParticleRadius());
} }
if (properties.getType() == EntityTypes::Zone) { if (properties.getType() == EntityTypes::Zone) {
@ -1080,9 +1086,10 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MAX_PARTICLES, float, setMaxParticles); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_MAX_PARTICLES, float, setMaxParticles);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LIFESPAN, float, setLifespan); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LIFESPAN, float, setLifespan);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_RATE, float, setEmitRate); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_RATE, float, setEmitRate);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_DIRECTION, glm::vec3, setEmitDirection); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_VELOCITY, glm::vec3, setEmitVelocity);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_EMIT_STRENGTH, float, setEmitStrength); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VELOCITY_SPREAD, glm::vec3, setVelocitySpread);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_LOCAL_GRAVITY, float, setLocalGravity); 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_PARTICLE_RADIUS, float, setParticleRadius); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_PARTICLE_RADIUS, float, setParticleRadius);
} }
@ -1211,9 +1218,10 @@ void EntityItemProperties::markAllChanged() {
_maxParticlesChanged = true; _maxParticlesChanged = true;
_lifespanChanged = true; _lifespanChanged = true;
_emitRateChanged = true; _emitRateChanged = true;
_emitDirectionChanged = true; _emitVelocityChanged = true;
_emitStrengthChanged = true; _velocitySpreadChanged = true;
_localGravityChanged = true; _emitAccelerationChanged = true;
_accelerationSpreadChanged = true;
_particleRadiusChanged = true; _particleRadiusChanged = true;
_marketplaceIDChanged = true; _marketplaceIDChanged = true;

View file

@ -131,9 +131,10 @@ public:
DEFINE_PROPERTY(PROP_MAX_PARTICLES, MaxParticles, maxParticles, quint32); DEFINE_PROPERTY(PROP_MAX_PARTICLES, MaxParticles, maxParticles, quint32);
DEFINE_PROPERTY(PROP_LIFESPAN, Lifespan, lifespan, float); DEFINE_PROPERTY(PROP_LIFESPAN, Lifespan, lifespan, float);
DEFINE_PROPERTY(PROP_EMIT_RATE, EmitRate, emitRate, float); DEFINE_PROPERTY(PROP_EMIT_RATE, EmitRate, emitRate, float);
DEFINE_PROPERTY_REF(PROP_EMIT_DIRECTION, EmitDirection, emitDirection, glm::vec3); DEFINE_PROPERTY_REF(PROP_EMIT_VELOCITY, EmitVelocity, emitVelocity, glm::vec3);
DEFINE_PROPERTY(PROP_EMIT_STRENGTH, EmitStrength, emitStrength, float); DEFINE_PROPERTY_REF(PROP_VELOCITY_SPREAD, VelocitySpread, velocitySpread, glm::vec3);
DEFINE_PROPERTY(PROP_LOCAL_GRAVITY, LocalGravity, localGravity, float); DEFINE_PROPERTY(PROP_EMIT_ACCELERATION, EmitAcceleration, emitAcceleration, 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_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);
@ -311,9 +312,9 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) {
DEBUG_PROPERTY_IF_CHANGED(debug, properties, MaxParticles, maxParticles, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, MaxParticles, maxParticles, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, Lifespan, lifespan, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, Lifespan, lifespan, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitRate, emitRate, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitRate, emitRate, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitDirection, emitDirection, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitVelocity, emitVelocity, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitStrength, emitStrength, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, EmitAcceleration, emitAcceleration, "");
DEBUG_PROPERTY_IF_CHANGED(debug, properties, LocalGravity, localGravity, ""); 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, 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, "");

View file

@ -96,9 +96,9 @@ enum EntityPropertyList {
PROP_MAX_PARTICLES, PROP_MAX_PARTICLES,
PROP_LIFESPAN, PROP_LIFESPAN,
PROP_EMIT_RATE, PROP_EMIT_RATE,
PROP_EMIT_DIRECTION, PROP_EMIT_VELOCITY,
PROP_EMIT_STRENGTH, PROP_EMIT_STRENGTH,
PROP_LOCAL_GRAVITY, PROP_EMIT_ACCELERATION,
PROP_PARTICLE_RADIUS, PROP_PARTICLE_RADIUS,
PROP_COMPOUND_SHAPE_URL, // used by Model + zones entities PROP_COMPOUND_SHAPE_URL, // used by Model + zones entities
@ -134,7 +134,10 @@ enum EntityPropertyList {
// Used by PolyLine entity // Used by PolyLine entity
PROP_NORMALS, PROP_NORMALS,
PROP_STROKE_WIDTHS, PROP_STROKE_WIDTHS,
// used by particles
PROP_VELOCITY_SPREAD,
PROP_ACCELERATION_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
@ -168,9 +171,9 @@ enum EntityPropertyList {
PROP_ATMOSPHERE_CENTER = PROP_MAX_PARTICLES, PROP_ATMOSPHERE_CENTER = PROP_MAX_PARTICLES,
PROP_ATMOSPHERE_INNER_RADIUS = PROP_LIFESPAN, PROP_ATMOSPHERE_INNER_RADIUS = PROP_LIFESPAN,
PROP_ATMOSPHERE_OUTER_RADIUS = PROP_EMIT_RATE, PROP_ATMOSPHERE_OUTER_RADIUS = PROP_EMIT_RATE,
PROP_ATMOSPHERE_MIE_SCATTERING = PROP_EMIT_DIRECTION, PROP_ATMOSPHERE_MIE_SCATTERING = PROP_EMIT_VELOCITY,
PROP_ATMOSPHERE_RAYLEIGH_SCATTERING = PROP_EMIT_STRENGTH, PROP_ATMOSPHERE_RAYLEIGH_SCATTERING = PROP_EMIT_STRENGTH,
PROP_ATMOSPHERE_SCATTERING_WAVELENGTHS = PROP_LOCAL_GRAVITY, PROP_ATMOSPHERE_SCATTERING_WAVELENGTHS = PROP_EMIT_ACCELERATION,
PROP_ATMOSPHERE_HAS_STARS = PROP_PARTICLE_RADIUS, PROP_ATMOSPHERE_HAS_STARS = PROP_PARTICLE_RADIUS,
PROP_BACKGROUND_MODE = PROP_MODEL_URL, PROP_BACKGROUND_MODE = PROP_MODEL_URL,
PROP_SKYBOX_COLOR = PROP_ANIMATION_URL, PROP_SKYBOX_COLOR = PROP_ANIMATION_URL,

View file

@ -16,7 +16,6 @@
// - Just to get this out the door, I just did forward Euler integration. There are better ways. // - Just to get this out the door, I just did forward Euler integration. There are better ways.
// - Gravity always points along the Y axis. Support an actual gravity vector. // - Gravity always points along the Y axis. Support an actual gravity vector.
// - Add the ability to add arbitrary forces to the simulation. // - Add the ability to add arbitrary forces to the simulation.
// - Add controls for spread (which is currently hard-coded) and varying emission strength (not currently implemented).
// - Add drag. // - Add drag.
// - Add some kind of support for collisions. // - Add some kind of support for collisions.
// - There's no synchronization of the simulation across clients at all. In fact, it's using rand() under the hood, so // - There's no synchronization of the simulation across clients at all. In fact, it's using rand() under the hood, so
@ -50,9 +49,10 @@ const float ParticleEffectEntityItem::DEFAULT_ANIMATION_FPS = 30.0f;
const quint32 ParticleEffectEntityItem::DEFAULT_MAX_PARTICLES = 1000; const quint32 ParticleEffectEntityItem::DEFAULT_MAX_PARTICLES = 1000;
const float ParticleEffectEntityItem::DEFAULT_LIFESPAN = 3.0f; const float ParticleEffectEntityItem::DEFAULT_LIFESPAN = 3.0f;
const float ParticleEffectEntityItem::DEFAULT_EMIT_RATE = 15.0f; const float ParticleEffectEntityItem::DEFAULT_EMIT_RATE = 15.0f;
const glm::vec3 ParticleEffectEntityItem::DEFAULT_EMIT_DIRECTION(0.0f, 1.0f, 0.0f); const glm::vec3 ParticleEffectEntityItem::DEFAULT_EMIT_VELOCITY(0.0f, 5.0f, 0.0f);
const float ParticleEffectEntityItem::DEFAULT_EMIT_STRENGTH = 25.0f; const glm::vec3 ParticleEffectEntityItem::DEFAULT_VELOCITY_SPREAD(3.0f, 0.0f, 3.0f);
const float ParticleEffectEntityItem::DEFAULT_LOCAL_GRAVITY = -9.8f; 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 float ParticleEffectEntityItem::DEFAULT_PARTICLE_RADIUS = 0.025f; const float ParticleEffectEntityItem::DEFAULT_PARTICLE_RADIUS = 0.025f;
const QString ParticleEffectEntityItem::DEFAULT_TEXTURES = ""; const QString ParticleEffectEntityItem::DEFAULT_TEXTURES = "";
@ -67,9 +67,10 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte
_maxParticles(DEFAULT_MAX_PARTICLES), _maxParticles(DEFAULT_MAX_PARTICLES),
_lifespan(DEFAULT_LIFESPAN), _lifespan(DEFAULT_LIFESPAN),
_emitRate(DEFAULT_EMIT_RATE), _emitRate(DEFAULT_EMIT_RATE),
_emitDirection(DEFAULT_EMIT_DIRECTION), _emitVelocity(DEFAULT_EMIT_VELOCITY),
_emitStrength(DEFAULT_EMIT_STRENGTH), _velocitySpread(DEFAULT_VELOCITY_SPREAD),
_localGravity(DEFAULT_LOCAL_GRAVITY), _emitAcceleration(DEFAULT_EMIT_ACCELERATION),
_accelerationSpread(DEFAULT_ACCELERATION_SPREAD),
_particleRadius(DEFAULT_PARTICLE_RADIUS), _particleRadius(DEFAULT_PARTICLE_RADIUS),
_lastAnimated(usecTimestampNow()), _lastAnimated(usecTimestampNow()),
_animationLoop(), _animationLoop(),
@ -80,6 +81,7 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte
_particleLifetimes(DEFAULT_MAX_PARTICLES, 0.0f), _particleLifetimes(DEFAULT_MAX_PARTICLES, 0.0f),
_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)),
_timeUntilNextEmit(0.0f), _timeUntilNextEmit(0.0f),
_particleHeadIndex(0), _particleHeadIndex(0),
_particleTailIndex(0), _particleTailIndex(0),
@ -94,75 +96,59 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte
ParticleEffectEntityItem::~ParticleEffectEntityItem() { ParticleEffectEntityItem::~ParticleEffectEntityItem() {
} }
void ParticleEffectEntityItem::setDimensions(const glm::vec3& value) {
computeAndUpdateDimensions();
}
void ParticleEffectEntityItem::setLifespan(float lifespan) { void ParticleEffectEntityItem::setLifespan(float lifespan) {
_lifespan = lifespan; _lifespan = lifespan;
}
void ParticleEffectEntityItem::setEmitVelocity(const glm::vec3& emitVelocity) {
_emitVelocity = emitVelocity;
computeAndUpdateDimensions(); computeAndUpdateDimensions();
} }
void ParticleEffectEntityItem::setEmitDirection(glm::vec3 emitDirection) { void ParticleEffectEntityItem::setVelocitySpread(const glm::vec3& velocitySpread) {
_emitDirection = glm::normalize(emitDirection); _velocitySpread = velocitySpread;
computeAndUpdateDimensions(); computeAndUpdateDimensions();
} }
void ParticleEffectEntityItem::setEmitStrength(float emitStrength) {
_emitStrength = emitStrength; void ParticleEffectEntityItem::setEmitAcceleration(const glm::vec3& emitAcceleration) {
_emitAcceleration = emitAcceleration;
computeAndUpdateDimensions(); computeAndUpdateDimensions();
} }
void ParticleEffectEntityItem::setLocalGravity(float localGravity) { void ParticleEffectEntityItem::setAccelerationSpread(const glm::vec3& accelerationSpread){
_localGravity = localGravity; _accelerationSpread = accelerationSpread;
computeAndUpdateDimensions(); computeAndUpdateDimensions();
} }
void ParticleEffectEntityItem::setParticleRadius(float particleRadius) { void ParticleEffectEntityItem::setParticleRadius(float particleRadius) {
_particleRadius = particleRadius; _particleRadius = particleRadius;
computeAndUpdateDimensions();
} }
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 t = _lifespan * 1.1f; // add 10% extra time, to account for incremental timer accumulation error.
const float MAX_RANDOM_FACTOR = (0.5f * 0.25f); float maxVelocityX = fabsf(_velocity.x) + _velocitySpread.x;
const float maxOffset = (MAX_RANDOM_FACTOR * _emitStrength) + _particleRadius; float maxAccelerationX = fabsf(_acceleration.x) + _accelerationSpread.x;
float maxXDistance = (maxVelocityX * time) + (0.5 * maxAccelerationX * time * time);
// bounds for x and z is easy to compute because there is no at^2 term.
float xMax = (_emitDirection.x * _emitStrength + maxOffset) * t; float maxVelocityY = fabs(_velocity.y) + _velocitySpread.y;
float xMin = (_emitDirection.x * _emitStrength - maxOffset) * t; float maxAccelerationY = fabsf(_acceleration.y) + _accelerationSpread.y;
float maxYDistance = (maxVelocityY * time) + (0.5 * maxAccelerationY * time * time);
float zMax = (_emitDirection.z * _emitStrength + maxOffset) * t;
float zMin = (_emitDirection.z * _emitStrength - maxOffset) * t; float maxVelocityZ = fabsf(_velocity.z) + _velocitySpread.z;
float maxAccelerationZ = fabsf(_acceleration.z) + _accelerationSpread.z;
// yEnd is where the particle will end. float maxZDistance = (maxVelocityZ * time) + (0.5 * maxAccelerationZ * time * time);
float a = _localGravity;
float atSquared = a * t * t; float maxDistance = std::max(maxXDistance, std::max(maxYDistance, maxZDistance));
float v = _emitDirection.y * _emitStrength + maxOffset;
float vt = v * t; //times 2 because dimensions are diameters not radii
float yEnd = 0.5f * atSquared + vt; glm::vec3 dims(2.0 * maxDistance);
// yApex is where the particle is at it's apex.
float yApexT = (-v / a);
float yApex = 0.0f;
// only set apex if it's within the lifespan of the particle.
if (yApexT >= 0.0f && yApexT <= t) {
yApex = -(v * v) / (2.0f * a);
}
float yMax = std::max(yApex, yEnd);
float yMin = std::min(yApex, yEnd);
// times 2 because dimensions are diameters not radii.
glm::vec3 dims(2.0f * std::max(fabsf(xMin), fabsf(xMax)),
2.0f * std::max(fabsf(yMin), fabsf(yMax)),
2.0f * std::max(fabsf(zMin), fabsf(zMax)));
EntityItem::setDimensions(dims); EntityItem::setDimensions(dims);
} }
EntityItemProperties ParticleEffectEntityItem::getProperties() const { EntityItemProperties ParticleEffectEntityItem::getProperties() const {
EntityItemProperties properties = EntityItem::getProperties(); // get the properties from our base class EntityItemProperties properties = EntityItem::getProperties(); // get the properties from our base class
@ -176,9 +162,9 @@ EntityItemProperties ParticleEffectEntityItem::getProperties() const {
COPY_ENTITY_PROPERTY_TO_PROPERTIES(maxParticles, getMaxParticles); COPY_ENTITY_PROPERTY_TO_PROPERTIES(maxParticles, getMaxParticles);
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(emitDirection, getEmitDirection); COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitVelocity, getEmitVelocity);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(emitStrength, getEmitStrength);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(localGravity, getLocalGravity); 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(textures, getTextures); COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures);
@ -198,11 +184,12 @@ bool ParticleEffectEntityItem::setProperties(const EntityItemProperties& propert
SET_ENTITY_PROPERTY_FROM_PROPERTIES(maxParticles, setMaxParticles); SET_ENTITY_PROPERTY_FROM_PROPERTIES(maxParticles, setMaxParticles);
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(emitDirection, setEmitDirection); SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitVelocity, setEmitVelocity);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitStrength, setEmitStrength); SET_ENTITY_PROPERTY_FROM_PROPERTIES(emitAcceleration, setEmitAcceleration);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(localGravity, setLocalGravity); 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(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;
@ -247,17 +234,28 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch
if (propertyFlags.getHasProperty(PROP_ANIMATION_FRAME_INDEX)) { if (propertyFlags.getHasProperty(PROP_ANIMATION_FRAME_INDEX)) {
setAnimationFrameIndex(animationFrameIndex); setAnimationFrameIndex(animationFrameIndex);
} }
READ_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, QString, setAnimationSettings); READ_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, QString, setAnimationSettings);
READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, updateShapeType); READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, updateShapeType);
READ_ENTITY_PROPERTY(PROP_MAX_PARTICLES, quint32, setMaxParticles); READ_ENTITY_PROPERTY(PROP_MAX_PARTICLES, quint32, setMaxParticles);
READ_ENTITY_PROPERTY(PROP_LIFESPAN, float, setLifespan); READ_ENTITY_PROPERTY(PROP_LIFESPAN, float, setLifespan);
READ_ENTITY_PROPERTY(PROP_EMIT_RATE, float, setEmitRate); READ_ENTITY_PROPERTY(PROP_EMIT_RATE, float, setEmitRate);
READ_ENTITY_PROPERTY(PROP_EMIT_DIRECTION, glm::vec3, setEmitDirection); READ_ENTITY_PROPERTY(PROP_EMIT_VELOCITY, glm::vec3, setEmitVelocity);
READ_ENTITY_PROPERTY(PROP_EMIT_STRENGTH, float, setEmitStrength);
READ_ENTITY_PROPERTY(PROP_LOCAL_GRAVITY, float, setLocalGravity); if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLE_MODIFICATIONS) {
READ_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float, setParticleRadius); READ_ENTITY_PROPERTY(PROP_EMIT_ACCELERATION, glm::vec3, setEmitAcceleration);
READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures); READ_ENTITY_PROPERTY(PROP_ACCELERATION_SPREAD, glm::vec3, setAccelerationSpread);
READ_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float, setParticleRadius);
READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures);
READ_ENTITY_PROPERTY(PROP_VELOCITY_SPREAD, glm::vec3, setVelocitySpread);
} else {
// EMIT_STRENGTH FAKEOUT
READ_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float, setParticleRadius);
// LOCAL_GRAVITY FAKEOUT
READ_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float, setParticleRadius);
// ACTUALLY PARTICLE RADIUS
READ_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float, setParticleRadius);
READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures);
}
return bytesRead; return bytesRead;
} }
@ -276,11 +274,12 @@ EntityPropertyFlags ParticleEffectEntityItem::getEntityProperties(EncodeBitstrea
requestedProperties += PROP_MAX_PARTICLES; requestedProperties += PROP_MAX_PARTICLES;
requestedProperties += PROP_LIFESPAN; requestedProperties += PROP_LIFESPAN;
requestedProperties += PROP_EMIT_RATE; requestedProperties += PROP_EMIT_RATE;
requestedProperties += PROP_EMIT_DIRECTION; requestedProperties += PROP_EMIT_VELOCITY;
requestedProperties += PROP_EMIT_STRENGTH; requestedProperties += PROP_EMIT_ACCELERATION;
requestedProperties += PROP_LOCAL_GRAVITY; requestedProperties += PROP_ACCELERATION_SPREAD;
requestedProperties += PROP_PARTICLE_RADIUS; requestedProperties += PROP_PARTICLE_RADIUS;
requestedProperties += PROP_TEXTURES; requestedProperties += PROP_TEXTURES;
requestedProperties += PROP_VELOCITY_SPREAD;
return requestedProperties; return requestedProperties;
} }
@ -303,11 +302,12 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData,
APPEND_ENTITY_PROPERTY(PROP_MAX_PARTICLES, getMaxParticles()); APPEND_ENTITY_PROPERTY(PROP_MAX_PARTICLES, getMaxParticles());
APPEND_ENTITY_PROPERTY(PROP_LIFESPAN, getLifespan()); APPEND_ENTITY_PROPERTY(PROP_LIFESPAN, getLifespan());
APPEND_ENTITY_PROPERTY(PROP_EMIT_RATE, getEmitRate()); APPEND_ENTITY_PROPERTY(PROP_EMIT_RATE, getEmitRate());
APPEND_ENTITY_PROPERTY(PROP_EMIT_DIRECTION, getEmitDirection()); APPEND_ENTITY_PROPERTY(PROP_EMIT_VELOCITY, getEmitVelocity());
APPEND_ENTITY_PROPERTY(PROP_EMIT_STRENGTH, getEmitStrength()); APPEND_ENTITY_PROPERTY(PROP_EMIT_ACCELERATION, getEmitAcceleration());
APPEND_ENTITY_PROPERTY(PROP_LOCAL_GRAVITY, getLocalGravity()); APPEND_ENTITY_PROPERTY(PROP_ACCELERATION_SPREAD, getAccelerationSpread());
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());
} }
bool ParticleEffectEntityItem::isAnimatingSomething() const { bool ParticleEffectEntityItem::isAnimatingSomething() const {
@ -487,8 +487,9 @@ void ParticleEffectEntityItem::extendBounds(const glm::vec3& point) {
} }
void ParticleEffectEntityItem::integrateParticle(quint32 index, float deltaTime) { void ParticleEffectEntityItem::integrateParticle(quint32 index, float deltaTime) {
glm::vec3 atSquared(0.0f, 0.5f * _localGravity * deltaTime * deltaTime, 0.0f); glm::vec3 accel = _particleAccelerations[index];
glm::vec3 at(0.0f, _localGravity * deltaTime, 0.0f); glm::vec3 atSquared = (0.5f * deltaTime * deltaTime) * accel;
glm::vec3 at = accel * deltaTime;
_particlePositions[index] += _particleVelocities[index] * deltaTime + atSquared; _particlePositions[index] += _particleVelocities[index] * deltaTime + atSquared;
_particleVelocities[index] += at; _particleVelocities[index] += at;
} }
@ -526,15 +527,22 @@ void ParticleEffectEntityItem::stepSimulation(float deltaTime) {
quint32 i = _particleTailIndex; quint32 i = _particleTailIndex;
_particleLifetimes[i] = _lifespan; _particleLifetimes[i] = _lifespan;
// jitter the _emitDirection by a random offset
glm::vec3 randOffset; glm::vec3 spreadOffset;
randOffset.x = (randFloat() - 0.5f) * 0.25f * _emitStrength; spreadOffset.x = -_velocitySpread.x + randFloat() * (_velocitySpread.x * 2.0f);
randOffset.y = (randFloat() - 0.5f) * 0.25f * _emitStrength; spreadOffset.y = -_velocitySpread.y + randFloat() * (_velocitySpread.y * 2.0f);
randOffset.z = (randFloat() - 0.5f) * 0.25f * _emitStrength; spreadOffset.z = -_velocitySpread.z + randFloat() * (_velocitySpread.z * 2.0f);
// set initial conditions // set initial conditions
_particlePositions[i] = glm::vec3(0.0f, 0.0f, 0.0f); _particlePositions[i] = getPosition();
_particleVelocities[i] = _emitDirection * _emitStrength + randOffset; _particleVelocities[i] = _emitVelocity + spreadOffset;
spreadOffset.x = -_accelerationSpread.x + randFloat() * (_accelerationSpread.x * 2.0f);
spreadOffset.y = -_accelerationSpread.y + randFloat() * (_accelerationSpread.y * 2.0f);
spreadOffset.z = -_accelerationSpread.z + randFloat() * (_accelerationSpread.z * 2.0f);
_particleAccelerations[i] = _emitAcceleration + spreadOffset;
integrateParticle(i, timeLeftInFrame); integrateParticle(i, timeLeftInFrame);
extendBounds(_particlePositions[i]); extendBounds(_particlePositions[i]);

View file

@ -86,8 +86,6 @@ public:
void setAnimationLastFrame(float lastFrame) { _animationLoop.setLastFrame(lastFrame); } void setAnimationLastFrame(float lastFrame) { _animationLoop.setLastFrame(lastFrame); }
float getAnimationLastFrame() const { return _animationLoop.getLastFrame(); } float getAnimationLastFrame() const { return _animationLoop.getLastFrame(); }
virtual void setDimensions(const glm::vec3& value) override;
static const quint32 DEFAULT_MAX_PARTICLES; static const quint32 DEFAULT_MAX_PARTICLES;
void setMaxParticles(quint32 maxParticles); void setMaxParticles(quint32 maxParticles);
quint32 getMaxParticles() const { return _maxParticles; } quint32 getMaxParticles() const { return _maxParticles; }
@ -100,24 +98,31 @@ public:
void setEmitRate(float emitRate) { _emitRate = emitRate; } void setEmitRate(float emitRate) { _emitRate = emitRate; }
float getEmitRate() const { return _emitRate; } float getEmitRate() const { return _emitRate; }
static const glm::vec3 DEFAULT_EMIT_DIRECTION; static const glm::vec3 DEFAULT_EMIT_VELOCITY;
void setEmitDirection(glm::vec3 emitDirection); void setEmitVelocity(const glm::vec3& emitVelocity);
const glm::vec3& getEmitDirection() const { return _emitDirection; } const glm::vec3& getEmitVelocity() const { return _emitVelocity; }
static const glm::vec3 DEFAULT_VELOCITY_SPREAD;
void setVelocitySpread(const glm::vec3& velocitySpread);
const glm::vec3& getVelocitySpread() const { return _velocitySpread; }
static const float DEFAULT_EMIT_STRENGTH;
void setEmitStrength(float emitStrength);
float getEmitStrength() const { return _emitStrength; }
static const float DEFAULT_LOCAL_GRAVITY; static const glm::vec3 DEFAULT_EMIT_ACCELERATION;
void setLocalGravity(float localGravity); void setEmitAcceleration(const glm::vec3& emitAcceleration);
float getLocalGravity() const { return _localGravity; } const glm::vec3& getEmitAcceleration() const { return _emitAcceleration; }
static const glm::vec3 DEFAULT_ACCELERATION_SPREAD;
void setAccelerationSpread(const glm::vec3& accelerationSpread);
const glm::vec3& getAccelerationSpread() const { return _accelerationSpread; }
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; }
void computeAndUpdateDimensions(); void computeAndUpdateDimensions();
bool getAnimationIsPlaying() const { return _animationLoop.isRunning(); } bool getAnimationIsPlaying() const { return _animationLoop.isRunning(); }
float getAnimationFrameIndex() const { return _animationLoop.getFrameIndex(); } float getAnimationFrameIndex() const { return _animationLoop.getFrameIndex(); }
float getAnimationFPS() const { return _animationLoop.getFPS(); } float getAnimationFPS() const { return _animationLoop.getFPS(); }
@ -145,9 +150,10 @@ protected:
quint32 _maxParticles; quint32 _maxParticles;
float _lifespan; float _lifespan;
float _emitRate; float _emitRate;
glm::vec3 _emitDirection; glm::vec3 _emitVelocity;
float _emitStrength; glm::vec3 _velocitySpread;
float _localGravity; glm::vec3 _emitAcceleration;
glm::vec3 _accelerationSpread;
float _particleRadius; float _particleRadius;
quint64 _lastAnimated; quint64 _lastAnimated;
AnimationLoop _animationLoop; AnimationLoop _animationLoop;
@ -160,6 +166,7 @@ protected:
QVector<float> _particleLifetimes; QVector<float> _particleLifetimes;
QVector<glm::vec3> _particlePositions; QVector<glm::vec3> _particlePositions;
QVector<glm::vec3> _particleVelocities; QVector<glm::vec3> _particleVelocities;
QVector<glm::vec3> _particleAccelerations;
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_OCTREE_CENTERED_ORIGIN; return VERSION_ENTITIES_PARTICLE_MODIFICATIONS;
case AvatarData: case AvatarData:
return 12; return 12;
default: default:

View file

@ -143,5 +143,6 @@ const PacketVersion VERSION_ENTITIES_NEW_PROTOCOL_LAYER = 35;
const PacketVersion VERSION_POLYVOX_TEXTURES = 36; 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;
#endif // hifi_PacketHeaders_h #endif // hifi_PacketHeaders_h