1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
#pragma once
#include "irenderable.h"
#include "imapmerge.h"
#include "inode.h"
#include "iselection.h"
namespace render
{
/**
* Front end renderer base implementation shared by CamRenderer and XYRenderer
*
* Provides support for highlighting selected objects by activating the
* RenderableCollector's "highlight" flags based on the renderable object's
* selection state.
*/
class RenderableCollectorBase :
public IRenderableCollector
{
protected:
std::size_t _flags;
public:
RenderableCollectorBase() :
_flags(Highlight::Flags::NoHighlight)
{}
~RenderableCollectorBase() override
{}
bool hasHighlightFlags() const override
{
return _flags != 0;
}
bool hasHighlightFlag(Highlight::Flags flags) const override
{
return (_flags & flags) == flags;
}
void setHighlightFlag(Highlight::Flags flags, bool enabled) override
{
if (enabled)
{
_flags |= flags;
}
else
{
_flags &= ~flags;
}
}
virtual void processNode(const scene::INodePtr& node, const VolumeTest& volume)
{
node->onPreRender(volume);
// greebo: Highlighting propagates to child nodes
auto parent = node->getParent();
auto highlightFlags = node->getHighlightFlags();
auto nodeType = node->getNodeType();
// Particle nodes shouldn't inherit the highlight flags from their parent,
// as it obstructs the view when their wireframe gets rendered (#5682)
if (parent && nodeType != scene::INode::Type::Particle)
{
highlightFlags |= parent->getHighlightFlags();
}
if (nodeType == scene::INode::Type::MergeAction)
{
setHighlightFlag(Highlight::MergeAction, true);
auto mergeActionNode = std::dynamic_pointer_cast<scene::IMergeActionNode>(node);
assert(mergeActionNode);
switch (mergeActionNode->getActionType())
{
case scene::merge::ActionType::AddChildNode:
case scene::merge::ActionType::AddEntity:
setHighlightFlag(Highlight::MergeActionAdd, true);
setHighlightFlag(Highlight::MergeActionChange, false);
setHighlightFlag(Highlight::MergeActionRemove, false);
setHighlightFlag(Highlight::MergeActionConflict, false);
break;
case scene::merge::ActionType::AddKeyValue:
case scene::merge::ActionType::ChangeKeyValue:
case scene::merge::ActionType::RemoveKeyValue:
setHighlightFlag(Highlight::MergeActionChange, true);
setHighlightFlag(Highlight::MergeActionAdd, false);
setHighlightFlag(Highlight::MergeActionRemove, false);
setHighlightFlag(Highlight::MergeActionConflict, false);
break;
case scene::merge::ActionType::RemoveChildNode:
case scene::merge::ActionType::RemoveEntity:
setHighlightFlag(Highlight::MergeActionRemove, true);
setHighlightFlag(Highlight::MergeActionAdd, false);
setHighlightFlag(Highlight::MergeActionChange, false);
setHighlightFlag(Highlight::MergeActionConflict, false);
break;
case scene::merge::ActionType::ConflictResolution:
setHighlightFlag(Highlight::MergeActionConflict, true);
setHighlightFlag(Highlight::MergeActionAdd, false);
setHighlightFlag(Highlight::MergeActionChange, false);
setHighlightFlag(Highlight::MergeActionRemove, false);
break;
}
}
else
{
setHighlightFlag(Highlight::MergeAction, false);
setHighlightFlag(Highlight::MergeActionAdd, false);
setHighlightFlag(Highlight::MergeActionChange, false);
setHighlightFlag(Highlight::MergeActionRemove, false);
setHighlightFlag(Highlight::MergeActionConflict, false);
}
if (highlightFlags & Renderable::Highlight::Selected)
{
if (GlobalSelectionSystem().getSelectionMode() != selection::SelectionMode::Component)
{
setHighlightFlag(Highlight::Faces, true);
}
else
{
setHighlightFlag(Highlight::Faces, false);
}
setHighlightFlag(Highlight::Primitives, true);
// Pass on the info about whether we have a group member selected
if (highlightFlags & Renderable::Highlight::GroupMember)
{
setHighlightFlag(Highlight::GroupMember, true);
}
else
{
setHighlightFlag(Highlight::GroupMember, false);
}
}
else
{
setHighlightFlag(Highlight::Primitives, false);
setHighlightFlag(Highlight::Faces, false);
setHighlightFlag(Highlight::GroupMember, false);
}
// If this node should be highlighted, ask it to submit the corresponding geometry
if (hasHighlightFlags())
{
node->renderHighlights(*this, volume);
}
}
};
}
|