]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - radiant/selection.cpp
option: -sRGBcolor (unused yet)
[xonotic/netradiant.git] / radiant / selection.cpp
index dc3f624c659f4f27efa87bb9b5e4c5a7d5e85a1b..d2283d4537452ccb93c185e68716427b1278dc9a 100644 (file)
@@ -54,12 +54,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
 TextOutputStream& ostream_write(TextOutputStream& t, const Vector4& v)
 {
-  return t << "[ " << v.x() << " " << v.y() << " " << v.z() << " " << v.w() << " ]";
+       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() << " ]";
+       return t << "[ " << m.x() << " " << m.y() << " " << m.z() << " " << m.t() << " ]";
 }
 
 struct Pivot2World
@@ -318,7 +318,7 @@ public:
     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);
   }
@@ -350,7 +350,7 @@ public:
     current = vector3_subtracted(current, m_start);
 
     translation_local2object(current, current, manip2object);
-    vector3_snap(current, GetGridSize());
+    vector3_snap(current, GetSnapGridSize());
     
     m_translatable.translate(current);
   }
@@ -386,9 +386,9 @@ public:
     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],
@@ -424,9 +424,9 @@ public:
     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],
@@ -2315,42 +2315,70 @@ Vector3 get_local_pivot(const Vector3& world_pivot, const Matrix4& localToWorld)
   );
 }
 
+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
@@ -2422,8 +2450,6 @@ public:
       Transformable* transform = Instance_getTransformable(instance);
       if(transform != 0)
       {
-                 Matrix4 previousTransform = instance.localToWorld();
-
         transform->setType(TRANSFORM_PRIMITIVE);
         transform->setScale(c_scale_identity);
         transform->setTranslation(c_translation_identity);
@@ -2433,11 +2459,17 @@ public:
         {
           Editable* editable = Node_getEditable(instance.path().top());
           const Matrix4& localPivot = editable != 0 ? editable->getLocalPivot() : g_matrix4_identity;
+    
+          Vector3 parent_translation;
+          translation_for_pivoted_scale(
+            parent_translation,
+            m_scale,
+            m_world_pivot,
+            matrix4_multiplied_by_matrix4(instance.localToWorld(), localPivot),
+            matrix4_multiplied_by_matrix4(transformNode->localToParent(), localPivot)
+          );
 
-                 Vector3 previousOrigin = matrix4_get_translation_vec3(matrix4_multiplied_by_matrix4(previousTransform, localPivot));
-                 Vector3 currentOrigin = matrix4_get_translation_vec3(matrix4_multiplied_by_matrix4(instance.localToWorld(), localPivot));
-                 Vector3 wishOrigin = vector3_added(m_world_pivot, vector3_scaled(vector3_subtracted(previousOrigin, m_world_pivot), m_scale));
-          transform->setTranslation(vector3_subtracted(wishOrigin, currentOrigin));
+          transform->setTranslation(parent_translation);
         }
       }
     }
@@ -3698,7 +3730,7 @@ void RadiantSelectionSystem::ConstructPivot() const
       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)
@@ -3840,7 +3872,9 @@ const ModifierFlags c_modifier_toggle_face = c_modifier_toggle | c_modifier_face
 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_
@@ -4062,7 +4096,7 @@ public:
       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);
       }