mirror of
https://github.com/overte-org/overte.git
synced 2025-04-22 09:33:36 +02:00
First working fade
This commit is contained in:
parent
06d69d04c3
commit
267531cc1a
9 changed files with 221 additions and 87 deletions
|
@ -61,7 +61,7 @@ namespace render {
|
|||
template <> uint32_t metaFetchMetaSubItems(const AvatarSharedPointer& avatar, ItemIDs& subItems) {
|
||||
auto avatarPtr = static_pointer_cast<Avatar>(avatar);
|
||||
if (avatarPtr->getSkeletonModel()) {
|
||||
auto metaSubItems = avatarPtr->getSkeletonModel()->fetchRenderItemIDs();
|
||||
auto& metaSubItems = avatarPtr->getSkeletonModel()->fetchRenderItemIDs();
|
||||
subItems.insert(subItems.end(), metaSubItems.begin(), metaSubItems.end());
|
||||
return (uint32_t) metaSubItems.size();
|
||||
}
|
||||
|
|
|
@ -217,8 +217,9 @@ namespace render {
|
|||
}
|
||||
template <> uint32_t metaFetchMetaSubItems(const RenderableModelEntityItemMeta::Pointer& payload, ItemIDs& subItems) {
|
||||
auto modelEntity = std::static_pointer_cast<RenderableModelEntityItem>(payload->entity);
|
||||
if (modelEntity->hasModel()) {
|
||||
auto metaSubItems = modelEntity->getModelNotSafe()->fetchRenderItemIDs();
|
||||
auto model = modelEntity->getModelNotSafe();
|
||||
if (modelEntity->hasModel() && model) {
|
||||
auto& metaSubItems = model->fetchRenderItemIDs();
|
||||
subItems.insert(subItems.end(), metaSubItems.begin(), metaSubItems.end());
|
||||
return (uint32_t) metaSubItems.size();
|
||||
}
|
||||
|
@ -489,6 +490,17 @@ ModelPointer RenderableModelEntityItem::getModelNotSafe() {
|
|||
return _model;
|
||||
}
|
||||
|
||||
void RenderableModelEntityItem::setModelURLFinished(bool success) {
|
||||
if (success) {
|
||||
const render::ScenePointer& scene = AbstractViewStateInterface::instance()->getMain3DScene();
|
||||
render::Transaction transaction;
|
||||
|
||||
const auto& item = scene->getItem(_myMetaItem);
|
||||
transaction.transitionItem(_myMetaItem, render::Transition::ELEMENT_ENTER_LEAVE_DOMAIN);
|
||||
scene->enqueueTransaction(transaction);
|
||||
}
|
||||
}
|
||||
|
||||
ModelPointer RenderableModelEntityItem::getModel() {
|
||||
// make sure our renderer is setup
|
||||
if (!_myRenderer) {
|
||||
|
@ -506,6 +518,7 @@ ModelPointer RenderableModelEntityItem::getModel() {
|
|||
// If we don't have a model, allocate one *immediately*
|
||||
if (!_model) {
|
||||
_model = _myRenderer->allocateModel(getModelURL(), _myRenderer->getEntityLoadingPriority(*this), this);
|
||||
QObject::connect(_model.get(), &Model::setURLFinished, this, &RenderableModelEntityItem::setModelURLFinished);
|
||||
_needsInitialSimulation = true;
|
||||
// If we need to change URLs, update it *after rendering* (to avoid access violations)
|
||||
} else if (QUrl(getModelURL()) != _model->getURL()) {
|
||||
|
|
|
@ -12,16 +12,21 @@
|
|||
#ifndef hifi_RenderableModelEntityItem_h
|
||||
#define hifi_RenderableModelEntityItem_h
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
|
||||
#include <ModelEntityItem.h>
|
||||
#include <AnimationCache.h>
|
||||
#include <model-networking\ModelCache.h>
|
||||
|
||||
#include "RenderableEntityItem.h"
|
||||
|
||||
class Model;
|
||||
class EntityTreeRenderer;
|
||||
|
||||
class RenderableModelEntityItem : public ModelEntityItem, RenderableEntityInterface {
|
||||
class RenderableModelEntityItem : public QObject, public ModelEntityItem, RenderableEntityInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
|
@ -116,6 +121,10 @@ public:
|
|||
return _animation;
|
||||
}
|
||||
|
||||
public slots:
|
||||
|
||||
void setModelURLFinished(bool success);
|
||||
|
||||
private:
|
||||
QVariantMap parseTexturesToMap(QString textures);
|
||||
void remapTextures();
|
||||
|
|
|
@ -464,6 +464,7 @@ FadeJob::FadeJob()
|
|||
{
|
||||
auto texturePath = PathUtils::resourcesPath() + "images/fadeMask.png";
|
||||
_fadeMaskMap = DependencyManager::get<TextureCache>()->getImageTexture(texturePath, image::TextureUsage::STRICT_TEXTURE);
|
||||
_previousTime = usecTimestampNow();
|
||||
}
|
||||
|
||||
void FadeJob::configure(const Config& config) {
|
||||
|
@ -493,76 +494,91 @@ void FadeJob::run(const render::RenderContextPointer& renderContext) {
|
|||
auto transitionStage = scene->getStage<render::TransitionStage>(render::TransitionStage::getName());
|
||||
uint64_t now = usecTimestampNow();
|
||||
const double deltaTime = (int64_t(now) - int64_t(_previousTime)) / double(USECS_PER_SECOND);
|
||||
render::Transaction transaction;
|
||||
bool hasTransactions = false;
|
||||
|
||||
// And now update fade effect
|
||||
for (auto transitionId : *transitionStage) {
|
||||
auto& state = transitionStage->editTransition(transitionId);
|
||||
update(*jobConfig, scene, state, deltaTime);
|
||||
if (!update(*jobConfig, scene, state, deltaTime)) {
|
||||
// Remove transition for this item
|
||||
transaction.transitionItem(state.itemId, render::Transition::NONE);
|
||||
hasTransactions = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasTransactions) {
|
||||
scene->enqueueTransaction(transaction);
|
||||
}
|
||||
_previousTime = now;
|
||||
}
|
||||
|
||||
void FadeJob::update(const Config& config, const render::ScenePointer& scene, render::Transition& transition, const double deltaTime) const {
|
||||
bool FadeJob::update(const Config& config, const render::ScenePointer& scene, render::Transition& transition, const double deltaTime) const {
|
||||
auto& eventConfig = config.events[transition.eventType];
|
||||
auto& item = scene->getItem(transition.itemId);
|
||||
auto& aabb = item.getBound();
|
||||
auto& dimensions = aabb.getDimensions();
|
||||
const double eventDuration = (double)eventConfig.duration;
|
||||
const FadeConfig::Timing timing = (FadeConfig::Timing) eventConfig.timing;
|
||||
bool continueTransition = true;
|
||||
|
||||
assert(timing < render::Transition::EVENT_CATEGORY_COUNT);
|
||||
if (item.exist()) {
|
||||
auto& aabb = item.getBound();
|
||||
auto& dimensions = aabb.getDimensions();
|
||||
|
||||
switch (transition.eventType) {
|
||||
case render::Transition::ELEMENT_ENTER_LEAVE_DOMAIN:
|
||||
transition.threshold = 1.f - computeElementEnterThreshold(transition.time, eventConfig.duration, timing);
|
||||
transition.threshold = (transition.threshold - 0.5f)*_thresholdScale[transition.eventType] + 0.5f;
|
||||
transition.noiseOffset = aabb.calcCenter();
|
||||
transition.baseOffset = transition.noiseOffset - dimensions.y;
|
||||
transition.baseInvSize.x = 1.f / dimensions.x;
|
||||
transition.baseInvSize.y = 1.f / dimensions.y;
|
||||
transition.baseInvSize.z = 1.f / dimensions.z;
|
||||
assert(timing < render::Transition::EVENT_CATEGORY_COUNT);
|
||||
|
||||
switch (transition.eventType) {
|
||||
case render::Transition::ELEMENT_ENTER_LEAVE_DOMAIN:
|
||||
transition.threshold = 1.f - computeElementEnterRatio(transition.time, eventConfig.duration, timing);
|
||||
transition.threshold = (transition.threshold - 0.5f)*_thresholdScale[transition.eventType] + 0.5f;
|
||||
transition.noiseOffset = aabb.calcCenter();
|
||||
transition.baseOffset = transition.noiseOffset - dimensions.y;
|
||||
transition.baseInvSize.x = 1.f / dimensions.x;
|
||||
transition.baseInvSize.y = 1.f / dimensions.y;
|
||||
transition.baseInvSize.z = 1.f / dimensions.z;
|
||||
continueTransition = transition.threshold > 0.f;
|
||||
break;
|
||||
|
||||
case render::Transition::BUBBLE_ISECT_OWNER:
|
||||
{
|
||||
/* const glm::vec3 cameraPos = renderContext->args->getViewFrustum().getPosition();
|
||||
glm::vec3 delta = itemBounds.bound.calcCenter() - cameraPos;
|
||||
float distance = glm::length(delta);
|
||||
|
||||
delta = glm::normalize(delta) * std::max(0.f, distance - 0.5f);
|
||||
|
||||
_editBaseOffset = cameraPos + delta*_editThreshold;
|
||||
_editThreshold = 0.33f;*/
|
||||
}
|
||||
break;
|
||||
|
||||
case render::Transition::BUBBLE_ISECT_OWNER:
|
||||
{
|
||||
/* const glm::vec3 cameraPos = renderContext->args->getViewFrustum().getPosition();
|
||||
glm::vec3 delta = itemBounds.bound.calcCenter() - cameraPos;
|
||||
float distance = glm::length(delta);
|
||||
|
||||
delta = glm::normalize(delta) * std::max(0.f, distance - 0.5f);
|
||||
|
||||
_editBaseOffset = cameraPos + delta*_editThreshold;
|
||||
_editThreshold = 0.33f;*/
|
||||
}
|
||||
break;
|
||||
|
||||
case render::Transition::BUBBLE_ISECT_TRESPASSER:
|
||||
{
|
||||
// _editBaseOffset = glm::vec3{ 0.f, 0.f, 0.f };
|
||||
}
|
||||
break;
|
||||
|
||||
case render::Transition::USER_ENTER_LEAVE_DOMAIN:
|
||||
{
|
||||
/* _editBaseOffset = itemBounds.bound.calcCenter();
|
||||
_editBaseOffset.y -= itemBounds.bound.getDimensions().y / 2.f;*/
|
||||
}
|
||||
break;
|
||||
|
||||
case render::Transition::AVATAR_CHANGE:
|
||||
case render::Transition::BUBBLE_ISECT_TRESPASSER:
|
||||
{
|
||||
// _editBaseOffset = glm::vec3{ 0.f, 0.f, 0.f };
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
case render::Transition::USER_ENTER_LEAVE_DOMAIN:
|
||||
{
|
||||
/* _editBaseOffset = itemBounds.bound.calcCenter();
|
||||
_editBaseOffset.y -= itemBounds.bound.getDimensions().y / 2.f;*/
|
||||
}
|
||||
break;
|
||||
|
||||
case render::Transition::AVATAR_CHANGE:
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
transition.time += deltaTime;
|
||||
|
||||
// renderContext->jobConfig->setProperty("threshold", threshold);
|
||||
return continueTransition;
|
||||
}
|
||||
|
||||
float FadeJob::computeElementEnterThreshold(double time, const double period, FadeConfig::Timing timing) const {
|
||||
float FadeJob::computeElementEnterRatio(double time, const double period, FadeConfig::Timing timing) {
|
||||
assert(period > 0.0);
|
||||
float fadeAlpha = 1.0f;
|
||||
const double INV_FADE_PERIOD = 1.0 / period;
|
||||
|
|
|
@ -193,8 +193,8 @@ private:
|
|||
float _thresholdScale[render::Transition::EVENT_CATEGORY_COUNT];
|
||||
uint64_t _previousTime{ 0 };
|
||||
|
||||
void update(const Config& config, const render::ScenePointer& scene, render::Transition& transition, const double deltaTime) const;
|
||||
float computeElementEnterThreshold(double time, const double period, FadeConfig::Timing timing) const;
|
||||
bool update(const Config& config, const render::ScenePointer& scene, render::Transition& transition, const double deltaTime) const;
|
||||
static float computeElementEnterRatio(double time, const double period, FadeConfig::Timing timing);
|
||||
|
||||
const render::Item* findNearestItem(const render::RenderContextPointer& renderContext, const render::Varying& input, float& minIsectDistance) const;
|
||||
};
|
||||
|
|
|
@ -104,7 +104,8 @@ void initDeferredPipelines(ShapePlumber& plumber, const render::ShapePipeline::B
|
|||
void initForwardPipelines(ShapePlumber& plumber);
|
||||
|
||||
void addPlumberPipeline(ShapePlumber& plumber,
|
||||
const ShapeKey& key, const gpu::ShaderPointer& vertex, const gpu::ShaderPointer& pixel);
|
||||
const ShapeKey& key, const gpu::ShaderPointer& vertex, const gpu::ShaderPointer& pixel,
|
||||
const render::ShapePipeline::BatchSetter& batchSetter, const render::ShapePipeline::ItemSetter& itemSetter);
|
||||
|
||||
void batchSetter(const ShapePipeline& pipeline, gpu::Batch& batch, RenderArgs* args);
|
||||
void lightBatchSetter(const ShapePipeline& pipeline, gpu::Batch& batch, RenderArgs* args);
|
||||
|
@ -228,30 +229,30 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip
|
|||
auto simpleTranslucentUnlitFadePixel = gpu::Shader::createPixel(std::string(simple_transparent_textured_unlit_fade_frag));
|
||||
|
||||
using Key = render::ShapeKey;
|
||||
auto addPipeline = std::bind(&addPlumberPipeline, std::ref(plumber), _1, _2, _3);
|
||||
auto addPipeline = std::bind(&addPlumberPipeline, std::ref(plumber), _1, _2, _3, _4, _5);
|
||||
// TODO: Refactor this to use a filter
|
||||
// Opaques
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial(),
|
||||
modelVertex, modelPixel);
|
||||
modelVertex, modelPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder(),
|
||||
simpleVertex, simplePixel);
|
||||
simpleVertex, simplePixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withUnlit(),
|
||||
modelVertex, modelUnlitPixel);
|
||||
modelVertex, modelUnlitPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withUnlit(),
|
||||
simpleVertex, simpleUnlitPixel);
|
||||
simpleVertex, simpleUnlitPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTangents(),
|
||||
modelNormalMapVertex, modelNormalMapPixel);
|
||||
modelNormalMapVertex, modelNormalMapPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSpecular(),
|
||||
modelVertex, modelSpecularMapPixel);
|
||||
modelVertex, modelSpecularMapPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTangents().withSpecular(),
|
||||
modelNormalMapVertex, modelNormalSpecularMapPixel);
|
||||
modelNormalMapVertex, modelNormalSpecularMapPixel, nullptr, nullptr);
|
||||
// Same thing but with Fade on
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withFade(),
|
||||
|
@ -278,29 +279,29 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip
|
|||
// Translucents
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTranslucent(),
|
||||
modelVertex, modelTranslucentPixel);
|
||||
modelVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withTranslucent(),
|
||||
simpleVertex, simpleTranslucentPixel);
|
||||
simpleVertex, simpleTranslucentPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTranslucent().withUnlit(),
|
||||
modelVertex, modelTranslucentUnlitPixel);
|
||||
modelVertex, modelTranslucentUnlitPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withTranslucent().withUnlit(),
|
||||
simpleVertex, simpleTranslucentUnlitPixel);
|
||||
simpleVertex, simpleTranslucentUnlitPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTranslucent().withTangents(),
|
||||
modelNormalMapVertex, modelTranslucentPixel);
|
||||
modelNormalMapVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTranslucent().withSpecular(),
|
||||
modelVertex, modelTranslucentPixel);
|
||||
modelVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTranslucent().withTangents().withSpecular(),
|
||||
modelNormalMapVertex, modelTranslucentPixel);
|
||||
modelNormalMapVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
// FIXME: Ignore lightmap for translucents meshpart
|
||||
Key::Builder().withMaterial().withTranslucent().withLightmap(),
|
||||
modelVertex, modelTranslucentPixel);
|
||||
modelVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
// Same thing but with Fade on
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withTranslucent().withFade(),
|
||||
|
@ -331,16 +332,16 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip
|
|||
// Lightmapped
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withLightmap(),
|
||||
modelLightmapVertex, modelLightmapPixel);
|
||||
modelLightmapVertex, modelLightmapPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withLightmap().withTangents(),
|
||||
modelLightmapNormalMapVertex, modelLightmapNormalMapPixel);
|
||||
modelLightmapNormalMapVertex, modelLightmapNormalMapPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withLightmap().withSpecular(),
|
||||
modelLightmapVertex, modelLightmapSpecularMapPixel);
|
||||
modelLightmapVertex, modelLightmapSpecularMapPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withLightmap().withTangents().withSpecular(),
|
||||
modelLightmapNormalMapVertex, modelLightmapNormalSpecularMapPixel);
|
||||
modelLightmapNormalMapVertex, modelLightmapNormalSpecularMapPixel, nullptr, nullptr);
|
||||
// Same thing but with Fade on
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withLightmap().withFade(),
|
||||
|
@ -358,16 +359,16 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip
|
|||
// Skinned
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned(),
|
||||
skinModelVertex, modelPixel);
|
||||
skinModelVertex, modelPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTangents(),
|
||||
skinModelNormalMapVertex, modelNormalMapPixel);
|
||||
skinModelNormalMapVertex, modelNormalMapPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withSpecular(),
|
||||
skinModelVertex, modelSpecularMapPixel);
|
||||
skinModelVertex, modelSpecularMapPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTangents().withSpecular(),
|
||||
skinModelNormalMapVertex, modelNormalSpecularMapPixel);
|
||||
skinModelNormalMapVertex, modelNormalSpecularMapPixel, nullptr, nullptr);
|
||||
// Same thing but with Fade on
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withFade(),
|
||||
|
@ -385,16 +386,16 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip
|
|||
// Skinned and Translucent
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTranslucent(),
|
||||
skinModelVertex, modelTranslucentPixel);
|
||||
skinModelVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTranslucent().withTangents(),
|
||||
skinModelNormalMapVertex, modelTranslucentPixel);
|
||||
skinModelNormalMapVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTranslucent().withSpecular(),
|
||||
skinModelVertex, modelTranslucentPixel);
|
||||
skinModelVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTranslucent().withTangents().withSpecular(),
|
||||
skinModelNormalMapVertex, modelTranslucentPixel);
|
||||
skinModelNormalMapVertex, modelTranslucentPixel, nullptr, nullptr);
|
||||
// Same thing but with Fade on
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial().withSkinned().withTranslucent().withFade(),
|
||||
|
@ -412,10 +413,10 @@ void initDeferredPipelines(render::ShapePlumber& plumber, const render::ShapePip
|
|||
// Depth-only
|
||||
addPipeline(
|
||||
Key::Builder().withDepthOnly(),
|
||||
modelShadowVertex, modelShadowPixel);
|
||||
modelShadowVertex, modelShadowPixel, nullptr, nullptr);
|
||||
addPipeline(
|
||||
Key::Builder().withSkinned().withDepthOnly(),
|
||||
skinModelShadowVertex, modelShadowPixel);
|
||||
skinModelShadowVertex, modelShadowPixel, nullptr, nullptr);
|
||||
// Same thing but with Fade on
|
||||
addPipeline(
|
||||
Key::Builder().withDepthOnly().withFade(),
|
||||
|
@ -440,7 +441,7 @@ void initForwardPipelines(render::ShapePlumber& plumber) {
|
|||
auto modelNormalSpecularMapPixel = gpu::Shader::createPixel(std::string(forward_model_normal_specular_map_frag));
|
||||
|
||||
using Key = render::ShapeKey;
|
||||
auto addPipeline = std::bind(&addPlumberPipeline, std::ref(plumber), _1, _2, _3);
|
||||
auto addPipeline = std::bind(&addPlumberPipeline, std::ref(plumber), _1, _2, _3, nullptr, nullptr);
|
||||
// Opaques
|
||||
addPipeline(
|
||||
Key::Builder().withMaterial(),
|
||||
|
@ -473,7 +474,8 @@ void initForwardPipelines(render::ShapePlumber& plumber) {
|
|||
}
|
||||
|
||||
void addPlumberPipeline(ShapePlumber& plumber,
|
||||
const ShapeKey& key, const gpu::ShaderPointer& vertex, const gpu::ShaderPointer& pixel) {
|
||||
const ShapeKey& key, const gpu::ShaderPointer& vertex, const gpu::ShaderPointer& pixel,
|
||||
const render::ShapePipeline::BatchSetter& extraBatchSetter, const render::ShapePipeline::ItemSetter& itemSetter) {
|
||||
// These key-values' pipelines are added by this functor in addition to the key passed
|
||||
assert(!key.isWireframe());
|
||||
assert(!key.isDepthBiased());
|
||||
|
@ -510,8 +512,18 @@ void addPlumberPipeline(ShapePlumber& plumber,
|
|||
state->setDepthBiasSlopeScale(1.0f);
|
||||
}
|
||||
|
||||
plumber.addPipeline(builder.build(), program, state,
|
||||
key.isTranslucent() ? &lightBatchSetter : &batchSetter);
|
||||
auto baseBatchSetter = key.isTranslucent() ? &lightBatchSetter : &batchSetter;
|
||||
render::ShapePipeline::BatchSetter finalBatchSetter;
|
||||
if (extraBatchSetter) {
|
||||
finalBatchSetter = [baseBatchSetter, extraBatchSetter](const ShapePipeline& pipeline, gpu::Batch& batch, render::Args* args) {
|
||||
baseBatchSetter(pipeline, batch, args);
|
||||
extraBatchSetter(pipeline, batch, args);
|
||||
};
|
||||
}
|
||||
else {
|
||||
finalBatchSetter = baseBatchSetter;
|
||||
}
|
||||
plumber.addPipeline(builder.build(), program, state, finalBatchSetter, itemSetter);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <numeric>
|
||||
#include <gpu/Batch.h>
|
||||
#include "Logging.h"
|
||||
#include "TransitionStage.h"
|
||||
|
||||
using namespace render;
|
||||
|
||||
|
@ -30,6 +31,11 @@ void Transaction::removeItem(ItemID id) {
|
|||
_removedItems.emplace_back(id);
|
||||
}
|
||||
|
||||
void Transaction::transitionItem(ItemID id, Transition::Type transition) {
|
||||
_transitioningItems.emplace_back(id);
|
||||
_transitionTypes.emplace_back(transition);
|
||||
}
|
||||
|
||||
void Transaction::updateItem(ItemID id, const UpdateFunctorPointer& functor) {
|
||||
_updatedItems.emplace_back(id);
|
||||
_updateFunctors.emplace_back(functor);
|
||||
|
@ -46,6 +52,8 @@ void Transaction::merge(const Transaction& transaction) {
|
|||
_updatedItems.insert(_updatedItems.end(), transaction._updatedItems.begin(), transaction._updatedItems.end());
|
||||
_updateFunctors.insert(_updateFunctors.end(), transaction._updateFunctors.begin(), transaction._updateFunctors.end());
|
||||
_resetSelections.insert(_resetSelections.end(), transaction._resetSelections.begin(), transaction._resetSelections.end());
|
||||
_transitioningItems.insert(_transitioningItems.end(), transaction._transitioningItems.begin(), transaction._transitioningItems.end());
|
||||
_transitionTypes.insert(_transitionTypes.end(), transaction._transitionTypes.begin(), transaction._transitionTypes.end());
|
||||
}
|
||||
|
||||
|
||||
|
@ -115,6 +123,9 @@ void Scene::processTransactionQueue() {
|
|||
// removes
|
||||
removeItems(consolidatedTransaction._removedItems);
|
||||
|
||||
// Transitions
|
||||
transitionItems(consolidatedTransaction._transitioningItems, consolidatedTransaction._transitionTypes);
|
||||
|
||||
// Update the numItemsAtomic counter AFTER the pending changes went through
|
||||
_numAllocatedItems.exchange(maxID);
|
||||
}
|
||||
|
@ -216,6 +227,67 @@ void Scene::updateItems(const ItemIDs& ids, UpdateFunctors& functors) {
|
|||
}
|
||||
}
|
||||
|
||||
void Scene::transitionItems(const ItemIDs& ids, const TransitionTypes& types) {
|
||||
auto transitionType = types.begin();
|
||||
auto transitionStage = getStage<TransitionStage>(TransitionStage::getName());
|
||||
|
||||
for (auto itemId : ids) {
|
||||
auto transitionId = INVALID_INDEX;
|
||||
|
||||
if (*transitionType != Transition::NONE) {
|
||||
transitionId = transitionStage->addTransition(itemId, *transitionType);
|
||||
}
|
||||
|
||||
setItemTransition(itemId, transitionId);
|
||||
// next loop
|
||||
transitionType++;
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::collectSubItems(ItemID parentId, ItemIDs& subItems) const {
|
||||
// Access the true item
|
||||
auto& item = _items[parentId];
|
||||
|
||||
if (item.exist()) {
|
||||
// Recursivelly collect the subitems
|
||||
auto subItemBeginIndex = subItems.size();
|
||||
auto subItemCount = item.fetchMetaSubItems(subItems);
|
||||
for (auto i = subItemBeginIndex; i < (subItemBeginIndex + subItemCount); i++) {
|
||||
collectSubItems(subItems[i], subItems);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::setItemTransition(ItemID itemId, Index transitionId) {
|
||||
// Access the true item
|
||||
auto& item = _items[itemId];
|
||||
|
||||
if (item.exist()) {
|
||||
ItemIDs subItems;
|
||||
|
||||
item.setTransitionId(transitionId);
|
||||
|
||||
// Sub-items share the same transition Id
|
||||
collectSubItems(itemId, subItems);
|
||||
for (auto subItemId : subItems) {
|
||||
auto& subItem = _items[subItemId];
|
||||
subItem.setTransitionId(transitionId);
|
||||
}
|
||||
}
|
||||
else {
|
||||
qWarning() << "Collecting sub items on item without payload";
|
||||
}
|
||||
}
|
||||
|
||||
void Scene::resetItemTransition(ItemID itemId) {
|
||||
// Access the true item
|
||||
auto& item = _items[itemId];
|
||||
auto transitionStage = getStage<TransitionStage>(TransitionStage::getName());
|
||||
|
||||
transitionStage->removeTransition(item.getTransitionId());
|
||||
setItemTransition(itemId, Transition::NONE);
|
||||
}
|
||||
|
||||
// THis fucntion is thread safe
|
||||
Selection Scene::getSelection(const Selection::Name& name) const {
|
||||
std::unique_lock<std::mutex> lock(_selectionsMutex);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "SpatialTree.h"
|
||||
#include "Stage.h"
|
||||
#include "Selection.h"
|
||||
#include "Transition.h"
|
||||
|
||||
namespace render {
|
||||
|
||||
|
@ -39,6 +40,8 @@ public:
|
|||
void resetItem(ItemID id, const PayloadPointer& payload);
|
||||
void removeItem(ItemID id);
|
||||
|
||||
void transitionItem(ItemID id, Transition::Type transition);
|
||||
|
||||
template <class T> void updateItem(ItemID id, std::function<void(T&)> func) {
|
||||
updateItem(id, std::make_shared<UpdateFunctor<T>>(func));
|
||||
}
|
||||
|
@ -54,10 +57,12 @@ public:
|
|||
// Checkers if there is work to do when processing the transaction
|
||||
bool touchTransactions() const { return !_resetSelections.empty(); }
|
||||
|
||||
ItemIDs _resetItems;
|
||||
ItemIDs _resetItems;
|
||||
Payloads _resetPayloads;
|
||||
ItemIDs _removedItems;
|
||||
ItemIDs _updatedItems;
|
||||
ItemIDs _transitioningItems;
|
||||
TransitionTypes _transitionTypes;
|
||||
UpdateFunctors _updateFunctors;
|
||||
|
||||
Selections _resetSelections;
|
||||
|
@ -123,6 +128,8 @@ public:
|
|||
}
|
||||
void resetStage(const Stage::Name& name, const StagePointer& stage);
|
||||
|
||||
void setItemTransition(ItemID id, Index transitionId);
|
||||
void resetItemTransition(ItemID id);
|
||||
|
||||
protected:
|
||||
// Thread safe elements that can be accessed from anywhere
|
||||
|
@ -141,6 +148,9 @@ protected:
|
|||
void resetItems(const ItemIDs& ids, Payloads& payloads);
|
||||
void removeItems(const ItemIDs& ids);
|
||||
void updateItems(const ItemIDs& ids, UpdateFunctors& functors);
|
||||
void transitionItems(const ItemIDs& ids, const TransitionTypes& types);
|
||||
|
||||
void collectSubItems(ItemID parentId, ItemIDs& subItems) const;
|
||||
|
||||
// The Selection map
|
||||
mutable std::mutex _selectionsMutex; // mutable so it can be used in the thread safe getSelection const method
|
||||
|
|
|
@ -27,7 +27,8 @@ namespace render {
|
|||
AVATAR_CHANGE,
|
||||
|
||||
// Don't forget to modify Fade.slh to reflect the change in number of categories
|
||||
EVENT_CATEGORY_COUNT
|
||||
EVENT_CATEGORY_COUNT,
|
||||
NONE = EVENT_CATEGORY_COUNT
|
||||
};
|
||||
|
||||
Type eventType{ ELEMENT_ENTER_LEAVE_DOMAIN };
|
||||
|
@ -41,6 +42,7 @@ namespace render {
|
|||
};
|
||||
|
||||
typedef std::shared_ptr<Transition> TransitionPointer;
|
||||
typedef std::vector<Transition::Type> TransitionTypes;
|
||||
}
|
||||
|
||||
#endif // hifi_render_Transition_h
|
Loading…
Reference in a new issue