mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Adding support for the meta rendering
This commit is contained in:
parent
95aad3140d
commit
83d1c3ad01
15 changed files with 156 additions and 60 deletions
|
@ -62,7 +62,7 @@ const glm::vec3 HAND_TO_PALM_OFFSET(0.0f, 0.12f, 0.08f);
|
||||||
|
|
||||||
namespace render {
|
namespace render {
|
||||||
template <> const ItemKey payloadGetKey(const AvatarSharedPointer& avatar) {
|
template <> const ItemKey payloadGetKey(const AvatarSharedPointer& avatar) {
|
||||||
return ItemKey::Builder::opaqueShape();
|
return ItemKey::Builder::opaqueShape().withTypeMeta();
|
||||||
}
|
}
|
||||||
template <> const Item::Bound payloadGetBound(const AvatarSharedPointer& avatar) {
|
template <> const Item::Bound payloadGetBound(const AvatarSharedPointer& avatar) {
|
||||||
return static_pointer_cast<Avatar>(avatar)->getBounds();
|
return static_pointer_cast<Avatar>(avatar)->getBounds();
|
||||||
|
@ -74,6 +74,15 @@ namespace render {
|
||||||
avatarPtr->render(args, qApp->getCamera()->getPosition());
|
avatarPtr->render(args, qApp->getCamera()->getPosition());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
template <> uint32_t metaFetchMetaSubItems(const AvatarSharedPointer& avatar, ItemIDs& subItems) {
|
||||||
|
auto avatarPtr = static_pointer_cast<Avatar>(avatar);
|
||||||
|
if (avatarPtr->getSkeletonModel()) {
|
||||||
|
auto metaSubItems = avatarPtr->getSkeletonModel()->fetchRenderItemIDs();
|
||||||
|
subItems.insert(subItems.end(), metaSubItems.begin(), metaSubItems.end());
|
||||||
|
return metaSubItems.size();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint64_t timeProcessingJoints = 0;
|
static uint64_t timeProcessingJoints = 0;
|
||||||
|
|
|
@ -32,6 +32,7 @@ namespace render {
|
||||||
template <> const ItemKey payloadGetKey(const AvatarSharedPointer& avatar);
|
template <> const ItemKey payloadGetKey(const AvatarSharedPointer& avatar);
|
||||||
template <> const Item::Bound payloadGetBound(const AvatarSharedPointer& avatar);
|
template <> const Item::Bound payloadGetBound(const AvatarSharedPointer& avatar);
|
||||||
template <> void payloadRender(const AvatarSharedPointer& avatar, RenderArgs* args);
|
template <> void payloadRender(const AvatarSharedPointer& avatar, RenderArgs* args);
|
||||||
|
template <> uint32_t metaFetchMetaSubItems(const AvatarSharedPointer& avatar, ItemIDs& subItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const float SCALING_RATIO = .05f;
|
static const float SCALING_RATIO = .05f;
|
||||||
|
|
|
@ -15,21 +15,21 @@
|
||||||
|
|
||||||
namespace render {
|
namespace render {
|
||||||
template <> const ItemKey payloadGetKey(const RenderableEntityItemProxy::Pointer& payload) {
|
template <> const ItemKey payloadGetKey(const RenderableEntityItemProxy::Pointer& payload) {
|
||||||
if (payload && payload->entity) {
|
if (payload && payload->_entity) {
|
||||||
if (payload->entity->getType() == EntityTypes::Light) {
|
if (payload->_entity->getType() == EntityTypes::Light) {
|
||||||
return ItemKey::Builder::light();
|
return ItemKey::Builder::light().withTypeMeta();
|
||||||
}
|
}
|
||||||
if (payload && payload->entity->isTransparent()) {
|
if (payload && payload->_entity->isTransparent()) {
|
||||||
return ItemKey::Builder::transparentShape();
|
return ItemKey::Builder::transparentShape().withTypeMeta();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ItemKey::Builder::opaqueShape();
|
return ItemKey::Builder::opaqueShape().withTypeMeta();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> const Item::Bound payloadGetBound(const RenderableEntityItemProxy::Pointer& payload) {
|
template <> const Item::Bound payloadGetBound(const RenderableEntityItemProxy::Pointer& payload) {
|
||||||
if (payload && payload->entity) {
|
if (payload && payload->_entity) {
|
||||||
bool success;
|
bool success;
|
||||||
auto result = payload->entity->getAABox(success);
|
auto result = payload->_entity->getAABox(success);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
return render::Item::Bound();
|
return render::Item::Bound();
|
||||||
}
|
}
|
||||||
|
@ -39,11 +39,19 @@ namespace render {
|
||||||
}
|
}
|
||||||
template <> void payloadRender(const RenderableEntityItemProxy::Pointer& payload, RenderArgs* args) {
|
template <> void payloadRender(const RenderableEntityItemProxy::Pointer& payload, RenderArgs* args) {
|
||||||
if (args) {
|
if (args) {
|
||||||
if (payload && payload->entity && payload->entity->getVisible()) {
|
if (payload && payload->_entity && payload->_entity->getVisible()) {
|
||||||
payload->entity->render(args);
|
payload->_entity->render(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
template <> uint32_t metaFetchMetaSubItems(const RenderableEntityItemProxy::Pointer& payload, ItemIDs& subItems) {
|
||||||
|
auto metaID = payload->_metaID;
|
||||||
|
if (Item::isValidID(metaID)) {
|
||||||
|
subItems.emplace_back(metaID);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeEntityItemStatusGetters(EntityItemPointer entity, render::Item::Status::Getters& statusGetters) {
|
void makeEntityItemStatusGetters(EntityItemPointer entity, render::Item::Status::Getters& statusGetters) {
|
||||||
|
|
|
@ -36,17 +36,19 @@ void makeEntityItemStatusGetters(EntityItemPointer entity, render::Item::Status:
|
||||||
|
|
||||||
class RenderableEntityItemProxy {
|
class RenderableEntityItemProxy {
|
||||||
public:
|
public:
|
||||||
RenderableEntityItemProxy(EntityItemPointer entity) : entity(entity) { }
|
RenderableEntityItemProxy(EntityItemPointer entity, render::ItemID metaID) : _entity(entity), _metaID(metaID) { }
|
||||||
typedef render::Payload<RenderableEntityItemProxy> Payload;
|
typedef render::Payload<RenderableEntityItemProxy> Payload;
|
||||||
typedef Payload::DataPointer Pointer;
|
typedef Payload::DataPointer Pointer;
|
||||||
|
|
||||||
EntityItemPointer entity;
|
EntityItemPointer _entity;
|
||||||
|
render::ItemID _metaID;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace render {
|
namespace render {
|
||||||
template <> const ItemKey payloadGetKey(const RenderableEntityItemProxy::Pointer& payload);
|
template <> const ItemKey payloadGetKey(const RenderableEntityItemProxy::Pointer& payload);
|
||||||
template <> const Item::Bound payloadGetBound(const RenderableEntityItemProxy::Pointer& payload);
|
template <> const Item::Bound payloadGetBound(const RenderableEntityItemProxy::Pointer& payload);
|
||||||
template <> void payloadRender(const RenderableEntityItemProxy::Pointer& payload, RenderArgs* args);
|
template <> void payloadRender(const RenderableEntityItemProxy::Pointer& payload, RenderArgs* args);
|
||||||
|
template <> uint32_t metaFetchMetaSubItems(const RenderableEntityItemProxy::Pointer& payload, ItemIDs& subItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mixin class for implementing basic single item rendering
|
// Mixin class for implementing basic single item rendering
|
||||||
|
@ -55,7 +57,7 @@ public:
|
||||||
bool addToScene(EntityItemPointer self, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges) {
|
bool addToScene(EntityItemPointer self, std::shared_ptr<render::Scene> scene, render::PendingChanges& pendingChanges) {
|
||||||
_myItem = scene->allocateID();
|
_myItem = scene->allocateID();
|
||||||
|
|
||||||
auto renderData = std::make_shared<RenderableEntityItemProxy>(self);
|
auto renderData = std::make_shared<RenderableEntityItemProxy>(self, _myItem);
|
||||||
auto renderPayload = std::make_shared<RenderableEntityItemProxy::Payload>(renderData);
|
auto renderPayload = std::make_shared<RenderableEntityItemProxy::Payload>(renderData);
|
||||||
|
|
||||||
render::Item::Status::Getters statusGetters;
|
render::Item::Status::Getters statusGetters;
|
||||||
|
|
|
@ -194,7 +194,7 @@ public:
|
||||||
|
|
||||||
namespace render {
|
namespace render {
|
||||||
template <> const ItemKey payloadGetKey(const RenderableModelEntityItemMeta::Pointer& payload) {
|
template <> const ItemKey payloadGetKey(const RenderableModelEntityItemMeta::Pointer& payload) {
|
||||||
return ItemKey::Builder::opaqueShape();
|
return ItemKey::Builder::opaqueShape().withTypeMeta();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> const Item::Bound payloadGetBound(const RenderableModelEntityItemMeta::Pointer& payload) {
|
template <> const Item::Bound payloadGetBound(const RenderableModelEntityItemMeta::Pointer& payload) {
|
||||||
|
@ -216,6 +216,15 @@ 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();
|
||||||
|
subItems.insert(subItems.end(), metaSubItems.begin(), metaSubItems.end());
|
||||||
|
return (uint32_t) metaSubItems.size();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderableModelEntityItem::addToScene(EntityItemPointer self, std::shared_ptr<render::Scene> scene,
|
bool RenderableModelEntityItem::addToScene(EntityItemPointer self, std::shared_ptr<render::Scene> scene,
|
||||||
|
@ -473,6 +482,10 @@ void RenderableModelEntityItem::render(RenderArgs* args) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ModelPointer RenderableModelEntityItem::getModelNotSafe() {
|
||||||
|
return _model;
|
||||||
|
}
|
||||||
|
|
||||||
ModelPointer RenderableModelEntityItem::getModel(QSharedPointer<EntityTreeRenderer> renderer) {
|
ModelPointer RenderableModelEntityItem::getModel(QSharedPointer<EntityTreeRenderer> renderer) {
|
||||||
if (!renderer) {
|
if (!renderer) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -52,6 +52,7 @@ public:
|
||||||
BoxFace& face, glm::vec3& surfaceNormal,
|
BoxFace& face, glm::vec3& surfaceNormal,
|
||||||
void** intersectedObject, bool precisionPicking) const override;
|
void** intersectedObject, bool precisionPicking) const override;
|
||||||
ModelPointer getModel(QSharedPointer<EntityTreeRenderer> renderer);
|
ModelPointer getModel(QSharedPointer<EntityTreeRenderer> renderer);
|
||||||
|
ModelPointer getModelNotSafe();
|
||||||
|
|
||||||
virtual bool needsToCallUpdate() const override;
|
virtual bool needsToCallUpdate() const override;
|
||||||
virtual void update(const quint64& now) override;
|
virtual void update(const quint64& now) override;
|
||||||
|
|
|
@ -673,6 +673,7 @@ bool Model::addToScene(std::shared_ptr<render::Scene> scene,
|
||||||
hasTransparent = hasTransparent || renderItem.get()->getShapeKey().isTranslucent();
|
hasTransparent = hasTransparent || renderItem.get()->getShapeKey().isTranslucent();
|
||||||
verticesCount += renderItem.get()->getVerticesCount();
|
verticesCount += renderItem.get()->getVerticesCount();
|
||||||
_modelMeshRenderItems.insert(item, renderPayload);
|
_modelMeshRenderItems.insert(item, renderPayload);
|
||||||
|
_modelMeshRenderItemIDs.emplace_back(item);
|
||||||
}
|
}
|
||||||
somethingAdded = !_modelMeshRenderItems.empty();
|
somethingAdded = !_modelMeshRenderItems.empty();
|
||||||
|
|
||||||
|
@ -695,6 +696,7 @@ void Model::removeFromScene(std::shared_ptr<render::Scene> scene, render::Pendin
|
||||||
foreach (auto item, _modelMeshRenderItems.keys()) {
|
foreach (auto item, _modelMeshRenderItems.keys()) {
|
||||||
pendingChanges.removeItem(item);
|
pendingChanges.removeItem(item);
|
||||||
}
|
}
|
||||||
|
_modelMeshRenderItemIDs.clear();
|
||||||
_modelMeshRenderItems.clear();
|
_modelMeshRenderItems.clear();
|
||||||
_modelMeshRenderItemsSet.clear();
|
_modelMeshRenderItemsSet.clear();
|
||||||
|
|
||||||
|
@ -1301,6 +1303,10 @@ AABox Model::getRenderableMeshBound() const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const render::ItemIDs& Model::fetchRenderItemIDs() const {
|
||||||
|
return _modelMeshRenderItemIDs;
|
||||||
|
}
|
||||||
|
|
||||||
void Model::createRenderItemSet() {
|
void Model::createRenderItemSet() {
|
||||||
if (_collisionGeometry) {
|
if (_collisionGeometry) {
|
||||||
if (_collisionRenderItemsSet.empty()) {
|
if (_collisionRenderItemsSet.empty()) {
|
||||||
|
@ -1479,6 +1485,7 @@ void ModelBlender::noteRequiresBlend(ModelPointer model) {
|
||||||
|
|
||||||
{
|
{
|
||||||
Lock lock(_mutex);
|
Lock lock(_mutex);
|
||||||
|
|
||||||
_modelsRequiringBlends.insert(model);
|
_modelsRequiringBlends.insert(model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -105,6 +105,7 @@ public:
|
||||||
void setRenderItemsNeedUpdate() { _renderItemsNeedUpdate = true; }
|
void setRenderItemsNeedUpdate() { _renderItemsNeedUpdate = true; }
|
||||||
bool getRenderItemsNeedUpdate() { return _renderItemsNeedUpdate; }
|
bool getRenderItemsNeedUpdate() { return _renderItemsNeedUpdate; }
|
||||||
AABox getRenderableMeshBound() const;
|
AABox getRenderableMeshBound() const;
|
||||||
|
const render::ItemIDs& fetchRenderItemIDs() const;
|
||||||
|
|
||||||
bool maybeStartBlender();
|
bool maybeStartBlender();
|
||||||
|
|
||||||
|
@ -389,6 +390,8 @@ protected:
|
||||||
QSet<std::shared_ptr<ModelMeshPartPayload>> _modelMeshRenderItemsSet;
|
QSet<std::shared_ptr<ModelMeshPartPayload>> _modelMeshRenderItemsSet;
|
||||||
QMap<render::ItemID, render::PayloadPointer> _modelMeshRenderItems;
|
QMap<render::ItemID, render::PayloadPointer> _modelMeshRenderItems;
|
||||||
|
|
||||||
|
render::ItemIDs _modelMeshRenderItemIDs;
|
||||||
|
|
||||||
bool _addedToScene { false }; // has been added to scene
|
bool _addedToScene { false }; // has been added to scene
|
||||||
bool _needsFixupInScene { true }; // needs to be removed/re-added to scene
|
bool _needsFixupInScene { true }; // needs to be removed/re-added to scene
|
||||||
bool _needsReload { true };
|
bool _needsReload { true };
|
||||||
|
|
|
@ -53,14 +53,15 @@ RenderDeferredTask::RenderDeferredTask(RenderFetchCullSortTask::Output items) {
|
||||||
ShapePlumberPointer shapePlumber = std::make_shared<ShapePlumber>();
|
ShapePlumberPointer shapePlumber = std::make_shared<ShapePlumber>();
|
||||||
initDeferredPipelines(*shapePlumber);
|
initDeferredPipelines(*shapePlumber);
|
||||||
|
|
||||||
// Extract opaques / transparents / lights / overlays
|
// Extract opaques / transparents / lights / metas / overlays / background
|
||||||
const auto opaques = items[0];
|
const auto opaques = items[RenderFetchCullSortTask::OPAQUE_SHAPE];
|
||||||
const auto transparents = items[1];
|
const auto transparents = items[RenderFetchCullSortTask::TRANSPARENT_SHAPE];
|
||||||
const auto lights = items[2];
|
const auto lights = items[RenderFetchCullSortTask::LIGHT];
|
||||||
const auto overlayOpaques = items[3];
|
const auto metas = items[RenderFetchCullSortTask::META];
|
||||||
const auto overlayTransparents = items[4];
|
const auto overlayOpaques = items[RenderFetchCullSortTask::OVERLAY_OPAQUE_SHAPE];
|
||||||
const auto background = items[5];
|
const auto overlayTransparents = items[RenderFetchCullSortTask::OVERLAY_TRANSPARENT_SHAPE];
|
||||||
const auto spatialSelection = items[6];
|
const auto background = items[RenderFetchCullSortTask::BACKGROUND];
|
||||||
|
const auto spatialSelection = items[RenderFetchCullSortTask::SPATIAL_SELECTION];
|
||||||
|
|
||||||
// Prepare deferred, generate the shared Deferred Frame Transform
|
// Prepare deferred, generate the shared Deferred Frame Transform
|
||||||
const auto deferredFrameTransform = addJob<GenerateDeferredFrameTransform>("DeferredFrameTransform");
|
const auto deferredFrameTransform = addJob<GenerateDeferredFrameTransform>("DeferredFrameTransform");
|
||||||
|
|
|
@ -36,13 +36,15 @@ RenderForwardTask::RenderForwardTask(RenderFetchCullSortTask::Output items) {
|
||||||
ShapePlumberPointer shapePlumber = std::make_shared<ShapePlumber>();
|
ShapePlumberPointer shapePlumber = std::make_shared<ShapePlumber>();
|
||||||
initForwardPipelines(*shapePlumber);
|
initForwardPipelines(*shapePlumber);
|
||||||
|
|
||||||
// Extract opaques / transparents / lights / overlays
|
// Extract opaques / transparents / lights / metas / overlays / background
|
||||||
const auto opaques = items[0];
|
const auto opaques = items[RenderFetchCullSortTask::OPAQUE_SHAPE];
|
||||||
const auto transparents = items[1];
|
const auto transparents = items[RenderFetchCullSortTask::TRANSPARENT_SHAPE];
|
||||||
const auto lights = items[2];
|
const auto lights = items[RenderFetchCullSortTask::LIGHT];
|
||||||
const auto overlayOpaques = items[3];
|
const auto metas = items[RenderFetchCullSortTask::META];
|
||||||
const auto overlayTransparents = items[4];
|
const auto overlayOpaques = items[RenderFetchCullSortTask::OVERLAY_OPAQUE_SHAPE];
|
||||||
const auto background = items[5];
|
const auto overlayTransparents = items[RenderFetchCullSortTask::OVERLAY_TRANSPARENT_SHAPE];
|
||||||
|
const auto background = items[RenderFetchCullSortTask::BACKGROUND];
|
||||||
|
const auto spatialSelection = items[RenderFetchCullSortTask::SPATIAL_SELECTION];
|
||||||
|
|
||||||
const auto framebuffer = addJob<PrepareFramebuffer>("PrepareFramebuffer");
|
const auto framebuffer = addJob<PrepareFramebuffer>("PrepareFramebuffer");
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ public:
|
||||||
enum FlagBit {
|
enum FlagBit {
|
||||||
TYPE_SHAPE = 0, // Item is a Shape
|
TYPE_SHAPE = 0, // Item is a Shape
|
||||||
TYPE_LIGHT, // Item is a Light
|
TYPE_LIGHT, // Item is a Light
|
||||||
|
TYPE_META, // Item is a Meta: meanning it s used to represent a higher level object, potentially represented by other render items
|
||||||
TRANSLUCENT, // Transparent and not opaque, for some odd reason TRANSPARENCY doesn't work...
|
TRANSLUCENT, // Transparent and not opaque, for some odd reason TRANSPARENCY doesn't work...
|
||||||
VIEW_SPACE, // Transformed in view space, and not in world space
|
VIEW_SPACE, // Transformed in view space, and not in world space
|
||||||
DYNAMIC, // Dynamic and bound will change unlike static item
|
DYNAMIC, // Dynamic and bound will change unlike static item
|
||||||
|
@ -72,6 +73,7 @@ public:
|
||||||
|
|
||||||
Builder& withTypeShape() { _flags.set(TYPE_SHAPE); return (*this); }
|
Builder& withTypeShape() { _flags.set(TYPE_SHAPE); return (*this); }
|
||||||
Builder& withTypeLight() { _flags.set(TYPE_LIGHT); return (*this); }
|
Builder& withTypeLight() { _flags.set(TYPE_LIGHT); return (*this); }
|
||||||
|
Builder& withTypeMeta() { _flags.set(TYPE_META); return (*this); }
|
||||||
Builder& withTransparent() { _flags.set(TRANSLUCENT); return (*this); }
|
Builder& withTransparent() { _flags.set(TRANSLUCENT); return (*this); }
|
||||||
Builder& withViewSpace() { _flags.set(VIEW_SPACE); return (*this); }
|
Builder& withViewSpace() { _flags.set(VIEW_SPACE); return (*this); }
|
||||||
Builder& withDynamic() { _flags.set(DYNAMIC); return (*this); }
|
Builder& withDynamic() { _flags.set(DYNAMIC); return (*this); }
|
||||||
|
@ -91,6 +93,7 @@ public:
|
||||||
|
|
||||||
bool isShape() const { return _flags[TYPE_SHAPE]; }
|
bool isShape() const { return _flags[TYPE_SHAPE]; }
|
||||||
bool isLight() const { return _flags[TYPE_LIGHT]; }
|
bool isLight() const { return _flags[TYPE_LIGHT]; }
|
||||||
|
bool isMeta() const { return _flags[TYPE_META]; }
|
||||||
|
|
||||||
bool isOpaque() const { return !_flags[TRANSLUCENT]; }
|
bool isOpaque() const { return !_flags[TRANSLUCENT]; }
|
||||||
bool isTransparent() const { return _flags[TRANSLUCENT]; }
|
bool isTransparent() const { return _flags[TRANSLUCENT]; }
|
||||||
|
@ -150,6 +153,7 @@ public:
|
||||||
|
|
||||||
Builder& withTypeShape() { _value.set(ItemKey::TYPE_SHAPE); _mask.set(ItemKey::TYPE_SHAPE); return (*this); }
|
Builder& withTypeShape() { _value.set(ItemKey::TYPE_SHAPE); _mask.set(ItemKey::TYPE_SHAPE); return (*this); }
|
||||||
Builder& withTypeLight() { _value.set(ItemKey::TYPE_LIGHT); _mask.set(ItemKey::TYPE_LIGHT); return (*this); }
|
Builder& withTypeLight() { _value.set(ItemKey::TYPE_LIGHT); _mask.set(ItemKey::TYPE_LIGHT); return (*this); }
|
||||||
|
Builder& withTypeMeta() { _value.set(ItemKey::TYPE_META); _mask.set(ItemKey::TYPE_META); return (*this); }
|
||||||
|
|
||||||
Builder& withOpaque() { _value.reset(ItemKey::TRANSLUCENT); _mask.set(ItemKey::TRANSLUCENT); return (*this); }
|
Builder& withOpaque() { _value.reset(ItemKey::TRANSLUCENT); _mask.set(ItemKey::TRANSLUCENT); return (*this); }
|
||||||
Builder& withTransparent() { _value.set(ItemKey::TRANSLUCENT); _mask.set(ItemKey::TRANSLUCENT); return (*this); }
|
Builder& withTransparent() { _value.set(ItemKey::TRANSLUCENT); _mask.set(ItemKey::TRANSLUCENT); return (*this); }
|
||||||
|
@ -179,6 +183,7 @@ public:
|
||||||
static Builder opaqueShape() { return Builder().withTypeShape().withOpaque().withWorldSpace(); }
|
static Builder opaqueShape() { return Builder().withTypeShape().withOpaque().withWorldSpace(); }
|
||||||
static Builder transparentShape() { return Builder().withTypeShape().withTransparent().withWorldSpace(); }
|
static Builder transparentShape() { return Builder().withTypeShape().withTransparent().withWorldSpace(); }
|
||||||
static Builder light() { return Builder().withTypeLight(); }
|
static Builder light() { return Builder().withTypeLight(); }
|
||||||
|
static Builder meta() { return Builder().withTypeMeta(); }
|
||||||
static Builder background() { return Builder().withViewSpace().withLayered(); }
|
static Builder background() { return Builder().withViewSpace().withLayered(); }
|
||||||
static Builder opaqueShapeLayered() { return Builder().withTypeShape().withOpaque().withWorldSpace().withLayered(); }
|
static Builder opaqueShapeLayered() { return Builder().withTypeShape().withOpaque().withWorldSpace().withLayered(); }
|
||||||
static Builder transparentShapeLayered() { return Builder().withTypeShape().withTransparent().withWorldSpace().withLayered(); }
|
static Builder transparentShapeLayered() { return Builder().withTypeShape().withTransparent().withWorldSpace().withLayered(); }
|
||||||
|
@ -210,6 +215,25 @@ inline QDebug operator<<(QDebug debug, const ItemFilter& me) {
|
||||||
using ItemID = uint32_t;
|
using ItemID = uint32_t;
|
||||||
using ItemCell = int32_t;
|
using ItemCell = int32_t;
|
||||||
|
|
||||||
|
// A few typedefs for standard containers of ItemIDs
|
||||||
|
using ItemIDs = std::vector<ItemID>;
|
||||||
|
using ItemIDSet = std::set<ItemID>;
|
||||||
|
|
||||||
|
// Handy type to just pass the ID and the bound of an item
|
||||||
|
class ItemBound {
|
||||||
|
public:
|
||||||
|
ItemBound(ItemID id) : id(id) { }
|
||||||
|
ItemBound(ItemID id, const AABox& bound) : id(id), bound(bound) { }
|
||||||
|
|
||||||
|
ItemID id;
|
||||||
|
AABox bound;
|
||||||
|
};
|
||||||
|
|
||||||
|
// many Item Bounds in a vector
|
||||||
|
using ItemBounds = std::vector<ItemBound>;
|
||||||
|
|
||||||
|
// Item is the proxy to a bounded "object" in the scene
|
||||||
|
// An item is described by its Key
|
||||||
class Item {
|
class Item {
|
||||||
public:
|
public:
|
||||||
typedef std::vector<Item> Vector;
|
typedef std::vector<Item> Vector;
|
||||||
|
@ -295,6 +319,8 @@ public:
|
||||||
|
|
||||||
virtual const ShapeKey getShapeKey() const = 0;
|
virtual const ShapeKey getShapeKey() const = 0;
|
||||||
|
|
||||||
|
virtual uint32_t fetchMetaSubItems(ItemIDs& subItems) const = 0;
|
||||||
|
|
||||||
~PayloadInterface() {}
|
~PayloadInterface() {}
|
||||||
|
|
||||||
// Status interface is local to the base class
|
// Status interface is local to the base class
|
||||||
|
@ -313,6 +339,9 @@ public:
|
||||||
Item() {}
|
Item() {}
|
||||||
~Item() {}
|
~Item() {}
|
||||||
|
|
||||||
|
// Item exists if it has a valid payload
|
||||||
|
bool exist() const { return (bool)(_payload); }
|
||||||
|
|
||||||
// Main scene / item managment interface reset/update/kill
|
// Main scene / item managment interface reset/update/kill
|
||||||
void resetPayload(const PayloadPointer& payload);
|
void resetPayload(const PayloadPointer& payload);
|
||||||
void resetCell(ItemCell cell = INVALID_CELL, bool _small = false) { _cell = cell; _key.setSmaller(_small); }
|
void resetCell(ItemCell cell = INVALID_CELL, bool _small = false) { _cell = cell; _key.setSmaller(_small); }
|
||||||
|
@ -339,6 +368,9 @@ public:
|
||||||
// Shape Type Interface
|
// Shape Type Interface
|
||||||
const ShapeKey getShapeKey() const { return _payload->getShapeKey(); }
|
const ShapeKey getShapeKey() const { return _payload->getShapeKey(); }
|
||||||
|
|
||||||
|
// Meta Type Interface
|
||||||
|
uint32_t fetchMetaSubItems(ItemIDs& subItems) const { return _payload->fetchMetaSubItems(subItems); }
|
||||||
|
|
||||||
// Access the status
|
// Access the status
|
||||||
const StatusPointer& getStatus() const { return _payload->getStatus(); }
|
const StatusPointer& getStatus() const { return _payload->getStatus(); }
|
||||||
|
|
||||||
|
@ -370,10 +402,7 @@ inline QDebug operator<<(QDebug debug, const Item& item) {
|
||||||
return debug;
|
return debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
// THe Payload class is the real Payload to be used
|
// Item shared interface supported by the payload
|
||||||
// THis allow anything to be turned into a Payload as long as the required interface functions are available
|
|
||||||
// When creating a new kind of payload from a new "stuff" class then you need to create specialized version for "stuff"
|
|
||||||
// of the Payload interface
|
|
||||||
template <class T> const ItemKey payloadGetKey(const std::shared_ptr<T>& payloadData) { return ItemKey(); }
|
template <class T> const ItemKey payloadGetKey(const std::shared_ptr<T>& payloadData) { return ItemKey(); }
|
||||||
template <class T> const Item::Bound payloadGetBound(const std::shared_ptr<T>& payloadData) { return Item::Bound(); }
|
template <class T> const Item::Bound payloadGetBound(const std::shared_ptr<T>& payloadData) { return Item::Bound(); }
|
||||||
template <class T> int payloadGetLayer(const std::shared_ptr<T>& payloadData) { return 0; }
|
template <class T> int payloadGetLayer(const std::shared_ptr<T>& payloadData) { return 0; }
|
||||||
|
@ -385,6 +414,14 @@ template <class T> void payloadRender(const std::shared_ptr<T>& payloadData, Ren
|
||||||
// implying that the shape will setup its own pipeline without the use of the ShapeKey.
|
// implying that the shape will setup its own pipeline without the use of the ShapeKey.
|
||||||
template <class T> const ShapeKey shapeGetShapeKey(const std::shared_ptr<T>& payloadData) { return ShapeKey::Builder::ownPipeline(); }
|
template <class T> const ShapeKey shapeGetShapeKey(const std::shared_ptr<T>& payloadData) { return ShapeKey::Builder::ownPipeline(); }
|
||||||
|
|
||||||
|
// Meta Type Interface
|
||||||
|
// Meta items act as the grouping object for several sub items (typically shapes).
|
||||||
|
template <class T> uint32_t metaFetchMetaSubItems(const std::shared_ptr<T>& payloadData, ItemIDs& subItems) { return 0; }
|
||||||
|
|
||||||
|
// THe Payload class is the real Payload to be used
|
||||||
|
// THis allow anything to be turned into a Payload as long as the required interface functions are available
|
||||||
|
// When creating a new kind of payload from a new "stuff" class then you need to create specialized version for "stuff"
|
||||||
|
// of the Payload interface
|
||||||
template <class T> class Payload : public Item::PayloadInterface {
|
template <class T> class Payload : public Item::PayloadInterface {
|
||||||
public:
|
public:
|
||||||
typedef std::shared_ptr<T> DataPointer;
|
typedef std::shared_ptr<T> DataPointer;
|
||||||
|
@ -403,6 +440,9 @@ public:
|
||||||
// Shape Type interface
|
// Shape Type interface
|
||||||
virtual const ShapeKey getShapeKey() const override { return shapeGetShapeKey<T>(_data); }
|
virtual const ShapeKey getShapeKey() const override { return shapeGetShapeKey<T>(_data); }
|
||||||
|
|
||||||
|
// Meta Type Interface
|
||||||
|
virtual uint32_t fetchMetaSubItems(ItemIDs& subItems) const { return metaFetchMetaSubItems<T>(_data, subItems); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
DataPointer _data;
|
DataPointer _data;
|
||||||
|
|
||||||
|
@ -450,22 +490,6 @@ template <> const Item::Bound payloadGetBound(const FooPointer& foo) {
|
||||||
typedef Item::PayloadPointer PayloadPointer;
|
typedef Item::PayloadPointer PayloadPointer;
|
||||||
typedef std::vector< PayloadPointer > Payloads;
|
typedef std::vector< PayloadPointer > Payloads;
|
||||||
|
|
||||||
// A few typedefs for standard containers of ItemIDs
|
|
||||||
using ItemIDs = std::vector<ItemID>;
|
|
||||||
using ItemIDSet = std::set<ItemID>;
|
|
||||||
|
|
||||||
// Handy type to just pass the ID and the bound of an item
|
|
||||||
class ItemBound {
|
|
||||||
public:
|
|
||||||
ItemBound(ItemID id) : id(id) { }
|
|
||||||
ItemBound(ItemID id, const AABox& bound) : id(id), bound(bound) { }
|
|
||||||
|
|
||||||
ItemID id;
|
|
||||||
AABox bound;
|
|
||||||
};
|
|
||||||
// many Item Bounds in a vector
|
|
||||||
using ItemBounds = std::vector<ItemBound>;
|
|
||||||
|
|
||||||
// A map of items by ShapeKey to optimize rendering pipeline assignments
|
// A map of items by ShapeKey to optimize rendering pipeline assignments
|
||||||
using ShapeBounds = std::unordered_map<ShapeKey, ItemBounds, ShapeKey::Hash, ShapeKey::KeyEqual>;
|
using ShapeBounds = std::unordered_map<ShapeKey, ItemBounds, ShapeKey::Hash, ShapeKey::KeyEqual>;
|
||||||
|
|
||||||
|
|
|
@ -29,33 +29,41 @@ RenderFetchCullSortTask::RenderFetchCullSortTask(CullFunctor cullFunctor) {
|
||||||
const auto nonspatialSelection = addJob<FetchNonspatialItems>("FetchOverlaySelection");
|
const auto nonspatialSelection = addJob<FetchNonspatialItems>("FetchOverlaySelection");
|
||||||
|
|
||||||
// Multi filter visible items into different buckets
|
// Multi filter visible items into different buckets
|
||||||
const int NUM_FILTERS = 3;
|
const int NUM_SPATIAL_FILTERS = 4;
|
||||||
|
const int NUM_NON_SPATIAL_FILTERS = 3;
|
||||||
const int OPAQUE_SHAPE_BUCKET = 0;
|
const int OPAQUE_SHAPE_BUCKET = 0;
|
||||||
const int TRANSPARENT_SHAPE_BUCKET = 1;
|
const int TRANSPARENT_SHAPE_BUCKET = 1;
|
||||||
const int LIGHT_BUCKET = 2;
|
const int LIGHT_BUCKET = 2;
|
||||||
|
const int META_BUCKET = 3;
|
||||||
const int BACKGROUND_BUCKET = 2;
|
const int BACKGROUND_BUCKET = 2;
|
||||||
MultiFilterItem<NUM_FILTERS>::ItemFilterArray spatialFilters = { {
|
MultiFilterItem<NUM_SPATIAL_FILTERS>::ItemFilterArray spatialFilters = { {
|
||||||
ItemFilter::Builder::opaqueShape(),
|
ItemFilter::Builder::opaqueShape(),
|
||||||
ItemFilter::Builder::transparentShape(),
|
ItemFilter::Builder::transparentShape(),
|
||||||
ItemFilter::Builder::light()
|
ItemFilter::Builder::light(),
|
||||||
|
ItemFilter::Builder::meta()
|
||||||
} };
|
} };
|
||||||
MultiFilterItem<NUM_FILTERS>::ItemFilterArray nonspatialFilters = { {
|
MultiFilterItem<NUM_NON_SPATIAL_FILTERS>::ItemFilterArray nonspatialFilters = { {
|
||||||
ItemFilter::Builder::opaqueShape(),
|
ItemFilter::Builder::opaqueShape(),
|
||||||
ItemFilter::Builder::transparentShape(),
|
ItemFilter::Builder::transparentShape(),
|
||||||
ItemFilter::Builder::background()
|
ItemFilter::Builder::background()
|
||||||
} };
|
} };
|
||||||
const auto filteredSpatialBuckets = addJob<MultiFilterItem<NUM_FILTERS>>("FilterSceneSelection", culledSpatialSelection, spatialFilters).get<MultiFilterItem<NUM_FILTERS>::ItemBoundsArray>();
|
const auto filteredSpatialBuckets =
|
||||||
const auto filteredNonspatialBuckets = addJob<MultiFilterItem<NUM_FILTERS>>("FilterOverlaySelection", nonspatialSelection, nonspatialFilters).get<MultiFilterItem<NUM_FILTERS>::ItemBoundsArray>();
|
addJob<MultiFilterItem<NUM_SPATIAL_FILTERS>>("FilterSceneSelection", culledSpatialSelection, spatialFilters)
|
||||||
|
.get<MultiFilterItem<NUM_SPATIAL_FILTERS>::ItemBoundsArray>();
|
||||||
|
const auto filteredNonspatialBuckets =
|
||||||
|
addJob<MultiFilterItem<NUM_NON_SPATIAL_FILTERS>>("FilterOverlaySelection", nonspatialSelection, nonspatialFilters)
|
||||||
|
.get<MultiFilterItem<NUM_NON_SPATIAL_FILTERS>::ItemBoundsArray>();
|
||||||
|
|
||||||
// Extract opaques / transparents / lights / overlays
|
// Extract opaques / transparents / lights / overlays
|
||||||
const auto opaques = addJob<DepthSortItems>("DepthSortOpaque", filteredSpatialBuckets[OPAQUE_SHAPE_BUCKET]);
|
const auto opaques = addJob<DepthSortItems>("DepthSortOpaque", filteredSpatialBuckets[OPAQUE_SHAPE_BUCKET]);
|
||||||
const auto transparents = addJob<DepthSortItems>("DepthSortTransparent", filteredSpatialBuckets[TRANSPARENT_SHAPE_BUCKET], DepthSortItems(false));
|
const auto transparents = addJob<DepthSortItems>("DepthSortTransparent", filteredSpatialBuckets[TRANSPARENT_SHAPE_BUCKET], DepthSortItems(false));
|
||||||
const auto lights = filteredSpatialBuckets[LIGHT_BUCKET];
|
const auto lights = filteredSpatialBuckets[LIGHT_BUCKET];
|
||||||
|
const auto metas = filteredSpatialBuckets[META_BUCKET];
|
||||||
|
|
||||||
const auto overlayOpaques = addJob<DepthSortItems>("DepthSortOverlayOpaque", filteredNonspatialBuckets[OPAQUE_SHAPE_BUCKET]);
|
const auto overlayOpaques = addJob<DepthSortItems>("DepthSortOverlayOpaque", filteredNonspatialBuckets[OPAQUE_SHAPE_BUCKET]);
|
||||||
const auto overlayTransparents = addJob<DepthSortItems>("DepthSortOverlayTransparent", filteredNonspatialBuckets[TRANSPARENT_SHAPE_BUCKET], DepthSortItems(false));
|
const auto overlayTransparents = addJob<DepthSortItems>("DepthSortOverlayTransparent", filteredNonspatialBuckets[TRANSPARENT_SHAPE_BUCKET], DepthSortItems(false));
|
||||||
const auto background = filteredNonspatialBuckets[BACKGROUND_BUCKET];
|
const auto background = filteredNonspatialBuckets[BACKGROUND_BUCKET];
|
||||||
|
|
||||||
setOutput(Output{{
|
setOutput(Output{{
|
||||||
opaques, transparents, lights, overlayOpaques, overlayTransparents, background, spatialSelection }});
|
opaques, transparents, lights, metas, overlayOpaques, overlayTransparents, background, spatialSelection }});
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,21 @@
|
||||||
|
|
||||||
class RenderFetchCullSortTask : public render::Task {
|
class RenderFetchCullSortTask : public render::Task {
|
||||||
public:
|
public:
|
||||||
using Output = std::array<render::Varying, 7>;
|
|
||||||
|
enum Buckets {
|
||||||
|
OPAQUE_SHAPE = 0,
|
||||||
|
TRANSPARENT_SHAPE,
|
||||||
|
LIGHT,
|
||||||
|
META,
|
||||||
|
OVERLAY_OPAQUE_SHAPE,
|
||||||
|
OVERLAY_TRANSPARENT_SHAPE,
|
||||||
|
BACKGROUND,
|
||||||
|
SPATIAL_SELECTION,
|
||||||
|
|
||||||
|
NUM_BUCKETS
|
||||||
|
};
|
||||||
|
|
||||||
|
using Output = std::array<render::Varying, Buckets::NUM_BUCKETS>;
|
||||||
using JobModel = ModelO<RenderFetchCullSortTask>;
|
using JobModel = ModelO<RenderFetchCullSortTask>;
|
||||||
|
|
||||||
RenderFetchCullSortTask(render::CullFunctor cullFunctor);
|
RenderFetchCullSortTask(render::CullFunctor cullFunctor);
|
||||||
|
|
|
@ -58,7 +58,7 @@ ItemID Scene::allocateID() {
|
||||||
return _IDAllocator.fetch_add(1);
|
return _IDAllocator.fetch_add(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Scene::isAllocatedID(const ItemID& id) {
|
bool Scene::isAllocatedID(const ItemID& id) const {
|
||||||
return Item::isValidID(id) && (id < _numAllocatedItems.load());
|
return Item::isValidID(id) && (id < _numAllocatedItems.load());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,7 +61,7 @@ public:
|
||||||
ItemID allocateID();
|
ItemID allocateID();
|
||||||
|
|
||||||
// Check that the ID is valid and allocated for this scene, this a threadsafe call
|
// Check that the ID is valid and allocated for this scene, this a threadsafe call
|
||||||
bool isAllocatedID(const ItemID& id);
|
bool isAllocatedID(const ItemID& id) const;
|
||||||
|
|
||||||
// THis is the total number of allocated items, this a threadsafe call
|
// THis is the total number of allocated items, this a threadsafe call
|
||||||
size_t getNumItems() const { return _numAllocatedItems.load(); }
|
size_t getNumItems() const { return _numAllocatedItems.load(); }
|
||||||
|
@ -78,6 +78,9 @@ public:
|
||||||
// WARNING, There is No check on the validity of the ID, so this could return a bad Item
|
// WARNING, There is No check on the validity of the ID, so this could return a bad Item
|
||||||
const Item& getItem(const ItemID& id) const { return _items[id]; }
|
const Item& getItem(const ItemID& id) const { return _items[id]; }
|
||||||
|
|
||||||
|
// Same as getItem, checking if the id is valid
|
||||||
|
const Item getItemSafe(const ItemID& id) const { if (isAllocatedID(id)) { return _items[id]; } else { return Item(); } }
|
||||||
|
|
||||||
// Access the spatialized items
|
// Access the spatialized items
|
||||||
const ItemSpatialTree& getSpatialTree() const { return _masterSpatialTree; }
|
const ItemSpatialTree& getSpatialTree() const { return _masterSpatialTree; }
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue