Merge pull request #6278 from ericrius1/particleSorting

Added additiveBlending property to particle effect entity
This commit is contained in:
James B. Pollack 2015-11-09 11:32:44 -08:00
commit 1812444614
11 changed files with 107 additions and 19 deletions

View file

@ -23,6 +23,7 @@
#include "untextured_particle_frag.h" #include "untextured_particle_frag.h"
#include "textured_particle_vert.h" #include "textured_particle_vert.h"
#include "textured_particle_frag.h" #include "textured_particle_frag.h"
#include "textured_particle_alpha_discard_frag.h"
class ParticlePayload { class ParticlePayload {
public: public:
@ -114,8 +115,7 @@ namespace render {
} }
} }
gpu::PipelinePointer RenderableParticleEffectEntityItem::_texturedPipeline;
gpu::PipelinePointer RenderableParticleEffectEntityItem::_untexturedPipeline;
EntityItemPointer RenderableParticleEffectEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { EntityItemPointer RenderableParticleEffectEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
return std::make_shared<RenderableParticleEffectEntityItem>(entityID, properties); return std::make_shared<RenderableParticleEffectEntityItem>(entityID, properties);
@ -203,19 +203,26 @@ void RenderableParticleEffectEntityItem::updateRenderItem() {
// 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();
qSort(particleDetails.begin(), particleDetails.end(), zSort); // No need to sort if we're doing additive blending
if (_additiveBlending != true) {
::zSortAxis = frustum->getDirection();
qSort(particleDetails.begin(), particleDetails.end(), zSort);
}
// allocate vertices // allocate vertices
_vertices.clear(); _vertices.clear();
// build vertices from particle positions and radiuses // build vertices from particle positions and radiuses
glm::vec3 frustumPosition = frustum->getPosition(); glm::vec3 frustumPosition = frustum->getPosition();
glm::vec3 dir = frustum->getDirection();
for (auto&& particle : particleDetails) { for (auto&& particle : particleDetails) {
glm::vec3 particleDirection = particle.position - frustumPosition; glm::vec3 right = glm::normalize(glm::cross(glm::vec3(0.0f, 1.0f, 0.0f), dir));
glm::vec3 right = glm::normalize(glm::cross(glm::vec3(0.0f, 1.0f, 0.0f), particleDirection)); glm::vec3 up = glm::normalize(glm::cross(right, dir));
glm::vec3 up = glm::normalize(glm::cross(right, particleDirection));
glm::vec3 upOffset = up * particle.radius; glm::vec3 upOffset = up * particle.radius;
glm::vec3 rightOffset = right * particle.radius; glm::vec3 rightOffset = right * particle.radius;
@ -309,12 +316,21 @@ void RenderableParticleEffectEntityItem::updateRenderItem() {
} }
void RenderableParticleEffectEntityItem::createPipelines() { void RenderableParticleEffectEntityItem::createPipelines() {
bool writeToDepthBuffer = false;
gpu::State::BlendArg destinationColorBlendArg;
if (_additiveBlending) {
destinationColorBlendArg = gpu::State::ONE;
}
else {
destinationColorBlendArg = gpu::State::INV_SRC_ALPHA;
writeToDepthBuffer = true;
}
if (!_untexturedPipeline) { if (!_untexturedPipeline) {
auto state = std::make_shared<gpu::State>(); auto state = std::make_shared<gpu::State>();
state->setCullMode(gpu::State::CULL_BACK); state->setCullMode(gpu::State::CULL_BACK);
state->setDepthTest(true, true, gpu::LESS_EQUAL); state->setDepthTest(true, writeToDepthBuffer, 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::ONE, gpu::State::FACTOR_ALPHA, destinationColorBlendArg, 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)));
@ -324,13 +340,24 @@ void RenderableParticleEffectEntityItem::createPipelines() {
if (!_texturedPipeline) { if (!_texturedPipeline) {
auto state = std::make_shared<gpu::State>(); auto state = std::make_shared<gpu::State>();
state->setCullMode(gpu::State::CULL_BACK); state->setCullMode(gpu::State::CULL_BACK);
state->setDepthTest(true, true, gpu::LESS_EQUAL);
bool writeToDepthBuffer = !_additiveBlending;
state->setDepthTest(true, writeToDepthBuffer, 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, destinationColorBlendArg, 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(textured_particle_vert))); auto vertShader = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(textured_particle_vert)));
auto fragShader = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(textured_particle_frag))); gpu::ShaderPointer fragShader;
if (_additiveBlending) {
fragShader = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(textured_particle_frag)));
}
else {
//If we are sorting and have no additive blending, we want to discard pixels with low alpha to avoid inter-particle entity artifacts
fragShader = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(textured_particle_alpha_discard_frag)));
}
auto program = gpu::ShaderPointer(gpu::Shader::createProgram(vertShader, fragShader)); auto program = gpu::ShaderPointer(gpu::Shader::createProgram(vertShader, fragShader));
_texturedPipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state)); _texturedPipeline = gpu::PipelinePointer(gpu::Pipeline::create(program, state));
} }
} }

View file

@ -38,11 +38,11 @@ protected:
uint32_t rgba; uint32_t rgba;
}; };
static void createPipelines(); void createPipelines();
std::vector<Vertex> _vertices; std::vector<Vertex> _vertices;
static gpu::PipelinePointer _untexturedPipeline; gpu::PipelinePointer _untexturedPipeline;
static gpu::PipelinePointer _texturedPipeline; gpu::PipelinePointer _texturedPipeline;
render::ScenePointer _scene; render::ScenePointer _scene;
NetworkTexturePointer _texture; NetworkTexturePointer _texture;

View file

@ -0,0 +1,25 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
// fragment shader
//
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
uniform sampler2D colorMap;
in vec4 _color;
in vec2 _texCoord0;
out vec4 outFragColor;
void main(void) {
vec4 color = texture(colorMap, _texCoord0);
if (color.a < 0.1) {
discard;
}
outFragColor = color * _color;
}

View file

@ -195,6 +195,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
CHECK_PROPERTY_CHANGE(PROP_ALPHA_SPREAD, alphaSpread); CHECK_PROPERTY_CHANGE(PROP_ALPHA_SPREAD, alphaSpread);
CHECK_PROPERTY_CHANGE(PROP_ALPHA_START, alphaStart); CHECK_PROPERTY_CHANGE(PROP_ALPHA_START, alphaStart);
CHECK_PROPERTY_CHANGE(PROP_ALPHA_FINISH, alphaFinish); CHECK_PROPERTY_CHANGE(PROP_ALPHA_FINISH, alphaFinish);
CHECK_PROPERTY_CHANGE(PROP_ADDITIVE_BLENDING, additiveBlending);
CHECK_PROPERTY_CHANGE(PROP_MODEL_URL, modelURL); CHECK_PROPERTY_CHANGE(PROP_MODEL_URL, modelURL);
CHECK_PROPERTY_CHANGE(PROP_COMPOUND_SHAPE_URL, compoundShapeURL); CHECK_PROPERTY_CHANGE(PROP_COMPOUND_SHAPE_URL, compoundShapeURL);
CHECK_PROPERTY_CHANGE(PROP_VISIBLE, visible); CHECK_PROPERTY_CHANGE(PROP_VISIBLE, visible);
@ -351,6 +352,8 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA_SPREAD, alphaSpread); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA_SPREAD, alphaSpread);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA_START, alphaStart); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA_START, alphaStart);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA_FINISH, alphaFinish); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA_FINISH, alphaFinish);
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ADDITIVE_BLENDING, additiveBlending);
} }
// Models only // Models only
@ -502,6 +505,7 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
COPY_PROPERTY_FROM_QSCRIPTVALUE(alphaSpread, float, setAlphaSpread); COPY_PROPERTY_FROM_QSCRIPTVALUE(alphaSpread, float, setAlphaSpread);
COPY_PROPERTY_FROM_QSCRIPTVALUE(alphaStart, float, setAlphaStart); COPY_PROPERTY_FROM_QSCRIPTVALUE(alphaStart, float, setAlphaStart);
COPY_PROPERTY_FROM_QSCRIPTVALUE(alphaFinish, float, setAlphaFinish); COPY_PROPERTY_FROM_QSCRIPTVALUE(alphaFinish, float, setAlphaFinish);
COPY_PROPERTY_FROM_QSCRIPTVALUE(additiveBlending, bool, setAdditiveBlending);
COPY_PROPERTY_FROM_QSCRIPTVALUE(modelURL, QString, setModelURL); COPY_PROPERTY_FROM_QSCRIPTVALUE(modelURL, QString, setModelURL);
COPY_PROPERTY_FROM_QSCRIPTVALUE(compoundShapeURL, QString, setCompoundShapeURL); COPY_PROPERTY_FROM_QSCRIPTVALUE(compoundShapeURL, QString, setCompoundShapeURL);
COPY_PROPERTY_FROM_QSCRIPTVALUE(glowLevel, float, setGlowLevel); COPY_PROPERTY_FROM_QSCRIPTVALUE(glowLevel, float, setGlowLevel);
@ -650,6 +654,7 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue
ADD_PROPERTY_TO_MAP(PROP_ALPHA_SPREAD, AlphaSpread, alphaSpread, float); ADD_PROPERTY_TO_MAP(PROP_ALPHA_SPREAD, AlphaSpread, alphaSpread, float);
ADD_PROPERTY_TO_MAP(PROP_ALPHA_START, AlphaStart, alphaStart, float); ADD_PROPERTY_TO_MAP(PROP_ALPHA_START, AlphaStart, alphaStart, float);
ADD_PROPERTY_TO_MAP(PROP_ALPHA_FINISH, AlphaFinish, alphaFinish, float); ADD_PROPERTY_TO_MAP(PROP_ALPHA_FINISH, AlphaFinish, alphaFinish, float);
ADD_PROPERTY_TO_MAP(PROP_ADDITIVE_BLENDING, AdditiveBlending, additiveBlending, bool);
ADD_PROPERTY_TO_MAP(PROP_MODEL_URL, ModelURL, modelURL, QString); ADD_PROPERTY_TO_MAP(PROP_MODEL_URL, ModelURL, modelURL, QString);
ADD_PROPERTY_TO_MAP(PROP_COMPOUND_SHAPE_URL, CompoundShapeURL, compoundShapeURL, QString); ADD_PROPERTY_TO_MAP(PROP_COMPOUND_SHAPE_URL, CompoundShapeURL, compoundShapeURL, QString);
ADD_PROPERTY_TO_MAP(PROP_REGISTRATION_POINT, RegistrationPoint, registrationPoint, glm::vec3); ADD_PROPERTY_TO_MAP(PROP_REGISTRATION_POINT, RegistrationPoint, registrationPoint, glm::vec3);
@ -959,6 +964,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
APPEND_ENTITY_PROPERTY(PROP_ALPHA_SPREAD, properties.getAlphaSpread()); APPEND_ENTITY_PROPERTY(PROP_ALPHA_SPREAD, properties.getAlphaSpread());
APPEND_ENTITY_PROPERTY(PROP_ALPHA_START, properties.getAlphaStart()); APPEND_ENTITY_PROPERTY(PROP_ALPHA_START, properties.getAlphaStart());
APPEND_ENTITY_PROPERTY(PROP_ALPHA_FINISH, properties.getAlphaFinish()); APPEND_ENTITY_PROPERTY(PROP_ALPHA_FINISH, properties.getAlphaFinish());
APPEND_ENTITY_PROPERTY(PROP_ADDITIVE_BLENDING, properties.getAdditiveBlending());
} }
if (properties.getType() == EntityTypes::Zone) { if (properties.getType() == EntityTypes::Zone) {
@ -1241,6 +1247,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA_SPREAD, float, setAlphaSpread); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA_SPREAD, float, setAlphaSpread);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA_START, float, setAlphaStart); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA_START, float, setAlphaStart);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA_FINISH, float, setAlphaFinish); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA_FINISH, float, setAlphaFinish);
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ADDITIVE_BLENDING, bool, setAdditiveBlending);
} }
if (properties.getType() == EntityTypes::Zone) { if (properties.getType() == EntityTypes::Zone) {
@ -1579,6 +1586,9 @@ QList<QString> EntityItemProperties::listChangedProperties() {
if (alphaFinishChanged()) { if (alphaFinishChanged()) {
out += "alphaFinish"; out += "alphaFinish";
} }
if (additiveBlendingChanged()) {
out += "additiveBlending";
}
if (modelURLChanged()) { if (modelURLChanged()) {
out += "modelURL"; out += "modelURL";
} }

View file

@ -159,6 +159,7 @@ public:
DEFINE_PROPERTY(PROP_RADIUS_SPREAD, RadiusSpread, radiusSpread, float, ParticleEffectEntityItem::DEFAULT_RADIUS_SPREAD); DEFINE_PROPERTY(PROP_RADIUS_SPREAD, RadiusSpread, radiusSpread, float, ParticleEffectEntityItem::DEFAULT_RADIUS_SPREAD);
DEFINE_PROPERTY(PROP_RADIUS_START, RadiusStart, radiusStart, float, ParticleEffectEntityItem::DEFAULT_RADIUS_START); DEFINE_PROPERTY(PROP_RADIUS_START, RadiusStart, radiusStart, float, ParticleEffectEntityItem::DEFAULT_RADIUS_START);
DEFINE_PROPERTY(PROP_RADIUS_FINISH, RadiusFinish, radiusFinish, float, ParticleEffectEntityItem::DEFAULT_RADIUS_FINISH); DEFINE_PROPERTY(PROP_RADIUS_FINISH, RadiusFinish, radiusFinish, float, ParticleEffectEntityItem::DEFAULT_RADIUS_FINISH);
DEFINE_PROPERTY(PROP_ADDITIVE_BLENDING, AdditiveBlending, additiveBlending, bool, ParticleEffectEntityItem::DEFAULT_ADDITIVE_BLENDING);
DEFINE_PROPERTY_REF(PROP_MARKETPLACE_ID, MarketplaceID, marketplaceID, QString, ENTITY_ITEM_DEFAULT_MARKETPLACE_ID); DEFINE_PROPERTY_REF(PROP_MARKETPLACE_ID, MarketplaceID, marketplaceID, QString, ENTITY_ITEM_DEFAULT_MARKETPLACE_ID);
DEFINE_PROPERTY_GROUP(KeyLight, keyLight, KeyLightPropertyGroup); DEFINE_PROPERTY_GROUP(KeyLight, keyLight, KeyLightPropertyGroup);
DEFINE_PROPERTY_REF(PROP_VOXEL_VOLUME_SIZE, VoxelVolumeSize, voxelVolumeSize, glm::vec3, PolyVoxEntityItem::DEFAULT_VOXEL_VOLUME_SIZE); DEFINE_PROPERTY_REF(PROP_VOXEL_VOLUME_SIZE, VoxelVolumeSize, voxelVolumeSize, glm::vec3, PolyVoxEntityItem::DEFAULT_VOXEL_VOLUME_SIZE);

View file

@ -149,6 +149,8 @@ enum EntityPropertyList {
PROP_ANIMATION_HOLD, PROP_ANIMATION_HOLD,
PROP_ANIMATION_START_AUTOMATICALLY, PROP_ANIMATION_START_AUTOMATICALLY,
PROP_ADDITIVE_BLENDING,
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
// ATTENTION: add new properties to end of list just ABOVE this line // ATTENTION: add new properties to end of list just ABOVE this line
PROP_AFTER_LAST_ITEM, PROP_AFTER_LAST_ITEM,

View file

@ -18,6 +18,7 @@
#include "EntityItemProperties.h" #include "EntityItemProperties.h"
#include "EntityTree.h" #include "EntityTree.h"
#include "EntityTreeElement.h" #include "EntityTreeElement.h"
#include "EntityTypes.h"
EntityTreeElement::EntityTreeElement(unsigned char* octalCode) : OctreeElement() { EntityTreeElement::EntityTreeElement(unsigned char* octalCode) : OctreeElement() {
init(octalCode); init(octalCode);
@ -591,7 +592,8 @@ bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, con
} }
} else { } else {
// if the entity type doesn't support a detailed intersection, then just return the non-AABox results // if the entity type doesn't support a detailed intersection, then just return the non-AABox results
if (localDistance < distance) { // Never intersect with particle effect entities
if (localDistance < distance && EntityTypes::getEntityTypeName(entity->getType()) != "ParticleEffect") {
distance = localDistance; distance = localDistance;
face = localFace; face = localFace;
surfaceNormal = localSurfaceNormal; surfaceNormal = localSurfaceNormal;

View file

@ -94,6 +94,7 @@ const float ParticleEffectEntityItem::DEFAULT_RADIUS_SPREAD = 0.0f;
const float ParticleEffectEntityItem::DEFAULT_RADIUS_START = DEFAULT_PARTICLE_RADIUS; const float ParticleEffectEntityItem::DEFAULT_RADIUS_START = DEFAULT_PARTICLE_RADIUS;
const float ParticleEffectEntityItem::DEFAULT_RADIUS_FINISH = DEFAULT_PARTICLE_RADIUS; const float ParticleEffectEntityItem::DEFAULT_RADIUS_FINISH = DEFAULT_PARTICLE_RADIUS;
const QString ParticleEffectEntityItem::DEFAULT_TEXTURES = ""; const QString ParticleEffectEntityItem::DEFAULT_TEXTURES = "";
const bool ParticleEffectEntityItem::DEFAULT_ADDITIVE_BLENDING = false;
EntityItemPointer ParticleEffectEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { EntityItemPointer ParticleEffectEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
@ -121,7 +122,8 @@ ParticleEffectEntityItem::ParticleEffectEntityItem(const EntityItemID& entityIte
_alphaMiddles(DEFAULT_MAX_PARTICLES, DEFAULT_ALPHA), _alphaMiddles(DEFAULT_MAX_PARTICLES, DEFAULT_ALPHA),
_alphaFinishes(DEFAULT_MAX_PARTICLES, DEFAULT_ALPHA), _alphaFinishes(DEFAULT_MAX_PARTICLES, DEFAULT_ALPHA),
_particleMaxBound(glm::vec3(1.0f, 1.0f, 1.0f)), _particleMaxBound(glm::vec3(1.0f, 1.0f, 1.0f)),
_particleMinBound(glm::vec3(-1.0f, -1.0f, -1.0f)) _particleMinBound(glm::vec3(-1.0f, -1.0f, -1.0f)) ,
_additiveBlending(DEFAULT_ADDITIVE_BLENDING)
{ {
_type = EntityTypes::ParticleEffect; _type = EntityTypes::ParticleEffect;
@ -355,6 +357,8 @@ EntityItemProperties ParticleEffectEntityItem::getProperties(EntityPropertyFlags
COPY_ENTITY_PROPERTY_TO_PROPERTIES(alphaStart, getAlphaStart); COPY_ENTITY_PROPERTY_TO_PROPERTIES(alphaStart, getAlphaStart);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(alphaFinish, getAlphaFinish); COPY_ENTITY_PROPERTY_TO_PROPERTIES(alphaFinish, getAlphaFinish);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures); COPY_ENTITY_PROPERTY_TO_PROPERTIES(textures, getTextures);
COPY_ENTITY_PROPERTY_TO_PROPERTIES(additiveBlending, getAdditiveBlending);
return properties; return properties;
} }
@ -392,6 +396,7 @@ bool ParticleEffectEntityItem::setProperties(const EntityItemProperties& propert
SET_ENTITY_PROPERTY_FROM_PROPERTIES(alphaStart, setAlphaStart); SET_ENTITY_PROPERTY_FROM_PROPERTIES(alphaStart, setAlphaStart);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(alphaFinish, setAlphaFinish); SET_ENTITY_PROPERTY_FROM_PROPERTIES(alphaFinish, setAlphaFinish);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures); SET_ENTITY_PROPERTY_FROM_PROPERTIES(textures, setTextures);
SET_ENTITY_PROPERTY_FROM_PROPERTIES(additiveBlending, setAdditiveBlending);
if (somethingChanged) { if (somethingChanged) {
bool wantDebug = false; bool wantDebug = false;
@ -483,6 +488,10 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch
READ_ENTITY_PROPERTY(PROP_AZIMUTH_FINISH, float, setAzimuthFinish); READ_ENTITY_PROPERTY(PROP_AZIMUTH_FINISH, float, setAzimuthFinish);
} }
if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLES_ADDITIVE_BLENDING) {
READ_ENTITY_PROPERTY(PROP_ADDITIVE_BLENDING, bool, setAdditiveBlending);
}
return bytesRead; return bytesRead;
} }
@ -520,6 +529,7 @@ EntityPropertyFlags ParticleEffectEntityItem::getEntityProperties(EncodeBitstrea
requestedProperties += PROP_POLAR_FINISH; requestedProperties += PROP_POLAR_FINISH;
requestedProperties += PROP_AZIMUTH_START; requestedProperties += PROP_AZIMUTH_START;
requestedProperties += PROP_AZIMUTH_FINISH; requestedProperties += PROP_AZIMUTH_FINISH;
requestedProperties += PROP_ADDITIVE_BLENDING;
return requestedProperties; return requestedProperties;
} }
@ -562,6 +572,7 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData,
APPEND_ENTITY_PROPERTY(PROP_POLAR_FINISH, getPolarFinish()); APPEND_ENTITY_PROPERTY(PROP_POLAR_FINISH, getPolarFinish());
APPEND_ENTITY_PROPERTY(PROP_AZIMUTH_START, getAzimuthStart()); APPEND_ENTITY_PROPERTY(PROP_AZIMUTH_START, getAzimuthStart());
APPEND_ENTITY_PROPERTY(PROP_AZIMUTH_FINISH, getAzimuthFinish()); APPEND_ENTITY_PROPERTY(PROP_AZIMUTH_FINISH, getAzimuthFinish());
APPEND_ENTITY_PROPERTY(PROP_ADDITIVE_BLENDING, getAdditiveBlending());
} }
bool ParticleEffectEntityItem::isEmittingParticles() const { bool ParticleEffectEntityItem::isEmittingParticles() const {

View file

@ -209,6 +209,14 @@ public:
} }
} }
static const bool DEFAULT_ADDITIVE_BLENDING;
bool getAdditiveBlending() const { return _additiveBlending; }
void setAdditiveBlending(bool additiveBlending) {
_additiveBlending = additiveBlending;
}
virtual bool supportsDetailedRayIntersection() const { return false; }
protected: protected:
bool isAnimatingSomething() const; bool isAnimatingSomething() const;
@ -219,7 +227,6 @@ protected:
void extendBounds(const glm::vec3& point); void extendBounds(const glm::vec3& point);
void integrateParticle(quint32 index, float deltaTime); void integrateParticle(quint32 index, float deltaTime);
quint32 getLivingParticleCount() const; quint32 getLivingParticleCount() const;
// the properties of this entity // the properties of this entity
rgbColor _color; rgbColor _color;
xColor _colorStart = DEFAULT_COLOR; xColor _colorStart = DEFAULT_COLOR;
@ -284,6 +291,8 @@ protected:
// bounding volume // bounding volume
glm::vec3 _particleMaxBound; glm::vec3 _particleMaxBound;
glm::vec3 _particleMinBound; glm::vec3 _particleMinBound;
bool _additiveBlending;
}; };
#endif // hifi_ParticleEffectEntityItem_h #endif // hifi_ParticleEffectEntityItem_h

View file

@ -38,7 +38,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
case PacketType::EntityAdd: case PacketType::EntityAdd:
case PacketType::EntityEdit: case PacketType::EntityEdit:
case PacketType::EntityData: case PacketType::EntityData:
return VERSION_ENTITIES_KEYLIGHT_PROPERTIES_GROUP_BIS; return VERSION_ENTITIES_PARTICLES_ADDITIVE_BLENDING;
case PacketType::AvatarData: case PacketType::AvatarData:
case PacketType::BulkAvatarData: case PacketType::BulkAvatarData:
default: default:

View file

@ -145,5 +145,6 @@ const PacketVersion VERSION_ENTITIES_PROTOCOL_CHANNELS = 45;
const PacketVersion VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP = 46; const PacketVersion VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP = 46;
const PacketVersion VERSION_ENTITIES_KEYLIGHT_PROPERTIES_GROUP = 47; const PacketVersion VERSION_ENTITIES_KEYLIGHT_PROPERTIES_GROUP = 47;
const PacketVersion VERSION_ENTITIES_KEYLIGHT_PROPERTIES_GROUP_BIS = 48; const PacketVersion VERSION_ENTITIES_KEYLIGHT_PROPERTIES_GROUP_BIS = 48;
const PacketVersion VERSION_ENTITIES_PARTICLES_ADDITIVE_BLENDING = 49;
#endif // hifi_PacketHeaders_h #endif // hifi_PacketHeaders_h