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
|
#include "TransformationVisitors.h"
#include "editable.h"
#include "manipulators/ManipulatorComponents.h"
#include "transformlib.h"
#include "registry/registry.h"
#include "selection/algorithm/General.h"
// greebo: This is needed e.g. to calculate the translation vector of a rotation transformation
Vector3 get_local_pivot(const Vector3& world_pivot, const Matrix4& localToWorld)
{
return localToWorld.getFullInverse().transformPoint(world_pivot);
}
// greebo: Calculates the translation vector of a rotation about a pivot point,
void translation_for_pivoted_rotation(Vector3& parent_translation, const Quaternion& local_rotation,
const Vector3& world_pivot, const Matrix4& localToWorld,
const Matrix4& localToParent)
{
Vector3 local_pivot(get_local_pivot(world_pivot, localToWorld));
Vector3 translation(
local_pivot +
Matrix4::getRotationQuantised(local_rotation).transformPoint(-local_pivot)
);
//rMessage() << "translation: " << translation << "\n";
selection::translation_local2object(parent_translation, translation, localToParent);
//rMessage() << "parent_translation: " << parent_translation << "\n";
}
// greebo: Calculates the translation vector of a scale transformation based on a pivot point,
void translation_for_pivoted_scale(Vector3& parent_translation, const Vector3& local_scale,
const Vector3& world_pivot, const Matrix4& localToWorld,
const Matrix4& localToParent)
{
Vector3 local_pivot(get_local_pivot(world_pivot, localToWorld));
Vector3 translation(
local_pivot +
(-local_pivot) * local_scale
);
selection::translation_local2object(parent_translation, translation, localToParent);
}
// ===================================================================================
void TranslateSelected::visit(const scene::INodePtr& node) const {
ITransformablePtr transform = scene::node_cast<ITransformable>(node);
if(transform != 0) {
transform->setType(TRANSFORM_PRIMITIVE);
transform->setTranslation(m_translate);
}
}
// ===================================================================================
RotateSelected::RotateSelected(const Quaternion& rotation, const Vector3& world_pivot) :
_rotation(rotation),
_worldPivot(world_pivot),
_freeObjectRotation(registry::getValue<bool>(selection::algorithm::RKEY_FREE_OBJECT_ROTATION))
{}
void RotateSelected::visit(const scene::INodePtr& node) const
{
ITransformNodePtr transformNode = scene::node_cast<ITransformNode>(node);
if (transformNode)
{
// Upcast the instance onto a Transformable
ITransformablePtr transformable = scene::node_cast<ITransformable>(node);
if (transformable)
{
// The object is not scaled or translated explicitly
// A translation might occur due to the rotation around a pivot point
transformable->setType(TRANSFORM_PRIMITIVE);
transformable->setScale(c_scale_identity);
transformable->setTranslation(c_translation_identity);
// Pass the rotation quaternion and the world pivot,
// unless we're rotating each object around their own center
transformable->setRotation(_rotation,
_freeObjectRotation ? transformable->getUntransformedOrigin() : _worldPivot,
node->localToWorld());
}
}
}
// ===================================================================================
void ScaleSelected::visit(const scene::INodePtr& node) const {
ITransformNodePtr transformNode = scene::node_cast<ITransformNode>(node);
if(transformNode != 0)
{
ITransformablePtr transform = scene::node_cast<ITransformable>(node);
if(transform != 0)
{
transform->setType(TRANSFORM_PRIMITIVE);
transform->setScale(c_scale_identity);
transform->setTranslation(c_translation_identity);
transform->setType(TRANSFORM_PRIMITIVE);
transform->setScale(m_scale);
{
Vector3 parent_translation;
translation_for_pivoted_scale(
parent_translation,
m_scale,
m_world_pivot,
node->localToWorld(),
transformNode->localToParent()
);
transform->setTranslation(parent_translation);
}
}
}
}
// ====== Component Visitors ==========================================================
void TranslateComponentSelected::visit(const scene::INodePtr& node) const {
ITransformablePtr transform = scene::node_cast<ITransformable>(node);
if(transform != 0)
{
transform->setType(TRANSFORM_COMPONENT);
transform->setTranslation(m_translate);
}
}
void RotateComponentSelected::visit(const scene::INodePtr& node) const {
ITransformablePtr transform = scene::node_cast<ITransformable>(node);
if(transform != 0) {
Vector3 parent_translation;
translation_for_pivoted_rotation(parent_translation, m_rotate, m_world_pivot,
node->localToWorld(),
scene::node_cast<ITransformNode>(node)->localToParent());
transform->setType(TRANSFORM_COMPONENT);
transform->setRotation(m_rotate);
transform->setTranslation(parent_translation);
}
}
void ScaleComponentSelected::visit(const scene::INodePtr& node) const {
ITransformablePtr transform = scene::node_cast<ITransformable>(node);
if(transform != 0) {
Vector3 parent_translation;
translation_for_pivoted_scale(parent_translation, m_scale, m_world_pivot, node->localToWorld(), scene::node_cast<ITransformNode>(node)->localToParent());
transform->setType(TRANSFORM_COMPONENT);
transform->setScale(m_scale);
transform->setTranslation(parent_translation);
}
}
|