File: SceneManipulationPivot.cpp

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 (118 lines) | stat: -rw-r--r-- 4,234 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
#include "SceneManipulationPivot.h"

#include "iselection.h"
#include "ilightnode.h"
#include "ientity.h"
#include "igrid.h"
#include "selectionlib.h"
#include "registry/registry.h"
#include "selection/algorithm/General.h"

namespace selection
{

const std::string SceneManipulationPivot::RKEY_ENTITY_PIVOT_IS_ORIGIN = "user/ui/rotationPivotIsOrigin";
const std::string SceneManipulationPivot::RKEY_SNAP_ROTATION_PIVOT_TO_GRID = "user/ui/snapRotationPivotToGrid";
const std::string SceneManipulationPivot::RKEY_DEFAULT_PIVOT_LOCATION_IGNORES_LIGHT_VOLUMES = "user/ui/defaultPivotLocationIgnoresLightVolumes";

SceneManipulationPivot::SceneManipulationPivot() :
    _entityPivotIsOrigin(false),
    _snapPivotToGrid(false),
    _defaultPivotLocationIgnoresLightVolumes(false)
{}

void SceneManipulationPivot::initialise()
{
    _entityPivotIsOrigin = registry::getValue<bool>(RKEY_ENTITY_PIVOT_IS_ORIGIN);
    _snapPivotToGrid = registry::getValue<bool>(RKEY_SNAP_ROTATION_PIVOT_TO_GRID);
    _defaultPivotLocationIgnoresLightVolumes = registry::getValue<bool>(RKEY_DEFAULT_PIVOT_LOCATION_IGNORES_LIGHT_VOLUMES);

    GlobalRegistry().signalForKey(RKEY_ENTITY_PIVOT_IS_ORIGIN).connect(
        sigc::mem_fun(this, &SceneManipulationPivot::onRegistryKeyChanged)
    );
    GlobalRegistry().signalForKey(RKEY_SNAP_ROTATION_PIVOT_TO_GRID).connect(
        sigc::mem_fun(this, &SceneManipulationPivot::onRegistryKeyChanged)
    );
    GlobalRegistry().signalForKey(RKEY_DEFAULT_PIVOT_LOCATION_IGNORES_LIGHT_VOLUMES).connect(
        sigc::mem_fun(this, &SceneManipulationPivot::onRegistryKeyChanged)
    );
}

void SceneManipulationPivot::applyTranslation(const Vector3& translation)
{
    ManipulationPivot::applyTranslation(translation);

    if (_snapPivotToGrid)
    {
        // The resulting pivot should be grid-snapped
        _pivot2World.setTranslation(
            _pivot2World.translation().getSnapped(GlobalGrid().getGridSize())
        );
    }
}

void SceneManipulationPivot::updateFromSelection()
{
    _needsRecalculation = false;
    _userLocked = false;

    Vector3 objectPivot;

    const SelectionInfo& info = GlobalSelectionSystem().getSelectionInfo();

    if (info.entityCount == 1 && info.totalCount == 1 &&
        Node_getLightNode(GlobalSelectionSystem().ultimateSelected()))
    {
        // When a single light is selected, use the origin for rotation
        objectPivot = Node_getLightNode(GlobalSelectionSystem().ultimateSelected())->getSelectAABB().origin;
    }
    else if (info.entityCount == 1 && info.totalCount == 1 && _entityPivotIsOrigin)
    {
        // Test if a single entity is selected
        scene::INodePtr node = GlobalSelectionSystem().ultimateSelected();
        Entity* entity = Node_getEntity(node);

        if (entity != nullptr)
        {
            objectPivot = string::convert<Vector3>(entity->getKeyValue("origin"));
        }
    }
    else
    {
        // Create a local variable where the aabb information is stored
        AABB bounds;

        // Traverse through the selection and update the <bounds> variable
        if (GlobalSelectionSystem().getSelectionMode() == SelectionMode::Component)
        {
            bounds = algorithm::getCurrentComponentSelectionBounds();
        }
        else
        {
            // Ignore light volumes for the pivot calculation
            bounds = algorithm::getCurrentSelectionBounds(!_defaultPivotLocationIgnoresLightVolumes);
        }

        // the <bounds> variable now contains the AABB of the selection, retrieve the origin
        objectPivot = bounds.origin;
    }

    if (_snapPivotToGrid)
    {
        objectPivot.snap(GlobalGrid().getGridSize());
    }

    // The pivot2world matrix is just a translation from the world origin (0,0,0) to the object pivot
    setFromMatrix(Matrix4::getTranslation(objectPivot));
}

void SceneManipulationPivot::onRegistryKeyChanged()
{
    _entityPivotIsOrigin = registry::getValue<bool>(RKEY_ENTITY_PIVOT_IS_ORIGIN);
    _snapPivotToGrid = registry::getValue<bool>(RKEY_SNAP_ROTATION_PIVOT_TO_GRID);
    _defaultPivotLocationIgnoresLightVolumes = registry::getValue<bool>(RKEY_DEFAULT_PIVOT_LOCATION_IGNORES_LIGHT_VOLUMES);

    GlobalSelectionSystem().pivotChanged();
}

}