File: RenderableCollectorBase.h

package info (click to toggle)
darkradiant 3.9.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 41,080 kB
  • sloc: cpp: 264,743; ansic: 10,659; python: 1,852; xml: 1,650; sh: 92; makefile: 21
file content (161 lines) | stat: -rw-r--r-- 5,289 bytes parent folder | download | duplicates (3)
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);
        }
    }
};

}