starting improve entity updates pt 2

This commit is contained in:
HifiExperiments 2020-10-12 18:50:46 -07:00
parent 89c006d190
commit 5a8c1a0374
16 changed files with 433 additions and 624 deletions

View file

@ -431,13 +431,13 @@ void EntityRenderer::doRenderUpdateSynchronous(const ScenePointer& scene, Transa
_visible = entity->getVisible();
setIsVisibleInSecondaryCamera(entity->isVisibleInSecondaryCamera());
setRenderLayer(entity->getRenderLayer());
setPrimitiveMode(entity->getPrimitiveMode());
_primitiveMode = entity->getPrimitiveMode();
_canCastShadow = entity->getCanCastShadow();
setCullWithParent(entity->getCullWithParent());
_cauterized = entity->getCauterized();
if (entity->needsZoneOcclusionUpdate()) {
entity->resetNeedsZoneOcclusionUpdate();
setRenderWithZones(entity->getRenderWithZones());
_renderWithZones = entity->getRenderWithZones();
}
entity->setNeedsRenderUpdate(false);
});

View file

@ -108,18 +108,7 @@ protected:
virtual void setIsVisibleInSecondaryCamera(bool value) { _isVisibleInSecondaryCamera = value; }
virtual void setRenderLayer(RenderLayer value) { _renderLayer = value; }
virtual void setPrimitiveMode(PrimitiveMode value) { _primitiveMode = value; }
virtual void setCullWithParent(bool value) { _cullWithParent = value; }
virtual void setRenderWithZones(const QVector<QUuid>& renderWithZones) { _renderWithZones = renderWithZones; }
template <typename F, typename T>
T withReadLockResult(const std::function<T()>& f) {
T result;
withReadLock([&] {
result = f();
});
return result;
}
signals:
void requestRenderUpdate();

View file

@ -52,14 +52,11 @@ void GizmoEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
void GizmoEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
bool dirty = false;
RingGizmoPropertyGroup ringProperties = entity->getRingProperties();
withWriteLock([&] {
_gizmoType = entity->getGizmoType();
if (_ringProperties != ringProperties) {
_ringProperties = ringProperties;
dirty = true;
}
});
_gizmoType = entity->getGizmoType();
if (_ringProperties != ringProperties) {
_ringProperties = ringProperties;
dirty = true;
}
if (dirty || _prevPrimitiveMode != _primitiveMode || !_ringGeometryID || !_majorTicksGeometryID || !_minorTicksGeometryID) {
_prevPrimitiveMode = _primitiveMode;
@ -242,19 +239,20 @@ void GizmoEntityRenderer::doRender(RenderArgs* args) {
if (_gizmoType == GizmoType::RING) {
Transform transform;
bool hasTickMarks;
glm::vec4 tickProperties;
bool hasTickMarks = _ringProperties.getHasTickMarks();
glm::vec4 tickProperties = glm::vec4(_ringProperties.getMajorTickMarksAngle(), _ringProperties.getMajorTickMarksLength(),
_ringProperties.getMinorTickMarksAngle(), _ringProperties.getMinorTickMarksLength());
bool forward;
bool wireframe;
bool transparent;
withReadLock([&] {
transform = _renderTransform;
hasTickMarks = _ringProperties.getHasTickMarks();
tickProperties = glm::vec4(_ringProperties.getMajorTickMarksAngle(), _ringProperties.getMajorTickMarksLength(),
_ringProperties.getMinorTickMarksAngle(), _ringProperties.getMinorTickMarksLength());
transparent = isTransparent();
wireframe = render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES;
forward = _renderLayer != RenderLayer::WORLD || args->_renderMethod == Args::RenderMethod::FORWARD;
});
bool wireframe = render::ShapeKey(args->_globalShapeKey).isWireframe() || _primitiveMode == PrimitiveMode::LINES;
geometryCache->bindSimpleProgram(batch, false, isTransparent(), wireframe, true, true, forward, graphics::MaterialKey::CULL_NONE);
geometryCache->bindSimpleProgram(batch, false, transparent, wireframe, true, true, forward, graphics::MaterialKey::CULL_NONE);
batch.setModelTransform(transform);

View file

@ -30,16 +30,6 @@ bool GridEntityRenderer::isTransparent() const {
}
void GridEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) {
withWriteLock([&] {
_color = entity->getColor();
_alpha = entity->getAlpha();
_pulseProperties = entity->getPulseProperties();
_followCamera = entity->getFollowCamera();
_majorGridEvery = entity->getMajorGridEvery();
_minorGridEvery = entity->getMinorGridEvery();
});
void* key = (void*)this;
AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity] {
withWriteLock([&] {
@ -49,6 +39,16 @@ void GridEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen
});
}
void GridEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
_color = entity->getColor();
_alpha = entity->getAlpha();
_pulseProperties = entity->getPulseProperties();
_followCamera = entity->getFollowCamera();
_majorGridEvery = entity->getMajorGridEvery();
_minorGridEvery = entity->getMinorGridEvery();
}
Item::Bound GridEntityRenderer::getBound() {
if (_followCamera) {
// This is a UI element that should always be in view, lie to the octree to avoid culling
@ -73,13 +73,12 @@ ShapeKey GridEntityRenderer::getShapeKey() {
}
void GridEntityRenderer::doRender(RenderArgs* args) {
glm::vec4 color;
glm::vec4 color = glm::vec4(toGlm(_color), _alpha);
color = EntityRenderer::calculatePulseColor(color, _pulseProperties, _created);
glm::vec3 dimensions;
Transform renderTransform;
bool forward;
withReadLock([&] {
color = glm::vec4(toGlm(_color), _alpha);
color = EntityRenderer::calculatePulseColor(color, _pulseProperties, _created);
dimensions = _dimensions;
renderTransform = _renderTransform;
forward = _renderLayer != RenderLayer::WORLD || args->_renderMethod == Args::RenderMethod::FORWARD;

View file

@ -30,10 +30,11 @@ protected:
private:
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;
virtual void doRender(RenderArgs* args) override;
glm::u8vec3 _color;
float _alpha;
glm::u8vec3 _color { NAN };
float _alpha { NAN };
PulsePropertyGroup _pulseProperties;
bool _followCamera;

View file

@ -29,44 +29,7 @@ bool ImageEntityRenderer::isTransparent() const {
return Parent::isTransparent() || (_textureIsLoaded && _texture->getGPUTexture() && _texture->getGPUTexture()->getUsage().isAlpha()) || _alpha < 1.0f || _pulseProperties.getAlphaMode() != PulseMode::NONE;
}
bool ImageEntityRenderer::needsRenderUpdate() const {
if (resultWithReadLock<bool>([&] {
return !_textureIsLoaded;
})) {
return true;
}
return Parent::needsRenderUpdate();
}
void ImageEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) {
withWriteLock([&] {
auto imageURL = entity->getImageURL();
if (_imageURL != imageURL) {
_imageURL = imageURL;
if (imageURL.isEmpty()) {
_texture.reset();
} else {
_texture = DependencyManager::get<TextureCache>()->getTexture(_imageURL);
}
_textureIsLoaded = false;
}
_emissive = entity->getEmissive();
_keepAspectRatio = entity->getKeepAspectRatio();
_subImage = entity->getSubImage();
_color = entity->getColor();
_alpha = entity->getAlpha();
_pulseProperties = entity->getPulseProperties();
_billboardMode = entity->getBillboardMode();
if (!_textureIsLoaded) {
emit requestRenderUpdate();
}
_textureIsLoaded = _texture && (_texture->isLoaded() || _texture->isFailed());
});
void* key = (void*)this;
AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity] {
withWriteLock([&] {
@ -76,6 +39,33 @@ void ImageEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
});
}
void ImageEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
auto imageURL = entity->getImageURL();
if (_imageURL != imageURL) {
_imageURL = imageURL;
if (imageURL.isEmpty()) {
_texture.reset();
} else {
_texture = DependencyManager::get<TextureCache>()->getTexture(_imageURL);
}
_textureIsLoaded = false;
}
_emissive = entity->getEmissive();
_keepAspectRatio = entity->getKeepAspectRatio();
_subImage = entity->getSubImage();
_color = entity->getColor();
_alpha = entity->getAlpha();
_pulseProperties = entity->getPulseProperties();
_billboardMode = entity->getBillboardMode();
if (!_textureIsLoaded) {
emit requestRenderUpdate();
}
_textureIsLoaded = _texture && (_texture->isLoaded() || _texture->isFailed());
}
Item::Bound ImageEntityRenderer::getBound() {
auto bound = Parent::getBound();
if (_billboardMode != BillboardMode::NONE) {
@ -93,33 +83,26 @@ ShapeKey ImageEntityRenderer::getShapeKey() {
builder.withTranslucent();
}
withReadLock([&] {
if (_emissive) {
builder.withUnlit();
}
if (_emissive) {
builder.withUnlit();
}
if (_primitiveMode == PrimitiveMode::LINES) {
builder.withWireframe();
}
});
if (_primitiveMode == PrimitiveMode::LINES) {
builder.withWireframe();
}
return builder.build();
}
void ImageEntityRenderer::doRender(RenderArgs* args) {
NetworkTexturePointer texture;
QRect subImage;
glm::vec4 color;
glm::vec4 color = glm::vec4(toGlm(_color), _alpha);
color = EntityRenderer::calculatePulseColor(color, _pulseProperties, _created);
Transform transform;
withReadLock([&] {
texture = _texture;
subImage = _subImage;
color = glm::vec4(toGlm(_color), _alpha);
color = EntityRenderer::calculatePulseColor(color, _pulseProperties, _created);
transform = _renderTransform;
});
if (!_visible || !texture || !texture->isLoaded() || color.a == 0.0f) {
if (!_visible || !_texture || !_texture->isLoaded() || color.a == 0.0f) {
return;
}
@ -129,28 +112,28 @@ void ImageEntityRenderer::doRender(RenderArgs* args) {
transform.setRotation(EntityItem::getBillboardRotation(transform.getTranslation(), transform.getRotation(), _billboardMode, args->getViewFrustum().getPosition()));
batch->setModelTransform(transform);
batch->setResourceTexture(0, texture->getGPUTexture());
batch->setResourceTexture(0, _texture->getGPUTexture());
float imageWidth = texture->getWidth();
float imageHeight = texture->getHeight();
float imageWidth = _texture->getWidth();
float imageHeight = _texture->getHeight();
QRect fromImage;
if (subImage.width() <= 0) {
if (_subImage.width() <= 0) {
fromImage.setX(0);
fromImage.setWidth(imageWidth);
} else {
float scaleX = imageWidth / texture->getOriginalWidth();
fromImage.setX(scaleX * subImage.x());
fromImage.setWidth(scaleX * subImage.width());
float scaleX = imageWidth / _texture->getOriginalWidth();
fromImage.setX(scaleX * _subImage.x());
fromImage.setWidth(scaleX * _subImage.width());
}
if (subImage.height() <= 0) {
if (_subImage.height() <= 0) {
fromImage.setY(0);
fromImage.setHeight(imageHeight);
} else {
float scaleY = imageHeight / texture->getOriginalHeight();
fromImage.setY(scaleY * subImage.y());
fromImage.setHeight(scaleY * subImage.height());
float scaleY = imageHeight / _texture->getOriginalHeight();
fromImage.setY(scaleY * _subImage.y());
fromImage.setHeight(scaleY * _subImage.height());
}
float maxSize = glm::max(fromImage.width(), fromImage.height());

View file

@ -29,8 +29,8 @@ protected:
bool isTransparent() const override;
private:
virtual bool needsRenderUpdate() const override;
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;
virtual void doRender(RenderArgs* args) override;
QString _imageURL;

View file

@ -16,199 +16,186 @@
using namespace render;
using namespace render::entities;
bool MaterialEntityRenderer::needsRenderUpdate() const {
if (_retryApply) {
return true;
}
if (!_texturesLoaded) {
return true;
}
return Parent::needsRenderUpdate();
}
bool MaterialEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const {
if (resultWithReadLock<bool>([&] {
if (entity->getTransform() != _transform) {
return true;
}
if (entity->getUnscaledDimensions() != _dimensions) {
return true;
}
if (entity->getParentID() != _parentID) {
return true;
}
return false;
return entity->getParentID() != _parentID;
})) {
return true;
}
return false;
}
void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
withWriteLock([&] {
bool deleteNeeded = false;
bool addNeeded = _retryApply;
bool transformChanged = false;
{
MaterialMappingMode mode = entity->getMaterialMappingMode();
if (mode != _materialMappingMode) {
_materialMappingMode = mode;
transformChanged = true;
}
}
{
bool repeat = entity->getMaterialRepeat();
if (repeat != _materialRepeat) {
_materialRepeat = repeat;
transformChanged = true;
}
}
{
glm::vec2 mappingPos = entity->getMaterialMappingPos();
glm::vec2 mappingScale = entity->getMaterialMappingScale();
float mappingRot = entity->getMaterialMappingRot();
if (mappingPos != _materialMappingPos || mappingScale != _materialMappingScale || mappingRot != _materialMappingRot) {
_materialMappingPos = mappingPos;
_materialMappingScale = mappingScale;
_materialMappingRot = mappingRot;
transformChanged |= _materialMappingMode == MaterialMappingMode::UV;
}
}
{
Transform transform = entity->getTransform();
glm::vec3 dimensions = entity->getUnscaledDimensions();
if (transform != _transform || dimensions != _dimensions) {
_transform = transform;
_dimensions = dimensions;
transformChanged |= _materialMappingMode == MaterialMappingMode::PROJECTED;
}
}
{
auto material = getMaterial();
// Update the old material regardless of if it's going to change
if (transformChanged && material && !_parentID.isNull()) {
deleteNeeded = true;
addNeeded = true;
applyTextureTransform(material);
}
}
bool urlChanged = false;
std::string newCurrentMaterialName = _currentMaterialName;
{
QString materialURL = entity->getMaterialURL();
if (materialURL != _materialURL) {
_materialURL = materialURL;
if (_materialURL.contains("#")) {
auto split = _materialURL.split("#");
newCurrentMaterialName = split.last().toStdString();
} else if (_materialURL.contains("?")) {
qDebug() << "DEPRECATED: Use # instead of ? for material URLS:" << _materialURL;
auto split = _materialURL.split("?");
newCurrentMaterialName = split.last().toStdString();
}
urlChanged = true;
}
}
bool usingMaterialData = _materialURL.startsWith("materialData");
bool materialDataChanged = false;
QUuid oldParentID = _parentID;
QString oldParentMaterialName = _parentMaterialName;
{
QString materialData = entity->getMaterialData();
if (materialData != _materialData) {
_materialData = materialData;
if (usingMaterialData) {
materialDataChanged = true;
}
}
}
{
QString parentMaterialName = entity->getParentMaterialName();
if (parentMaterialName != _parentMaterialName) {
_parentMaterialName = parentMaterialName;
deleteNeeded = true;
addNeeded = true;
}
}
{
QUuid parentID = entity->getParentID();
if (parentID != _parentID) {
_parentID = parentID;
deleteNeeded = true;
addNeeded = true;
}
}
{
quint16 priority = entity->getPriority();
if (priority != _priority) {
_priority = priority;
deleteNeeded = true;
addNeeded = true;
}
}
if (urlChanged && !usingMaterialData) {
_networkMaterial = DependencyManager::get<MaterialCache>()->getMaterial(_materialURL);
auto onMaterialRequestFinished = [this, entity, oldParentID, oldParentMaterialName, newCurrentMaterialName](bool success) {
if (success) {
deleteMaterial(oldParentID, oldParentMaterialName);
_texturesLoaded = false;
_parsedMaterials = _networkMaterial->parsedMaterials;
setCurrentMaterialName(newCurrentMaterialName);
applyMaterial(entity);
} else {
deleteMaterial(oldParentID, oldParentMaterialName);
_retryApply = false;
_texturesLoaded = true;
}
};
if (_networkMaterial) {
if (_networkMaterial->isLoaded()) {
onMaterialRequestFinished(!_networkMaterial->isFailed());
} else {
connect(_networkMaterial.data(), &Resource::finished, this, [this, onMaterialRequestFinished](bool success) {
withWriteLock([&] {
onMaterialRequestFinished(success);
});
});
}
}
} else if (materialDataChanged && usingMaterialData) {
deleteMaterial(oldParentID, oldParentMaterialName);
_texturesLoaded = false;
_parsedMaterials = NetworkMaterialResource::parseJSONMaterials(QJsonDocument::fromJson(_materialData.toUtf8()), _materialURL);
// Since our material changed, the current name might not be valid anymore, so we need to update
setCurrentMaterialName(newCurrentMaterialName);
applyMaterial(entity);
} else {
if (deleteNeeded) {
deleteMaterial(oldParentID, oldParentMaterialName);
}
if (addNeeded) {
applyMaterial(entity);
}
}
{
auto material = getMaterial();
bool newTexturesLoaded = material ? !material->isMissingTexture() : false;
if (!_texturesLoaded && newTexturesLoaded) {
material->checkResetOpacityMap();
}
_texturesLoaded = newTexturesLoaded;
}
_renderTransform = getModelTransform();
const float MATERIAL_ENTITY_SCALE = 0.5f;
_renderTransform.postScale(MATERIAL_ENTITY_SCALE);
_renderTransform.postScale(ENTITY_ITEM_DEFAULT_DIMENSIONS);
void MaterialEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) {
void* key = (void*)this;
AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [this, entity] {
withWriteLock([&] {
_renderTransform = getModelTransform();
const float MATERIAL_ENTITY_SCALE = 0.5f;
_renderTransform.postScale(MATERIAL_ENTITY_SCALE);
_renderTransform.postScale(ENTITY_ITEM_DEFAULT_DIMENSIONS);
});
});
}
void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
bool deleteNeeded = false;
bool addNeeded = _retryApply;
bool transformChanged = false;
{
MaterialMappingMode mode = entity->getMaterialMappingMode();
if (mode != _materialMappingMode) {
_materialMappingMode = mode;
transformChanged = true;
}
}
{
bool repeat = entity->getMaterialRepeat();
if (repeat != _materialRepeat) {
_materialRepeat = repeat;
transformChanged = true;
}
}
{
glm::vec2 mappingPos = entity->getMaterialMappingPos();
glm::vec2 mappingScale = entity->getMaterialMappingScale();
float mappingRot = entity->getMaterialMappingRot();
if (mappingPos != _materialMappingPos || mappingScale != _materialMappingScale || mappingRot != _materialMappingRot) {
_materialMappingPos = mappingPos;
_materialMappingScale = mappingScale;
_materialMappingRot = mappingRot;
transformChanged |= _materialMappingMode == MaterialMappingMode::UV;
}
}
{
Transform transform = entity->getTransform();
glm::vec3 dimensions = entity->getUnscaledDimensions();
if (transform != _transform || dimensions != _dimensions) {
_transform = transform;
_dimensions = dimensions;
transformChanged |= _materialMappingMode == MaterialMappingMode::PROJECTED;
}
}
{
auto material = getMaterial();
// Update the old material regardless of if it's going to change
if (transformChanged && material && !_parentID.isNull()) {
deleteNeeded = true;
addNeeded = true;
applyTextureTransform(material);
}
}
bool urlChanged = false;
std::string newCurrentMaterialName = _currentMaterialName;
{
QString materialURL = entity->getMaterialURL();
if (materialURL != _materialURL) {
_materialURL = materialURL;
if (_materialURL.contains("#")) {
auto split = _materialURL.split("#");
newCurrentMaterialName = split.last().toStdString();
} else if (_materialURL.contains("?")) {
qDebug() << "DEPRECATED: Use # instead of ? for material URLS:" << _materialURL;
auto split = _materialURL.split("?");
newCurrentMaterialName = split.last().toStdString();
}
urlChanged = true;
}
}
bool usingMaterialData = _materialURL.startsWith("materialData");
bool materialDataChanged = false;
QUuid oldParentID = _parentID;
QString oldParentMaterialName = _parentMaterialName;
{
QString materialData = entity->getMaterialData();
if (materialData != _materialData) {
_materialData = materialData;
if (usingMaterialData) {
materialDataChanged = true;
}
}
}
{
QString parentMaterialName = entity->getParentMaterialName();
if (parentMaterialName != _parentMaterialName) {
_parentMaterialName = parentMaterialName;
deleteNeeded = true;
addNeeded = true;
}
}
{
QUuid parentID = entity->getParentID();
if (parentID != _parentID) {
_parentID = parentID;
deleteNeeded = true;
addNeeded = true;
}
}
{
quint16 priority = entity->getPriority();
if (priority != _priority) {
_priority = priority;
deleteNeeded = true;
addNeeded = true;
}
}
if (urlChanged && !usingMaterialData) {
_networkMaterial = DependencyManager::get<MaterialCache>()->getMaterial(_materialURL);
auto onMaterialRequestFinished = [this, entity, oldParentID, oldParentMaterialName, newCurrentMaterialName](bool success) {
deleteMaterial(oldParentID, oldParentMaterialName);
if (success) {
_texturesLoaded = false;
_parsedMaterials = _networkMaterial->parsedMaterials;
setCurrentMaterialName(newCurrentMaterialName);
applyMaterial(entity);
emit requestRenderUpdate();
} else {
_retryApply = false;
_texturesLoaded = true;
}
};
if (_networkMaterial) {
if (_networkMaterial->isLoaded()) {
onMaterialRequestFinished(!_networkMaterial->isFailed());
} else {
connect(_networkMaterial.data(), &Resource::finished, this, [this, onMaterialRequestFinished](bool success) {
onMaterialRequestFinished(success);
});
}
}
} else if (materialDataChanged && usingMaterialData) {
deleteMaterial(oldParentID, oldParentMaterialName);
_texturesLoaded = false;
_parsedMaterials = NetworkMaterialResource::parseJSONMaterials(QJsonDocument::fromJson(_materialData.toUtf8()), _materialURL);
// Since our material changed, the current name might not be valid anymore, so we need to update
setCurrentMaterialName(newCurrentMaterialName);
applyMaterial(entity);
} else {
if (deleteNeeded) {
deleteMaterial(oldParentID, oldParentMaterialName);
}
if (addNeeded) {
applyMaterial(entity);
}
}
{
auto material = getMaterial();
bool newTexturesLoaded = material ? !material->isMissingTexture() : false;
if (!_texturesLoaded && newTexturesLoaded) {
material->checkResetOpacityMap();
}
_texturesLoaded = newTexturesLoaded;
}
if (!_texturesLoaded || _retryApply) {
emit requestRenderUpdate();
}
}
ItemKey MaterialEntityRenderer::getKey() {
auto builder = ItemKey::Builder().withTypeShape().withTagBits(getTagMask()).withLayer(getHifiRenderLayer());
@ -276,25 +263,26 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) {
return;
}
Transform renderTransform;
graphics::MaterialPointer drawMaterial;
graphics::MaterialPointer drawMaterial = getMaterial();
bool proceduralRender = false;
Transform textureTransform;
textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0));
textureTransform.setRotation(glm::vec3(0, 0, glm::radians(_materialMappingRot)));
textureTransform.setScale(glm::vec3(_materialMappingScale, 1));
Transform renderTransform;
withReadLock([&] {
renderTransform = _renderTransform;
drawMaterial = getMaterial();
textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0));
textureTransform.setRotation(glm::vec3(0, 0, glm::radians(_materialMappingRot)));
textureTransform.setScale(glm::vec3(_materialMappingScale, 1));
if (drawMaterial && drawMaterial->isProcedural() && drawMaterial->isReady()) {
proceduralRender = true;
}
});
if (!drawMaterial) {
return;
}
if (drawMaterial->isProcedural() && drawMaterial->isReady()) {
proceduralRender = true;
}
batch.setModelTransform(renderTransform);
if (!proceduralRender) {

View file

@ -27,8 +27,8 @@ public:
~MaterialEntityRenderer() { deleteMaterial(_parentID, _parentMaterialName); }
private:
virtual bool needsRenderUpdate() const override;
virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override;
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;
virtual void doRender(RenderArgs* args) override;

View file

@ -53,7 +53,7 @@ ModelPointer ModelEntityWrapper::getModel() const {
bool ModelEntityWrapper::isModelLoaded() const {
return resultWithReadLock<bool>([&] {
return _model.operator bool() && _model->isLoaded();
return _model && _model->isLoaded();
});
}
@ -69,8 +69,7 @@ EntityItemPointer RenderableModelEntityItem::factory(const EntityItemID& entityI
RenderableModelEntityItem::RenderableModelEntityItem(const EntityItemID& entityItemID, bool dimensionsInitialized) :
ModelEntityWrapper(entityItemID),
_dimensionsInitialized(dimensionsInitialized) {
}
RenderableModelEntityItem::~RenderableModelEntityItem() { }
@ -182,20 +181,24 @@ void RenderableModelEntityItem::updateModelBounds() {
}
bool overridingModelTransform = model->isOverridingModelTransformAndOffset();
glm::vec3 scaledDimensions = getScaledDimensions();
glm::vec3 registrationPoint = getRegistrationPoint();
QString modelURL = getModelURL();
if (!overridingModelTransform &&
(model->getScaleToFitDimensions() != getScaledDimensions() ||
model->getRegistrationPoint() != getRegistrationPoint() ||
(model->getScaleToFitDimensions() != scaledDimensions ||
model->getRegistrationPoint() != registrationPoint ||
model->getURL() != modelURL ||
!model->getIsScaledToFit())) {
// The machinery for updateModelBounds will give existing models the opportunity to fix their
// translation/rotation/scale/registration. The first two are straightforward, but the latter two
// have guards to make sure they don't happen after they've already been set. Here we reset those guards.
// This doesn't cause the entity values to change -- it just allows the model to match once it comes in.
model->setScaleToFit(false, getScaledDimensions());
model->setSnapModelToRegistrationPoint(false, getRegistrationPoint());
model->setScaleToFit(false, scaledDimensions);
model->setSnapModelToRegistrationPoint(false, registrationPoint);
// now recalculate the bounds and registration
model->setScaleToFit(true, getScaledDimensions());
model->setSnapModelToRegistrationPoint(true, getRegistrationPoint());
model->setScaleToFit(true, scaledDimensions);
model->setSnapModelToRegistrationPoint(true, registrationPoint);
updateRenderItems = true;
model->scaleToFit();
}
@ -248,8 +251,6 @@ EntityItemProperties RenderableModelEntityItem::getProperties(const EntityProper
}
}
return properties;
}
@ -960,13 +961,13 @@ QStringList RenderableModelEntityItem::getJointNames() const {
}
scriptable::ScriptableModelBase render::entities::ModelEntityRenderer::getScriptableModel() {
auto model = resultWithReadLock<ModelPointer>([this]{ return _model; });
auto model = resultWithReadLock<ModelPointer>([&] { return _model; });
if (!model || !model->isLoaded()) {
return scriptable::ScriptableModelBase();
}
auto result = _model->getScriptableModel();
auto result = model->getScriptableModel();
result.objectID = getEntity()->getID();
{
std::lock_guard<std::mutex> lock(_materialsLock);
@ -1054,10 +1055,10 @@ ModelEntityRenderer::ModelEntityRenderer(const EntityItemPointer& entity) : Pare
}
void ModelEntityRenderer::setKey(bool didVisualGeometryRequestSucceed) {
void ModelEntityRenderer::setKey(bool didVisualGeometryRequestSucceed, const ModelPointer& model) {
auto builder = ItemKey::Builder().withTypeMeta().withTagBits(getTagMask()).withLayer(getHifiRenderLayer());
if (!_cullWithParent && _model && _model->isGroupCulled()) {
if (!_cullWithParent && model && model->isGroupCulled()) {
builder.withMetaCullGroup();
} else if (_cullWithParent) {
builder.withSubMetaCulled();
@ -1075,8 +1076,9 @@ ItemKey ModelEntityRenderer::getKey() {
}
uint32_t ModelEntityRenderer::metaFetchMetaSubItems(ItemIDs& subItems) const {
if (_model) {
auto metaSubItems = _model->fetchRenderItemIDs();
auto model = resultWithReadLock<ModelPointer>([&] { return _model; });
if (model) {
auto metaSubItems = model->fetchRenderItemIDs();
subItems.insert(subItems.end(), metaSubItems.begin(), metaSubItems.end());
return (uint32_t)metaSubItems.size();
}
@ -1089,8 +1091,9 @@ void ModelEntityRenderer::handleBlendedVertices(int blendshapeNumber, const QVec
}
void ModelEntityRenderer::removeFromScene(const ScenePointer& scene, Transaction& transaction) {
if (_model) {
_model->removeFromScene(scene, transaction);
auto model = resultWithReadLock<ModelPointer>([&] { return _model; });
if (model) {
model->removeFromScene(scene, transaction);
}
Parent::removeFromScene(scene, transaction);
}
@ -1099,7 +1102,7 @@ void ModelEntityRenderer::onRemoveFromSceneTyped(const TypedEntityPointer& entit
entity->setModel({});
}
void ModelEntityRenderer::animate(const TypedEntityPointer& entity) {
void ModelEntityRenderer::animate(const TypedEntityPointer& entity, const ModelPointer& model) {
if (!_animation || !_animation->isLoaded()) {
return;
}
@ -1124,17 +1127,17 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) {
_lastKnownCurrentFrame = currentIntegerFrame;
}
if (_jointMapping.size() != _model->getJointStateCount()) {
if (_jointMapping.size() != model->getJointStateCount()) {
qCWarning(entitiesrenderer) << "RenderableModelEntityItem::getAnimationFrame -- joint count mismatch"
<< _jointMapping.size() << _model->getJointStateCount();
<< _jointMapping.size() << model->getJointStateCount();
return;
}
QStringList animationJointNames = _animation->getHFMModel().getJointNames();
auto& hfmJoints = _animation->getHFMModel().joints;
auto& originalHFMJoints = _model->getHFMModel().joints;
auto& originalHFMIndices = _model->getHFMModel().jointIndices;
auto& originalHFMJoints = model->getHFMModel().joints;
auto& originalHFMIndices = model->getHFMModel().jointIndices;
bool allowTranslation = entity->getAnimationAllowTranslation();
@ -1183,90 +1186,39 @@ void ModelEntityRenderer::animate(const TypedEntityPointer& entity) {
}
bool ModelEntityRenderer::needsRenderUpdate() const {
if (resultWithReadLock<bool>([&] {
if (_moving || _animating) {
return true;
}
//ModelPointer model = resultWithReadLock<ModelPointer>([&] {
// return _model;
//});
if (!_texturesLoaded) {
return true;
}
//if (model) {
// // When the individual mesh parts of a model finish fading, they will mark their Model as needing updating
// // we will watch for that and ask the model to update it's render items
// if (model->needsReload()) {
// return true;
// }
if (!_prevModelLoaded) {
return true;
}
return false;
})) {
return true;
}
ModelPointer model;
QUrl parsedModelURL;
withReadLock([&] {
model = _model;
parsedModelURL = _parsedModelURL;
});
if (model) {
// When the individual mesh parts of a model finish fading, they will mark their Model as needing updating
// we will watch for that and ask the model to update it's render items
if (parsedModelURL != model->getURL()) {
return true;
}
if (model->needsReload()) {
return true;
}
if (model->needsFixupInScene()) {
return true;
}
if (model->getRenderItemsNeedUpdate()) {
return true;
}
}
// if (model->needsFixupInScene()) {
// return true;
// }
//}
return Parent::needsRenderUpdate();
}
bool ModelEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const {
if (resultWithReadLock<bool>([&] {
if (entity->hasModel() != _hasModel) {
return true;
}
if (entity->blendshapesChanged()) {
return true;
}
// No model to render, early exit
if (!_hasModel) {
return false;
}
// Check to see if we need to update the model bounds
if (entity->needsUpdateModelBounds()) {
return true;
}
if (_animating != entity->isAnimatingSomething()) {
return true;
}
return false;
})) { return true; }
ModelPointer model;
withReadLock([&] {
model = _model;
ModelPointer model = resultWithReadLock<ModelPointer>([&] {
return _model;
});
if (model && model->isLoaded()) {
if (!entity->_dimensionsInitialized || entity->_needsInitialSimulation || !entity->_originalTexturesRead) {
return true;
}
if (entity->blendshapesChanged()) {
return true;
}
// Check to see if we need to update the model bounds
if (entity->needsUpdateModelBounds()) {
return true;
}
// Check to see if we need to update the model bounds
auto transform = entity->getTransform();
if (model->getTranslation() != transform.getTranslation() ||
@ -1280,48 +1232,38 @@ bool ModelEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoin
}
}
return false;
return Parent::needsRenderUpdateFromTypedEntity(entity);
}
void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) {
void ModelEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
DETAILED_PROFILE_RANGE(simulation_physics, __FUNCTION__);
if (_hasModel != entity->hasModel()) {
withWriteLock([&] {
_hasModel = entity->hasModel();
});
_hasModel = entity->hasModel();
if (_parsedModelURL != entity->getModelURL()) {
_parsedModelURL = QUrl(entity->getModelURL());
}
withWriteLock([&] {
_animating = entity->isAnimatingSomething();
if (_parsedModelURL != entity->getModelURL()) {
_parsedModelURL = QUrl(entity->getModelURL());
}
ModelPointer model = resultWithReadLock<ModelPointer>([&] {
return _model;
});
ModelPointer model;
withReadLock([&] { model = _model; });
bool visuallyReady = model && model->isLoaded() && _didLastVisualGeometryRequestSucceed && _texturesLoaded;
entity->setVisuallyReady(visuallyReady);
withWriteLock([&] {
bool visuallyReady = true;
if (_hasModel) {
if (model && _didLastVisualGeometryRequestSucceed) {
visuallyReady = (_prevModelLoaded && _texturesLoaded);
}
}
entity->setVisuallyReady(visuallyReady);
});
const render::ScenePointer& scene = AbstractViewStateInterface::instance()->getMain3DScene();
render::Transaction transaction;
// Check for removal
if (!_hasModel) {
if (model) {
model->removeFromScene(scene, transaction);
entity->bumpAncestorChainRenderableVersion();
withWriteLock([&] { _model.reset(); });
emit DependencyManager::get<scriptable::ModelProviderFactory>()->
modelRemovedFromScene(entity->getEntityItemID(), NestableType::Entity, _model);
modelRemovedFromScene(entity->getEntityItemID(), NestableType::Entity, model);
withWriteLock([&] { model.reset(); });
}
setKey(false);
_didLastVisualGeometryRequestSucceed = false;
setKey(_didLastVisualGeometryRequestSucceed, model);
return;
}
@ -1330,18 +1272,28 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
model = std::make_shared<Model>(nullptr, entity.get(), _created);
connect(model.get(), &Model::requestRenderUpdate, this, &ModelEntityRenderer::requestRenderUpdate);
connect(model.get(), &Model::setURLFinished, this, [&](bool didVisualGeometryRequestSucceed) {
setKey(didVisualGeometryRequestSucceed);
_model->setTagMask(getTagMask());
_model->setHifiRenderLayer(getHifiRenderLayer());
_model->setPrimitiveMode(_primitiveMode);
_model->setCullWithParent(_cullWithParent);
_model->setRenderWithZones(_renderWithZones);
emit requestRenderUpdate();
const render::ScenePointer& scene = AbstractViewStateInterface::instance()->getMain3DScene();
withWriteLock([&] {
setKey(didVisualGeometryRequestSucceed, _model);
_model->setVisibleInScene(_visible, scene);
_model->setCauterized(_cauterized, scene);
_model->setCanCastShadow(_canCastShadow, scene);
_model->setGroupCulled(entity->getGroupCulled(), scene);
_model->setTagMask(getTagMask(), scene);
_model->setHifiRenderLayer(getHifiRenderLayer(), scene);
_model->setPrimitiveMode(_primitiveMode, scene);
_model->setCullWithParent(_cullWithParent, scene);
_model->setRenderWithZones(_renderWithZones, scene);
});
if (didVisualGeometryRequestSucceed) {
emit DependencyManager::get<scriptable::ModelProviderFactory>()->
modelAddedToScene(entity->getEntityItemID(), NestableType::Entity, _model);
modelAddedToScene(entity->getEntityItemID(), NestableType::Entity, model);
}
_didLastVisualGeometryRequestSucceed = didVisualGeometryRequestSucceed;
entity->_dimensionsInitialized = false;
entity->_originalTexturesRead = false;
entity->_needsJointSimulation = true;
emit requestRenderUpdate();
});
model->setLoadingPriority(EntityTreeRenderer::getEntityLoadingPriority(*entity));
entity->setModel(model);
@ -1350,24 +1302,15 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
// From here on, we are guaranteed a populated model
if (_parsedModelURL != model->getURL()) {
withWriteLock([&] {
_texturesLoaded = false;
_jointMappingCompleted = false;
model->setURL(_parsedModelURL);
});
_texturesLoaded = false;
_jointMappingCompleted = false;
model->setURL(_parsedModelURL);
}
// Nothing else to do unless the model is loaded
if (!model->isLoaded()) {
withWriteLock([&] {
_prevModelLoaded = false;
});
emit requestRenderUpdate();
return;
} else if (!_prevModelLoaded) {
withWriteLock([&] {
_prevModelLoaded = true;
});
}
// Check for initializing the model
@ -1383,6 +1326,7 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
QMetaObject::invokeMethod(DependencyManager::get<EntityScriptingInterface>().data(), "editEntity",
Qt::QueuedConnection, Q_ARG(QUuid, entity->getEntityItemID()), Q_ARG(EntityItemProperties, properties));
entity->_dimensionsInitialized = true;
}
if (!entity->_originalTexturesRead) {
@ -1393,51 +1337,34 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
if (_textures != entity->getTextures()) {
QVariantMap newTextures;
withWriteLock([&] {
_texturesLoaded = false;
_textures = entity->getTextures();
newTextures = parseTexturesToMap(_textures, entity->_originalTextures);
});
_texturesLoaded = false;
_textures = entity->getTextures();
newTextures = parseTexturesToMap(_textures, entity->_originalTextures);
model->setTextures(newTextures);
}
if (entity->_needsJointSimulation) {
entity->copyAnimationJointDataToModel();
}
entity->updateModelBounds();
entity->stopModelOverrideIfNoParent();
if (model->isVisible() != _visible) {
model->setVisibleInScene(_visible, scene);
}
if (model->isCauterized() != _cauterized) {
model->setCauterized(_cauterized, scene);
}
render::hifi::Tag tagMask = getTagMask();
if (model->getTagMask() != tagMask) {
model->setTagMask(tagMask, scene);
}
setKey(_didLastVisualGeometryRequestSucceed, model);
model->setVisibleInScene(_visible, scene);
model->setCauterized(_cauterized, scene);
model->setCanCastShadow(_canCastShadow, scene);
model->setGroupCulled(entity->getGroupCulled(), scene);
model->setTagMask(getTagMask(), scene);
model->setHifiRenderLayer(getHifiRenderLayer(), scene);
model->setPrimitiveMode(_primitiveMode, scene);
model->setCullWithParent(_cullWithParent, scene);
model->setRenderWithZones(_renderWithZones, scene);
if (entity->blendshapesChanged()) {
model->setBlendshapeCoefficients(entity->getBlendshapeCoefficientVector());
model->updateBlendshapes();
}
// TODO? early exit here when not visible?
if (model->canCastShadow() != _canCastShadow) {
model->setCanCastShadow(_canCastShadow, scene);
}
{
bool groupCulled = entity->getGroupCulled();
if (model->isGroupCulled() != groupCulled) {
model->setGroupCulled(groupCulled);
setKey(_didLastVisualGeometryRequestSucceed);
}
}
{
DETAILED_PROFILE_RANGE(simulation_physics, "Fixup");
if (model->needsFixupInScene()) {
@ -1452,9 +1379,7 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
}
if (!_texturesLoaded && model->getGeometry() && model->getGeometry()->areTexturesLoaded()) {
withWriteLock([&] {
_texturesLoaded = true;
});
_texturesLoaded = true;
model->updateRenderItems();
} else if (!_texturesLoaded) {
emit requestRenderUpdate();
@ -1491,9 +1416,13 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
model->updateRenderItems();
}
scene->enqueueTransaction(transaction);
}
void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) {
// The code to deal with the change of properties is now in ModelEntityItem.cpp
// That is where _currentFrame and _lastAnimated were updated.
if (_animating) {
if (entity->isAnimatingSomething()) {
DETAILED_PROFILE_RANGE(simulation_physics, "Animate");
auto animationURL = entity->getAnimationURL();
@ -1502,18 +1431,20 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
_animationURL = animationURL;
if (_animation) {
//(_animation->getURL().toString() != entity->getAnimationURL())) { // bad check
// the joints have been mapped before but we have a new animation to load
_animation.reset();
_jointMappingCompleted = false;
}
}
ModelPointer model = resultWithReadLock<ModelPointer>([&] {
return _model;
});
if (!_jointMappingCompleted) {
mapJoints(entity, model);
}
if (entity->readyToAnimate()) {
animate(entity);
if (entity->readyToAnimate() && model && model->isLoaded()) {
animate(entity, model);
}
emit requestRenderUpdate();
}
@ -1521,40 +1452,20 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
void ModelEntityRenderer::setIsVisibleInSecondaryCamera(bool value) {
Parent::setIsVisibleInSecondaryCamera(value);
setKey(_didLastVisualGeometryRequestSucceed);
if (_model) {
_model->setTagMask(getTagMask());
}
// called within a lock so no need to lock for _model
setKey(_didLastVisualGeometryRequestSucceed, _model);
}
void ModelEntityRenderer::setRenderLayer(RenderLayer value) {
Parent::setRenderLayer(value);
setKey(_didLastVisualGeometryRequestSucceed);
if (_model) {
_model->setHifiRenderLayer(getHifiRenderLayer());
}
}
void ModelEntityRenderer::setPrimitiveMode(PrimitiveMode value) {
Parent::setPrimitiveMode(value);
if (_model) {
_model->setPrimitiveMode(_primitiveMode);
}
// called within a lock so no need to lock for _model
setKey(_didLastVisualGeometryRequestSucceed, _model);
}
void ModelEntityRenderer::setCullWithParent(bool value) {
Parent::setCullWithParent(value);
setKey(_didLastVisualGeometryRequestSucceed);
if (_model) {
_model->setCullWithParent(_cullWithParent);
}
}
void ModelEntityRenderer::setRenderWithZones(const QVector<QUuid>& renderWithZones) {
Parent::setRenderWithZones(renderWithZones);
if (_model) {
_model->setRenderWithZones(renderWithZones);
}
// called within a lock so no need to lock for _model
setKey(_didLastVisualGeometryRequestSucceed, _model);
}
// NOTE: this only renders the "meta" portion of the Model, namely it renders debugging items
@ -1570,9 +1481,8 @@ void ModelEntityRenderer::doRender(RenderArgs* args) {
geometryCache->renderWireCubeInstance(args, batch, greenColor, geometryCache->getShapePipelinePointer(false, false, args->_renderMethod == Args::RenderMethod::FORWARD));
#if WANT_EXTRA_DEBUGGING
ModelPointer model;
withReadLock([&] {
model = _model;
ModelPointer model = resultWithReadLock<ModelPointer>([&] {
return _model;
});
if (model) {
model->renderDebugMeshBoxes(batch, args->_renderMethod == Args::RenderMethod::FORWARD);

View file

@ -153,25 +153,24 @@ protected:
virtual void removeFromScene(const ScenePointer& scene, Transaction& transaction) override;
virtual void onRemoveFromSceneTyped(const TypedEntityPointer& entity) override;
void setKey(bool didVisualGeometryRequestSucceed);
void setKey(bool didVisualGeometryRequestSucceed, const ModelPointer& model);
virtual ItemKey getKey() override;
virtual uint32_t metaFetchMetaSubItems(ItemIDs& subItems) const override;
virtual void handleBlendedVertices(int blendshapeNumber, const QVector<BlendshapeOffset>& blendshapeOffsets,
const QVector<int>& blendedMeshSizes, const render::ItemIDs& subItemIDs) override;
virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override;
virtual bool needsRenderUpdate() const override;
virtual void doRender(RenderArgs* args) override;
virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override;
virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override;
virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;
virtual void doRender(RenderArgs* args) override;
void setIsVisibleInSecondaryCamera(bool value) override;
void setRenderLayer(RenderLayer value) override;
void setPrimitiveMode(PrimitiveMode value) override;
void setCullWithParent(bool value) override;
void setRenderWithZones(const QVector<QUuid>& renderWithZones) override;
private:
void animate(const TypedEntityPointer& entity);
void animate(const TypedEntityPointer& entity, const ModelPointer& model);
void mapJoints(const TypedEntityPointer& entity, const ModelPointer& model);
// Transparency is handled in ModelMeshPartPayload
@ -192,14 +191,12 @@ private:
bool _jointMappingCompleted { false };
QVector<int> _jointMapping; // domain is index into model-joints, range is index into animation-joints
AnimationPointer _animation;
bool _animating { false };
QString _animationURL;
uint64_t _lastAnimated { 0 };
render::ItemKey _itemKey { render::ItemKey::Builder().withTypeMeta() };
bool _didLastVisualGeometryRequestSucceed { true };
bool _prevModelLoaded { false };
void processMaterials();
bool _allProceduralMaterialsLoaded { false };

View file

@ -78,7 +78,14 @@ void LightEntityItem::setFalloffRadius(float value) {
}
void LightEntityItem::setIsSpotlight(bool value) {
if (value == getIsSpotlight()) {
bool needsRenderUpdate;
withWriteLock([&] {
needsRenderUpdate = value != _isSpotlight;
_needsRenderUpdate |= needsRenderUpdate;
_isSpotlight = value;
});
if (!needsRenderUpdate) {
return;
}
@ -92,25 +99,25 @@ void LightEntityItem::setIsSpotlight(bool value) {
newDimensions = glm::vec3(glm::compMax(dimensions));
}
withWriteLock([&] {
_needsRenderUpdate = true;
_isSpotlight = value;
});
setScaledDimensions(newDimensions);
}
void LightEntityItem::setCutoff(float value) {
value = glm::clamp(value, MIN_CUTOFF, MAX_CUTOFF);
if (value == getCutoff()) {
bool needsRenderUpdate;
bool spotlight;
withWriteLock([&] {
needsRenderUpdate = value != _cutoff;
_needsRenderUpdate |= needsRenderUpdate;
_cutoff = value;
spotlight = _isSpotlight;
});
if (!needsRenderUpdate) {
return;
}
withWriteLock([&] {
_needsRenderUpdate = true;
_cutoff = value;
});
if (getIsSpotlight()) {
if (spotlight) {
// If we are a spotlight, adjusting the cutoff will affect the area we encapsulate,
// so update the dimensions to reflect this.
const float length = getScaledDimensions().z;

View file

@ -330,13 +330,6 @@ void ModelEntityItem::setCompoundShapeURL(const QString& url) {
});
}
void ModelEntityItem::setAnimationURL(const QString& url) {
_flags |= Simulation::DIRTY_UPDATEABLE;
withWriteLock([&] {
_animationProperties.setURL(url);
});
}
void ModelEntityItem::setAnimationSettings(const QString& value) {
// NOTE: this method only called for old bitstream format
@ -399,20 +392,6 @@ void ModelEntityItem::setAnimationSettings(const QString& value) {
});
}
void ModelEntityItem::setAnimationIsPlaying(bool value) {
_flags |= Simulation::DIRTY_UPDATEABLE;
withWriteLock([&] {
_animationProperties.setRunning(value);
});
}
void ModelEntityItem::setAnimationFPS(float value) {
_flags |= Simulation::DIRTY_UPDATEABLE;
withWriteLock([&] {
_animationProperties.setFPS(value);
});
}
void ModelEntityItem::resizeJointArrays(int newSize) {
if (newSize < 0) {
return;
@ -629,61 +608,18 @@ void ModelEntityItem::setAnimationCurrentFrame(float value) {
});
}
void ModelEntityItem::setAnimationAllowTranslation(bool value) {
withWriteLock([&] {
_animationProperties.setAllowTranslation(value);
});
}
bool ModelEntityItem::getAnimationAllowTranslation() const {
return resultWithReadLock<bool>([&] {
return _animationProperties.getAllowTranslation();
});
}
void ModelEntityItem::setAnimationLoop(bool loop) {
withWriteLock([&] {
_animationProperties.setLoop(loop);
});
}
bool ModelEntityItem::getAnimationLoop() const {
return resultWithReadLock<bool>([&] {
return _animationProperties.getLoop();
});
}
void ModelEntityItem::setAnimationHold(bool hold) {
withWriteLock([&] {
_animationProperties.setHold(hold);
});
}
bool ModelEntityItem::getAnimationHold() const {
return resultWithReadLock<bool>([&] {
return _animationProperties.getHold();
});
}
bool ModelEntityItem::getAnimationIsPlaying() const {
return resultWithReadLock<bool>([&] {
return _animationProperties.getRunning();
});
}
float ModelEntityItem::getAnimationCurrentFrame() const {
return resultWithReadLock<float>([&] {
return _animationProperties.getCurrentFrame();
});
}
float ModelEntityItem::getAnimationFPS() const {
return resultWithReadLock<float>([&] {
return _animationProperties.getFPS();
});
}
bool ModelEntityItem::isAnimatingSomething() const {
return resultWithReadLock<bool>([&] {
return _animationProperties.isValidAndRunning();
@ -722,6 +658,7 @@ bool ModelEntityItem::applyNewAnimationProperties(AnimationPropertyGroup newProp
bool somethingChanged = newProperties != _animationProperties;
if (somethingChanged) {
_animationProperties = newProperties;
_needsRenderUpdate = true;
_flags |= Simulation::DIRTY_UPDATEABLE;
}
return somethingChanged;

View file

@ -85,24 +85,12 @@ public:
// Animation related items...
AnimationPropertyGroup getAnimationProperties() const;
// TODO: audit and remove unused Animation accessors
bool hasAnimation() const;
QString getAnimationURL() const;
virtual void setAnimationURL(const QString& url);
void setAnimationCurrentFrame(float value);
void setAnimationIsPlaying(bool value);
void setAnimationFPS(float value);
void setAnimationAllowTranslation(bool value);
float getAnimationCurrentFrame() const;
bool getAnimationAllowTranslation() const;
void setAnimationLoop(bool loop);
bool getAnimationLoop() const;
void setAnimationHold(bool hold);
bool getAnimationHold() const;
bool isAnimatingSomething() const;
void setRelayParentJoints(bool relayJoints);
bool getRelayParentJoints() const;
@ -110,11 +98,6 @@ public:
void setGroupCulled(bool value);
bool getGroupCulled() const;
bool getAnimationIsPlaying() const;
float getAnimationCurrentFrame() const;
float getAnimationFPS() const;
bool isAnimatingSomething() const;
static const QString DEFAULT_TEXTURES;
const QString getTextures() const;
void setTextures(const QString& textures);

View file

@ -958,16 +958,20 @@ void Model::setCauterized(bool cauterized, const render::ScenePointer& scene) {
}
}
void Model::setPrimitiveMode(PrimitiveMode primitiveMode) {
void Model::setPrimitiveMode(PrimitiveMode primitiveMode, const render::ScenePointer& scene) {
if (_primitiveMode != primitiveMode) {
_primitiveMode = primitiveMode;
updateRenderItemsKey(nullptr);
updateRenderItemsKey(scene);
}
}
void Model::setCullWithParent(bool cullWithParent) {
void Model::setCullWithParent(bool cullWithParent, const render::ScenePointer& scene) {
if (_cullWithParent != cullWithParent) {
_cullWithParent = cullWithParent;
if (!scene) {
_needsFixupInScene = true;
return;
}
render::Transaction transaction;
auto renderItemsKey = _renderItemKeyGlobalFlags;
@ -977,14 +981,27 @@ void Model::setCullWithParent(bool cullWithParent) {
data.updateKey(renderItemsKey);
});
}
AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction);
scene->enqueueTransaction(transaction);
}
}
void Model::setRenderWithZones(const QVector<QUuid>& renderWithZones) {
void Model::setRenderWithZones(const QVector<QUuid>& renderWithZones, const render::ScenePointer& scene) {
if (_renderWithZones != renderWithZones) {
_renderWithZones = renderWithZones;
setRenderItemsNeedUpdate();
if (!scene) {
_needsFixupInScene = true;
return;
}
render::Transaction transaction;
auto renderItemsKey = _renderItemKeyGlobalFlags;
for (auto item : _modelMeshRenderItemIDs) {
transaction.updateItem<ModelMeshPartPayload>(item, [renderWithZones, renderItemsKey](ModelMeshPartPayload& data) {
data.setRenderWithZones(renderWithZones);
});
}
scene->enqueueTransaction(transaction);
}
}

View file

@ -116,14 +116,14 @@ public:
void setHifiRenderLayer(render::hifi::Layer layer, const render::ScenePointer& scene = nullptr);
bool isCauterized() const { return _cauterized; }
void setCauterized(bool value, const render::ScenePointer& scene);
void setCauterized(bool value, const render::ScenePointer& scene = nullptr);
void setPrimitiveMode(PrimitiveMode primitiveMode);
void setPrimitiveMode(PrimitiveMode primitiveMode, const render::ScenePointer& scene = nullptr);
PrimitiveMode getPrimitiveMode() const { return _primitiveMode; }
void setCullWithParent(bool value);
void setCullWithParent(bool value, const render::ScenePointer& scene = nullptr);
void setRenderWithZones(const QVector<QUuid>& renderWithZones);
void setRenderWithZones(const QVector<QUuid>& renderWithZones, const render::ScenePointer& scene = nullptr);
const QVector<QUuid>& getRenderWithZones() const { return _renderWithZones; }
// Access the current RenderItemKey Global Flags used by the model and applied to the render items representing the parts of the model.