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