mirror of
https://github.com/overte-org/overte.git
synced 2025-04-11 01:42:11 +02:00
working on adding particle shape types
This commit is contained in:
parent
840f3a3a2e
commit
ea50133146
7 changed files with 138 additions and 55 deletions
|
@ -307,10 +307,6 @@ void RenderableModelEntityItem::setShapeType(ShapeType type) {
|
|||
}
|
||||
|
||||
void RenderableModelEntityItem::setCompoundShapeURL(const QString& url) {
|
||||
// because the caching system only allows one Geometry per url, and because this url might also be used
|
||||
// as a visual model, we need to change this url in some way. We add a "collision-hull" query-arg so it
|
||||
// will end up in a different hash-key in ResourceCache. TODO: It would be better to use the same URL and
|
||||
// parse it twice.
|
||||
auto currentCompoundShapeURL = getCompoundShapeURL();
|
||||
ModelEntityItem::setCompoundShapeURL(url);
|
||||
if (getCompoundShapeURL() != currentCompoundShapeURL || !getModel()) {
|
||||
|
|
|
@ -9,13 +9,11 @@
|
|||
//
|
||||
|
||||
#include "RenderableParticleEffectEntityItem.h"
|
||||
|
||||
#include <StencilMaskPass.h>
|
||||
|
||||
#include <GeometryCache.h>
|
||||
#include <shaders/Shaders.h>
|
||||
|
||||
|
||||
using namespace render;
|
||||
using namespace render::entities;
|
||||
|
||||
|
@ -79,6 +77,14 @@ bool ParticleEffectEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedE
|
|||
return true;
|
||||
}
|
||||
|
||||
if (_shapeType != entity->getShapeType()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_compoundShapeURL != entity->getCompoundShapeURL()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -87,11 +93,17 @@ void ParticleEffectEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePoi
|
|||
if (!newParticleProperties.valid()) {
|
||||
qCWarning(entitiesrenderer) << "Bad particle properties";
|
||||
}
|
||||
|
||||
if (resultWithReadLock<bool>([&]{ return _particleProperties != newParticleProperties; })) {
|
||||
|
||||
if (resultWithReadLock<bool>([&] { return _particleProperties != newParticleProperties; })) {
|
||||
_timeUntilNextEmit = 0;
|
||||
withWriteLock([&]{
|
||||
withWriteLock([&] {
|
||||
_particleProperties = newParticleProperties;
|
||||
_shapeType = entity->getShapeType();
|
||||
QString compoundShapeURL = entity->getCompoundShapeURL();
|
||||
if (_compoundShapeURL != compoundShapeURL) {
|
||||
_compoundShapeURL = compoundShapeURL;
|
||||
fetchGeometryResource();
|
||||
}
|
||||
if (!_prevEmitterShouldTrailInitialized) {
|
||||
_prevEmitterShouldTrailInitialized = true;
|
||||
_prevEmitterShouldTrail = _particleProperties.emission.shouldTrail;
|
||||
|
@ -104,10 +116,10 @@ void ParticleEffectEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePoi
|
|||
});
|
||||
_emitting = entity->getIsEmitting();
|
||||
|
||||
bool textureEmpty = resultWithReadLock<bool>([&]{ return _particleProperties.textures.isEmpty(); });
|
||||
bool textureEmpty = resultWithReadLock<bool>([&] { return _particleProperties.textures.isEmpty(); });
|
||||
if (textureEmpty) {
|
||||
if (_networkTexture) {
|
||||
withWriteLock([&] {
|
||||
withWriteLock([&] {
|
||||
_networkTexture.reset();
|
||||
});
|
||||
}
|
||||
|
@ -116,11 +128,11 @@ void ParticleEffectEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePoi
|
|||
entity->setVisuallyReady(true);
|
||||
});
|
||||
} else {
|
||||
bool textureNeedsUpdate = resultWithReadLock<bool>([&]{
|
||||
bool textureNeedsUpdate = resultWithReadLock<bool>([&] {
|
||||
return !_networkTexture || _networkTexture->getURL() != QUrl(_particleProperties.textures);
|
||||
});
|
||||
if (textureNeedsUpdate) {
|
||||
withWriteLock([&] {
|
||||
withWriteLock([&] {
|
||||
_networkTexture = DependencyManager::get<TextureCache>()->getTexture(_particleProperties.textures);
|
||||
});
|
||||
}
|
||||
|
@ -144,7 +156,7 @@ void ParticleEffectEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePoi
|
|||
void ParticleEffectEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
|
||||
// Fill in Uniforms structure
|
||||
ParticleUniforms particleUniforms;
|
||||
withReadLock([&]{
|
||||
withReadLock([&] {
|
||||
particleUniforms.radius.start = _particleProperties.radius.range.start;
|
||||
particleUniforms.radius.middle = _particleProperties.radius.gradient.target;
|
||||
particleUniforms.radius.finish = _particleProperties.radius.range.finish;
|
||||
|
@ -183,7 +195,8 @@ Item::Bound ParticleEffectEntityRenderer::getBound() {
|
|||
|
||||
static const size_t VERTEX_PER_PARTICLE = 4;
|
||||
|
||||
ParticleEffectEntityRenderer::CpuParticle ParticleEffectEntityRenderer::createParticle(uint64_t now, const Transform& baseTransform, const particle::Properties& particleProperties) {
|
||||
ParticleEffectEntityRenderer::CpuParticle ParticleEffectEntityRenderer::createParticle(uint64_t now, const Transform& baseTransform, const particle::Properties& particleProperties,
|
||||
const ShapeType& shapeType, const GeometryResource::Pointer& geometryResource) {
|
||||
CpuParticle particle;
|
||||
|
||||
const auto& accelerationSpread = particleProperties.emission.acceleration.spread;
|
||||
|
@ -221,33 +234,53 @@ ParticleEffectEntityRenderer::CpuParticle ParticleEffectEntityRenderer::createPa
|
|||
|
||||
float azimuth;
|
||||
if (azimuthFinish >= azimuthStart) {
|
||||
azimuth = azimuthStart + (azimuthFinish - azimuthStart) * randFloat();
|
||||
azimuth = azimuthStart + (azimuthFinish - azimuthStart) * randFloat();
|
||||
} else {
|
||||
azimuth = azimuthStart + (TWO_PI + azimuthFinish - azimuthStart) * randFloat();
|
||||
}
|
||||
|
||||
if (emitDimensions == Vectors::ZERO) {
|
||||
if (emitDimensions == Vectors::ZERO || shapeType == ShapeType::SHAPE_TYPE_NONE) {
|
||||
// Point
|
||||
emitDirection = glm::quat(glm::vec3(PI_OVER_TWO - elevation, 0.0f, azimuth)) * Vectors::UNIT_Z;
|
||||
} else {
|
||||
// Ellipsoid
|
||||
float radiusScale = 1.0f;
|
||||
if (emitRadiusStart < 1.0f) {
|
||||
float randRadius =
|
||||
emitRadiusStart + randFloatInRange(0.0f, particle::MAXIMUM_EMIT_RADIUS_START - emitRadiusStart);
|
||||
radiusScale = 1.0f - std::pow(1.0f - randRadius, 3.0f);
|
||||
glm::vec3 emitPosition;
|
||||
switch (shapeType) {
|
||||
case ShapeType::SHAPE_TYPE_BOX:
|
||||
|
||||
case ShapeType::SHAPE_TYPE_CAPSULE_X:
|
||||
case ShapeType::SHAPE_TYPE_CAPSULE_Y:
|
||||
case ShapeType::SHAPE_TYPE_CAPSULE_Z:
|
||||
|
||||
case ShapeType::SHAPE_TYPE_CYLINDER_X:
|
||||
case ShapeType::SHAPE_TYPE_CYLINDER_Y:
|
||||
case ShapeType::SHAPE_TYPE_CYLINDER_Z:
|
||||
|
||||
case ShapeType::SHAPE_TYPE_CIRCLE:
|
||||
case ShapeType::SHAPE_TYPE_PLANE:
|
||||
|
||||
case ShapeType::SHAPE_TYPE_COMPOUND:
|
||||
|
||||
case ShapeType::SHAPE_TYPE_SPHERE:
|
||||
case ShapeType::SHAPE_TYPE_ELLIPSOID:
|
||||
default: {
|
||||
float radiusScale = 1.0f;
|
||||
if (emitRadiusStart < 1.0f) {
|
||||
float randRadius =
|
||||
emitRadiusStart + randFloatInRange(0.0f, particle::MAXIMUM_EMIT_RADIUS_START - emitRadiusStart);
|
||||
radiusScale = 1.0f - std::pow(1.0f - randRadius, 3.0f);
|
||||
}
|
||||
|
||||
glm::vec3 radii = radiusScale * 0.5f * emitDimensions;
|
||||
float x = radii.x * glm::cos(elevation) * glm::cos(azimuth);
|
||||
float y = radii.y * glm::cos(elevation) * glm::sin(azimuth);
|
||||
float z = radii.z * glm::sin(elevation);
|
||||
emitPosition = glm::vec3(x, y, z);
|
||||
emitDirection = glm::normalize(glm::vec3(radii.x > 0.0f ? x / (radii.x * radii.x) : 0.0f,
|
||||
radii.y > 0.0f ? y / (radii.y * radii.y) : 0.0f,
|
||||
radii.z > 0.0f ? z / (radii.z * radii.z) : 0.0f));
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 radii = radiusScale * 0.5f * emitDimensions;
|
||||
float x = radii.x * glm::cos(elevation) * glm::cos(azimuth);
|
||||
float y = radii.y * glm::cos(elevation) * glm::sin(azimuth);
|
||||
float z = radii.z * glm::sin(elevation);
|
||||
glm::vec3 emitPosition = glm::vec3(x, y, z);
|
||||
emitDirection = glm::normalize(glm::vec3(
|
||||
radii.x > 0.0f ? x / (radii.x * radii.x) : 0.0f,
|
||||
radii.y > 0.0f ? y / (radii.y * radii.y) : 0.0f,
|
||||
radii.z > 0.0f ? z / (radii.z * radii.z) : 0.0f
|
||||
));
|
||||
particle.relativePosition += emitOrientation * emitPosition;
|
||||
}
|
||||
}
|
||||
|
@ -267,20 +300,25 @@ void ParticleEffectEntityRenderer::stepSimulation() {
|
|||
const auto now = usecTimestampNow();
|
||||
const auto interval = std::min<uint64_t>(USECS_PER_SECOND / 60, now - _lastSimulated);
|
||||
_lastSimulated = now;
|
||||
|
||||
|
||||
particle::Properties particleProperties;
|
||||
withReadLock([&]{
|
||||
ShapeType shapeType;
|
||||
GeometryResource::Pointer geometryResource;
|
||||
withReadLock([&] {
|
||||
particleProperties = _particleProperties;
|
||||
shapeType = _shapeType;
|
||||
geometryResource = _geometryResource;
|
||||
});
|
||||
|
||||
const auto& modelTransform = getModelTransform();
|
||||
if (_emitting && particleProperties.emitting()) {
|
||||
if (_emitting && particleProperties.emitting() &&
|
||||
(_shapeType != ShapeType::SHAPE_TYPE_COMPOUND || (_geometryResource && _geometryResource->isLoaded()))) {
|
||||
uint64_t emitInterval = particleProperties.emitIntervalUsecs();
|
||||
if (emitInterval > 0 && interval >= _timeUntilNextEmit) {
|
||||
auto timeRemaining = interval;
|
||||
while (timeRemaining > _timeUntilNextEmit) {
|
||||
// emit particle
|
||||
_cpuParticles.push_back(createParticle(now, modelTransform, particleProperties));
|
||||
_cpuParticles.push_back(createParticle(now, modelTransform, particleProperties, shapeType, geometryResource));
|
||||
_timeUntilNextEmit = emitInterval;
|
||||
if (emitInterval < timeRemaining) {
|
||||
timeRemaining -= emitInterval;
|
||||
|
@ -297,7 +335,7 @@ void ParticleEffectEntityRenderer::stepSimulation() {
|
|||
}
|
||||
|
||||
const float deltaTime = (float)interval / (float)USECS_PER_SECOND;
|
||||
// update the particles
|
||||
// update the particles
|
||||
for (auto& particle : _cpuParticles) {
|
||||
if (_prevEmitterShouldTrail != particleProperties.emission.shouldTrail) {
|
||||
if (_prevEmitterShouldTrail) {
|
||||
|
@ -313,7 +351,7 @@ void ParticleEffectEntityRenderer::stepSimulation() {
|
|||
static GpuParticles gpuParticles;
|
||||
gpuParticles.clear();
|
||||
gpuParticles.reserve(_cpuParticles.size()); // Reserve space
|
||||
std::transform(_cpuParticles.begin(), _cpuParticles.end(), std::back_inserter(gpuParticles), [&particleProperties, &modelTransform](const CpuParticle& particle) {
|
||||
std::transform(_cpuParticles.begin(), _cpuParticles.end(), std::back_inserter(gpuParticles), [&particleProperties, &modelTransform] (const CpuParticle& particle) {
|
||||
glm::vec3 position = particle.relativePosition + (particleProperties.emission.shouldTrail ? particle.basePosition : modelTransform.getTranslation());
|
||||
return GpuParticle(position, glm::vec2(particle.lifetime, particle.seed));
|
||||
});
|
||||
|
@ -358,3 +396,12 @@ void ParticleEffectEntityRenderer::doRender(RenderArgs* args) {
|
|||
auto numParticles = _particleBuffer->getSize() / sizeof(GpuParticle);
|
||||
batch.drawInstanced((gpu::uint32)numParticles, gpu::TRIANGLE_STRIP, (gpu::uint32)VERTEX_PER_PARTICLE);
|
||||
}
|
||||
|
||||
void ParticleEffectEntityRenderer::fetchGeometryResource() {
|
||||
QUrl hullURL(_compoundShapeURL);
|
||||
if (hullURL.isEmpty()) {
|
||||
_geometryResource.reset();
|
||||
} else {
|
||||
_geometryResource = DependencyManager::get<ModelCache>()->getCollisionGeometryResource(hullURL);
|
||||
}
|
||||
}
|
|
@ -81,7 +81,8 @@ private:
|
|||
glm::vec2 spare;
|
||||
};
|
||||
|
||||
static CpuParticle createParticle(uint64_t now, const Transform& baseTransform, const particle::Properties& particleProperties);
|
||||
static CpuParticle createParticle(uint64_t now, const Transform& baseTransform, const particle::Properties& particleProperties,
|
||||
const ShapeType& shapeType, const GeometryResource::Pointer& geometryResource);
|
||||
void stepSimulation();
|
||||
|
||||
particle::Properties _particleProperties;
|
||||
|
@ -90,11 +91,16 @@ private:
|
|||
CpuParticles _cpuParticles;
|
||||
bool _emitting { false };
|
||||
uint64_t _timeUntilNextEmit { 0 };
|
||||
BufferPointer _particleBuffer{ std::make_shared<Buffer>() };
|
||||
BufferPointer _particleBuffer { std::make_shared<Buffer>() };
|
||||
BufferView _uniformBuffer;
|
||||
quint64 _lastSimulated { 0 };
|
||||
|
||||
PulsePropertyGroup _pulseProperties;
|
||||
ShapeType _shapeType;
|
||||
QString _compoundShapeURL;
|
||||
|
||||
void fetchGeometryResource();
|
||||
GeometryResource::Pointer _geometryResource;
|
||||
|
||||
NetworkTexturePointer _networkTexture;
|
||||
ScenePointer _scene;
|
||||
|
|
|
@ -1114,23 +1114,28 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
* default, particles emit along the entity's local z-axis, and <code>azimuthStart</code> and <code>azimuthFinish</code>
|
||||
* are relative to the entity's local x-axis. The default value is a rotation of -90 degrees about the local x-axis, i.e.,
|
||||
* the particles emit vertically.
|
||||
* @property {Vec3} emitDimensions=0,0,0 - The dimensions of the ellipsoid from which particles are emitted.
|
||||
* @property {number} emitRadiusStart=1 - The starting radius within the ellipsoid at which particles start being emitted;
|
||||
* range <code>0.0</code> – <code>1.0</code> for the ellipsoid center to the ellipsoid surface, respectively.
|
||||
* Particles are emitted from the portion of the ellipsoid that lies between <code>emitRadiusStart</code> and the
|
||||
* ellipsoid's surface.
|
||||
* @property {Vec3} emitDimensions=0,0,0 - The dimensions of the shape from which particles are emitted. The shape is specified with
|
||||
* <code>shapeType</code>.
|
||||
* @property {number} emitRadiusStart=1 - The starting radius within the shape at which particles start being emitted;
|
||||
* range <code>0.0</code> – <code>1.0</code> for the center to the surface, respectively.
|
||||
* Particles are emitted from the portion of the shape that lies between <code>emitRadiusStart</code> and the
|
||||
* shape's surface.
|
||||
* @property {number} polarStart=0 - The angle in radians from the entity's local z-axis at which particles start being emitted
|
||||
* within the ellipsoid; range <code>0</code> – <code>Math.PI</code>. Particles are emitted from the portion of the
|
||||
* ellipsoid that lies between <code>polarStart<code> and <code>polarFinish</code>.
|
||||
* ellipsoid that lies between <code>polarStart<code> and <code>polarFinish</code>. Only used if <code>shapeType</code> is
|
||||
* <code>ellipsoid</code>.
|
||||
* @property {number} polarFinish=0 - The angle in radians from the entity's local z-axis at which particles stop being emitted
|
||||
* within the ellipsoid; range <code>0</code> – <code>Math.PI</code>. Particles are emitted from the portion of the
|
||||
* ellipsoid that lies between <code>polarStart<code> and <code>polarFinish</code>.
|
||||
* ellipsoid that lies between <code>polarStart<code> and <code>polarFinish</code>. Only used if <code>shapeType</code> is
|
||||
* <code>ellipsoid</code>.
|
||||
* @property {number} azimuthStart=-Math.PI - The angle in radians from the entity's local x-axis about the entity's local
|
||||
* z-axis at which particles start being emitted; range <code>-Math.PI</code> – <code>Math.PI</code>. Particles are
|
||||
* emitted from the portion of the ellipsoid that lies between <code>azimuthStart<code> and <code>azimuthFinish</code>.
|
||||
* Only used if <code>shapeType</code> is <code>ellipsoid</code>.
|
||||
* @property {number} azimuthFinish=Math.PI - The angle in radians from the entity's local x-axis about the entity's local
|
||||
* z-axis at which particles stop being emitted; range <code>-Math.PI</code> – <code>Math.PI</code>. Particles are
|
||||
* emitted from the portion of the ellipsoid that lies between <code>azimuthStart<code> and <code>azimuthFinish</code>.
|
||||
* Only used if <code>shapeType</code> is <code>ellipsoid</code>.
|
||||
*
|
||||
* @property {string} textures="" - The URL of a JPG or PNG image file to display for each particle. If you want transparency,
|
||||
* use PNG format.
|
||||
|
@ -1170,7 +1175,9 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
|||
* up in the world. If true, they will point towards the entity's up vector, based on its orientation.
|
||||
* @property {Entities.Pulse} pulse - The pulse-related properties. Deprecated.
|
||||
*
|
||||
* @property {ShapeType} shapeType="none" - <em>Currently not used.</em> <em>Read-only.</em>
|
||||
* @property {ShapeType} shapeType="ellipsoid" - The shape of the collision hull used if collisions are enabled.
|
||||
* @property {string} compoundShapeURL="" - The model file to use for the compound shape if <code>shapeType</code> is
|
||||
* <code>"compound"</code>.
|
||||
*
|
||||
* @example <caption>Create a ball of green smoke.</caption>
|
||||
* particles = Entities.addEntity({
|
||||
|
@ -1658,6 +1665,7 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
|||
// Particles only
|
||||
if (_type == EntityTypes::ParticleEffect) {
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_SHAPE_TYPE, shapeType, getShapeTypeAsString());
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COMPOUND_SHAPE_URL, compoundShapeURL);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(PROP_COLOR, color, u8vec3Color);
|
||||
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_ALPHA, alpha);
|
||||
_pulse.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
||||
|
@ -3104,6 +3112,7 @@ OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketTy
|
|||
|
||||
if (properties.getType() == EntityTypes::ParticleEffect) {
|
||||
APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)(properties.getShapeType()));
|
||||
APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, properties.getCompoundShapeURL());
|
||||
APPEND_ENTITY_PROPERTY(PROP_COLOR, properties.getColor());
|
||||
APPEND_ENTITY_PROPERTY(PROP_ALPHA, properties.getAlpha());
|
||||
_staticPulse.setProperties(properties);
|
||||
|
@ -3584,6 +3593,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
|||
|
||||
if (properties.getType() == EntityTypes::ParticleEffect) {
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SHAPE_TYPE, ShapeType, setShapeType);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COLOR, u8vec3Color, setColor);
|
||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ALPHA, float, setAlpha);
|
||||
properties.getPulse().decodeFromEditPacket(propertyFlags, dataAt, processedBytes);
|
||||
|
|
|
@ -410,6 +410,7 @@ EntityItemProperties ParticleEffectEntityItem::getProperties(const EntityPropert
|
|||
EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class
|
||||
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(shapeType, getShapeType);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(compoundShapeURL, getCompoundShapeURL);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(color, getColor);
|
||||
COPY_ENTITY_PROPERTY_TO_PROPERTIES(alpha, getAlpha);
|
||||
withReadLock([&] {
|
||||
|
@ -464,6 +465,7 @@ bool ParticleEffectEntityItem::setProperties(const EntityItemProperties& propert
|
|||
bool somethingChanged = EntityItem::setProperties(properties); // set the properties in our base class
|
||||
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(shapeType, setShapeType);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(compoundShapeURL, setCompoundShapeURL);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(color, setColor);
|
||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(alpha, setAlpha);
|
||||
withWriteLock([&] {
|
||||
|
@ -540,6 +542,7 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch
|
|||
const unsigned char* dataAt = data;
|
||||
|
||||
READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, setShapeType);
|
||||
READ_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL);
|
||||
READ_ENTITY_PROPERTY(PROP_COLOR, u8vec3Color, setColor);
|
||||
READ_ENTITY_PROPERTY(PROP_ALPHA, float, setAlpha);
|
||||
withWriteLock([&] {
|
||||
|
@ -598,6 +601,7 @@ EntityPropertyFlags ParticleEffectEntityItem::getEntityProperties(EncodeBitstrea
|
|||
EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params);
|
||||
|
||||
requestedProperties += PROP_SHAPE_TYPE;
|
||||
requestedProperties += PROP_COMPOUND_SHAPE_URL;
|
||||
requestedProperties += PROP_COLOR;
|
||||
requestedProperties += PROP_ALPHA;
|
||||
requestedProperties += _pulseProperties.getEntityProperties(params);
|
||||
|
@ -656,6 +660,7 @@ void ParticleEffectEntityItem::appendSubclassData(OctreePacketData* packetData,
|
|||
|
||||
bool successPropertyFits = true;
|
||||
APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)getShapeType());
|
||||
APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, getCompoundShapeURL());
|
||||
APPEND_ENTITY_PROPERTY(PROP_COLOR, getColor());
|
||||
APPEND_ENTITY_PROPERTY(PROP_ALPHA, getAlpha());
|
||||
withReadLock([&] {
|
||||
|
@ -726,6 +731,24 @@ void ParticleEffectEntityItem::setShapeType(ShapeType type) {
|
|||
});
|
||||
}
|
||||
|
||||
ShapeType ParticleEffectEntityItem::getShapeType() const {
|
||||
return resultWithReadLock<ShapeType>([&] {
|
||||
return _shapeType;
|
||||
});
|
||||
}
|
||||
|
||||
void ParticleEffectEntityItem::setCompoundShapeURL(const QString& compoundShapeURL) {
|
||||
withWriteLock([&] {
|
||||
_compoundShapeURL = compoundShapeURL;
|
||||
});
|
||||
}
|
||||
|
||||
QString ParticleEffectEntityItem::getCompoundShapeURL() const {
|
||||
return resultWithReadLock<QString>([&] {
|
||||
return _compoundShapeURL;
|
||||
});
|
||||
}
|
||||
|
||||
void ParticleEffectEntityItem::setMaxParticles(quint32 maxParticles) {
|
||||
withWriteLock([&] {
|
||||
_particleProperties.maxParticles = glm::clamp(maxParticles, MINIMUM_MAX_PARTICLES, MAXIMUM_MAX_PARTICLES);
|
||||
|
|
|
@ -79,6 +79,7 @@ namespace particle {
|
|||
static const QString DEFAULT_TEXTURES = "";
|
||||
static const bool DEFAULT_EMITTER_SHOULD_TRAIL = false;
|
||||
static const bool DEFAULT_ROTATE_WITH_ENTITY = false;
|
||||
static const ShapeType DEFAULT_SHAPE_TYPE = ShapeType::SHAPE_TYPE_ELLIPSOID;
|
||||
|
||||
template <typename T>
|
||||
struct Range {
|
||||
|
@ -255,7 +256,10 @@ public:
|
|||
float getAlphaSpread() const { return _particleProperties.alpha.gradient.spread; }
|
||||
|
||||
void setShapeType(ShapeType type) override;
|
||||
virtual ShapeType getShapeType() const override { return _shapeType; }
|
||||
virtual ShapeType getShapeType() const override;
|
||||
|
||||
QString getCompoundShapeURL() const;
|
||||
virtual void setCompoundShapeURL(const QString& url);
|
||||
|
||||
virtual void debugDump() const override;
|
||||
|
||||
|
@ -349,7 +353,8 @@ protected:
|
|||
PulsePropertyGroup _pulseProperties;
|
||||
bool _isEmitting { true };
|
||||
|
||||
ShapeType _shapeType { SHAPE_TYPE_NONE };
|
||||
ShapeType _shapeType{ particle::DEFAULT_SHAPE_TYPE };
|
||||
QString _compoundShapeURL { "" };
|
||||
};
|
||||
|
||||
#endif // hifi_ParticleEffectEntityItem_h
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
#include <glm/gtx/transform.hpp>
|
||||
#include <QDebug>
|
||||
#include <QUrlQuery>
|
||||
|
||||
#include <ByteCountCoding.h>
|
||||
|
||||
|
@ -463,9 +462,6 @@ void ZoneEntityItem::fetchCollisionGeometryResource() {
|
|||
if (hullURL.isEmpty()) {
|
||||
_shapeResource.reset();
|
||||
} else {
|
||||
QUrlQuery queryArgs(hullURL);
|
||||
queryArgs.addQueryItem("collision-hull", "");
|
||||
hullURL.setQuery(queryArgs);
|
||||
_shapeResource = DependencyManager::get<ModelCache>()->getCollisionGeometryResource(hullURL);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue