Code

Compute the correct visible front corner (also for 'upended' boxes) and set the z...
authorcilix42 <cilix42@users.sourceforge.net>
Tue, 7 Aug 2007 08:05:16 +0000 (08:05 +0000)
committercilix42 <cilix42@users.sourceforge.net>
Tue, 7 Aug 2007 08:05:16 +0000 (08:05 +0000)
src/axis-manip.h
src/box3d.cpp
src/box3d.h

index 5690eedcb79f564739f27cf2007f4af41bab7b70..8574bf3ff522846523dec4c3c3464c3f7f7b3b58 100644 (file)
@@ -75,6 +75,16 @@ inline bool is_single_axis_direction (Box3D::Axis dir) {
     return (!(dir & (dir - 1)) && dir);
 }
 
+// Warning: We don't check that axis really unamiguously specifies a plane.
+//          Make sure this is the case when calling this function.
+inline guint face_containing_corner (Box3D::Axis axis, guint corner) {
+    if (!is_single_axis_direction (axis)) {
+        axis = (Box3D::Axis) (axis ^ Box3D::XYZ);
+    }
+    return face_to_int (axis ^ ((corner & axis) ? Box3D::REAR : Box3D::FRONT));
+}
+
+
 /**
  * Given two axis directions out of {X, Y, Z} or the corresponding plane, return the remaining one
  * We don't check if 'plane' really specifies a plane (i.e., if it consists of precisely two directions).
index 7f04efde65ef116cc53d21976f7ddc733edb4264..0f71a99a84f8a059c46709e1f7220d126f6e2190 100644 (file)
@@ -406,7 +406,7 @@ bool sp_3dbox_recompute_z_orders (SP3DBox *box)
     Box3D::Perspective3D *persp = Box3D::get_persp_of_box (box);
 
     // TODO: Determine the front corner depending on the distance from VPs and/or the user presets
-    guint front_corner = 1;
+    guint front_corner = sp_3dbox_get_front_corner_id (box);
 
     gdouble dir_1x = sp_3dbox_corner_angle_to_VP (box, Box3D::X, front_corner);
     gdouble dir_3x = sp_3dbox_corner_angle_to_VP (box, Box3D::X, front_corner ^ Box3D::Y);
@@ -419,25 +419,25 @@ bool sp_3dbox_recompute_z_orders (SP3DBox *box)
 
     // Still not perfect, but only fails in some rather degenerate cases.
     // I suspect that there is a more elegant model, though. :)
-    new_z_orders[0] = Box3D::face_to_int (Box3D::XY ^ Box3D::FRONT);
+    new_z_orders[0] = Box3D::face_containing_corner (Box3D::XY, front_corner);
     if (normalized_angle (dir_1y - dir_1z) > 0) {
-        new_z_orders[1] = Box3D::face_to_int (Box3D::YZ ^ Box3D::REAR);
+        new_z_orders[1] = Box3D::face_containing_corner (Box3D::YZ, front_corner);
         if (normalized_angle (dir_1x - dir_1z) > 0) {
-            new_z_orders[2] = Box3D::face_to_int (Box3D::XZ ^ Box3D::REAR);
+            new_z_orders[2] = Box3D::face_containing_corner (Box3D::XZ, front_corner ^ Box3D::Y);
         } else {
-            new_z_orders[2] = Box3D::face_to_int (Box3D::XZ ^ Box3D::FRONT);
+            new_z_orders[2] = Box3D::face_containing_corner (Box3D::XZ, front_corner);
         }
     } else {
         if (normalized_angle (dir_3x - dir_3z) > 0) {
-            new_z_orders[1] = Box3D::face_to_int (Box3D::XZ ^ Box3D::REAR);
-            new_z_orders[2] = Box3D::face_to_int (Box3D::YZ ^ Box3D::FRONT);
+            new_z_orders[1] = Box3D::face_containing_corner (Box3D::XZ, front_corner ^ Box3D::Y);
+            new_z_orders[2] = Box3D::face_containing_corner (Box3D::YZ, front_corner ^ Box3D::X);
         } else {
             if (normalized_angle (dir_1x - dir_1z) > 0) {
-                new_z_orders[1] = Box3D::face_to_int (Box3D::YZ ^ Box3D::FRONT);
-                new_z_orders[2] = Box3D::face_to_int (Box3D::XZ ^ Box3D::FRONT);
+                new_z_orders[1] = Box3D::face_containing_corner (Box3D::YZ, front_corner ^ Box3D::X);
+                new_z_orders[2] = Box3D::face_containing_corner (Box3D::XZ, front_corner);
             } else {
-                new_z_orders[1] = Box3D::face_to_int (Box3D::XZ ^ Box3D::FRONT);
-                new_z_orders[2] = Box3D::face_to_int (Box3D::YZ ^ Box3D::FRONT);
+                new_z_orders[1] = Box3D::face_containing_corner (Box3D::XZ, front_corner);
+                new_z_orders[2] = Box3D::face_containing_corner (Box3D::YZ, front_corner ^ Box3D::X);
             }
         }
     }
@@ -448,8 +448,7 @@ bool sp_3dbox_recompute_z_orders (SP3DBox *box)
 
     /* We only need to look for changes among the topmost three faces because the order
        of the other ones is just inverted. */
-    // Currently we can even skip the first test since the front face is always in the XY plane.
-    if (// (box->z_orders[0] != new_z_orders[0]) ||
+    if ((box->z_orders[0] != new_z_orders[0]) ||
         (box->z_orders[1] != new_z_orders[1]) ||
         (box->z_orders[2] != new_z_orders[2]))
     {
@@ -763,6 +762,16 @@ sp_3dbox_get_corner_along_edge (const SP3DBox *box, guint corner, Box3D::Axis ax
     return box->corners[sp_3dbox_get_corner_id_along_edge (box, corner, axis, rel_pos)];
 }
 
+guint
+sp_3dbox_get_front_corner_id (const SP3DBox *box)
+{
+    guint front_corner = 1; // this could in fact be any corner, but we choose the one that is normally in front
+    front_corner = sp_3dbox_get_corner_id_along_edge (box, front_corner, Box3D::X, Box3D::FRONT);
+    front_corner = sp_3dbox_get_corner_id_along_edge (box, front_corner, Box3D::Y, Box3D::FRONT);
+    front_corner = sp_3dbox_get_corner_id_along_edge (box, front_corner, Box3D::Z, Box3D::FRONT);
+    return front_corner;
+}
+
 // auxiliary functions
 static void
 sp_3dbox_update_corner_with_value_from_svg (SPObject *object, guint corner_id, const gchar *value)
index bca319e678c6c01d461fa9fce6ace1429cd81190..aecc40462c19d495a2d3229584b5cbfd3f2946be 100644 (file)
@@ -74,6 +74,8 @@ void sp_3dbox_update_perspective_lines();
 void sp_3dbox_corners_for_perspective_lines (const SP3DBox * box, Box3D::Axis axis, NR::Point &corner1, NR::Point &corner2, NR::Point &corner3, NR::Point &corner4);
 guint sp_3dbox_get_corner_id_along_edge (const SP3DBox *box, guint corner, Box3D::Axis axis, Box3D::FrontOrRear rel_pos);
 NR::Point sp_3dbox_get_corner_along_edge (const SP3DBox *box, guint corner, Box3D::Axis axis, Box3D::FrontOrRear rel_pos);
+guint sp_3dbox_get_front_corner_id (const SP3DBox *box);
+
 
 gchar * sp_3dbox_get_svg_descr_of_persp (Box3D::Perspective3D *persp);