#include "grid.h"
+TextOutputStream& ostream_write(TextOutputStream& t, const Vector4& v)
+{
+ return t << "[ " << v.x() << " " << v.y() << " " << v.z() << " " << v.w() << " ]";
+}
+
+TextOutputStream& ostream_write(TextOutputStream& t, const Matrix4& m)
+{
+ return t << "[ " << m.x() << " " << m.y() << " " << m.z() << " " << m.t() << " ]";
+}
+
struct Pivot2World
{
Matrix4 m_worldSpace;
current = vector3_scaled(m_axis, distance_for_axis(m_start, current, m_axis));
translation_local2object(current, current, manip2object);
- vector3_snap(current, GetGridSize());
+ vector3_snap(current, GetSnapGridSize());
m_translatable.translate(current);
}
current = vector3_subtracted(current, m_start);
translation_local2object(current, current, manip2object);
- vector3_snap(current, GetGridSize());
+ vector3_snap(current, GetSnapGridSize());
m_translatable.translate(current);
}
Vector3 delta = vector3_subtracted(current, m_start);
translation_local2object(delta, delta, manip2object);
- vector3_snap(delta, GetGridSize());
+ vector3_snap(delta, GetSnapGridSize());
- Vector3 start(vector3_snapped(m_start, GetGridSize()));
+ Vector3 start(vector3_snapped(m_start, GetSnapGridSize()));
Vector3 scale(
start[0] == 0 ? 1 : 1 + delta[0] / start[0],
start[1] == 0 ? 1 : 1 + delta[1] / start[1],
Vector3 delta = vector3_subtracted(current, m_start);
translation_local2object(delta, delta, manip2object);
- vector3_snap(delta, GetGridSize());
+ vector3_snap(delta, GetSnapGridSize());
- Vector3 start(vector3_snapped(m_start, GetGridSize()));
+ Vector3 start(vector3_snapped(m_start, GetSnapGridSize()));
Vector3 scale(
start[0] == 0 ? 1 : 1 + delta[0] / start[0],
start[1] == 0 ? 1 : 1 + delta[1] / start[1],
);
}
+void translation_for_pivoted_matrix_transform(Vector3& parent_translation, const Matrix4& local_transform, const Vector3& world_pivot, const Matrix4& localToWorld, const Matrix4& localToParent)
+{
+ // we need a translation inside the parent system to move the origin of this object to the right place
+
+ // mathematically, it must fulfill:
+ //
+ // local_translation local_transform local_pivot = local_pivot
+ // local_translation = local_pivot - local_transform local_pivot
+ //
+ // or maybe?
+ // local_transform local_translation local_pivot = local_pivot
+ // local_translation local_pivot = local_transform^-1 local_pivot
+ // local_translation + local_pivot = local_transform^-1 local_pivot
+ // local_translation = local_transform^-1 local_pivot - local_pivot
+
+ Vector3 local_pivot(get_local_pivot(world_pivot, localToWorld));
+
+ Vector3 local_translation(
+ vector3_subtracted(
+ local_pivot,
+ matrix4_transformed_point(
+ local_transform,
+ local_pivot
+ )
+ /*
+ matrix4_transformed_point(
+ matrix4_full_inverse(local_transform),
+ local_pivot
+ ),
+ local_pivot
+ */
+ )
+ );
+
+ translation_local2object(parent_translation, local_translation, localToParent);
+
+ /*
+ // verify it!
+ globalOutputStream() << "World pivot is at " << world_pivot << "\n";
+ globalOutputStream() << "Local pivot is at " << local_pivot << "\n";
+ globalOutputStream() << "Transformation " << local_transform << " moves it to: " << matrix4_transformed_point(local_transform, local_pivot) << "\n";
+ globalOutputStream() << "Must move by " << local_translation << " in the local system" << "\n";
+ globalOutputStream() << "Must move by " << parent_translation << " in the parent system" << "\n";
+ */
+}
+
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(
- vector3_added(
- local_pivot,
- matrix4_transformed_point(
- matrix4_rotation_for_quaternion_quantised(local_rotation),
- vector3_negated(local_pivot)
- )
- )
- );
-
- //globalOutputStream() << "translation: " << translation << "\n";
-
- translation_local2object(parent_translation, translation, localToParent);
-
- //globalOutputStream() << "parent_translation: " << parent_translation << "\n";
+ translation_for_pivoted_matrix_transform(parent_translation, matrix4_rotation_for_quaternion_quantised(local_rotation), world_pivot, localToWorld, localToParent);
}
-void translation_for_pivoted_scale(Vector3& parent_translation, const Vector3& local_scale, const Vector3& world_pivot, const Matrix4& localToWorld, const Matrix4& localToParent)
+void translation_for_pivoted_scale(Vector3& parent_translation, const Vector3& world_scale, const Vector3& world_pivot, const Matrix4& localToWorld, const Matrix4& localToParent)
{
- Vector3 local_pivot(get_local_pivot(world_pivot, localToWorld));
-
- Vector3 translation(
- vector3_added(
- local_pivot,
- vector3_scaled(
- vector3_negated(local_pivot),
- local_scale
- )
- )
+ Matrix4 local_transform(
+ matrix4_multiplied_by_matrix4(
+ matrix4_full_inverse(localToWorld),
+ matrix4_multiplied_by_matrix4(
+ matrix4_scale_for_vec3(world_scale),
+ localToWorld
+ )
+ )
);
-
- translation_local2object(parent_translation, translation, localToParent);
+ local_transform.tx() = local_transform.ty() = local_transform.tz() = 0; // cancel translation parts
+ translation_for_pivoted_matrix_transform(parent_translation, local_transform, world_pivot, localToWorld, localToParent);
}
class rotate_selected : public SelectionSystem::Visitor
m_object_pivot = bounds.origin;
}
- vector3_snap(m_object_pivot, GetGridSize());
+ vector3_snap(m_object_pivot, GetSnapGridSize());
m_pivot2world = matrix4_translation_for_vec3(m_object_pivot);
switch(m_manipulator_mode)
const ModifierFlags c_modifier_replace_face = c_modifier_replace | c_modifier_face;
const ButtonIdentifier c_button_texture = c_buttonMiddle;
-const ModifierFlags c_modifier_apply_texture = c_modifierControl | c_modifierShift;
+const ModifierFlags c_modifier_apply_texture1 = c_modifierControl | c_modifierShift;
+const ModifierFlags c_modifier_apply_texture2 = c_modifierControl;
+const ModifierFlags c_modifier_apply_texture3 = c_modifierShift;
const ModifierFlags c_modifier_copy_texture = c_modifierNone;
class Selector_
ConstructSelectionTest(scissored, SelectionBoxForPoint(&devicePosition[0], &m_selector.m_epsilon[0]));
SelectionVolume volume(scissored);
- if(modifiers == c_modifier_apply_texture)
+ if(modifiers == c_modifier_apply_texture1 || modifiers == c_modifier_apply_texture2 || modifiers == c_modifier_apply_texture3)
{
Scene_applyClosestTexture(volume);
}