merge with/from trunk at r35190
[blender.git] / source / blender / editors / transform / transform_constraints.c
index da8f0c4d0e92df18b828b467fdf900d074a77471..4427e4724129e02872f8534e573e2415a83c5eff 100644 (file)
@@ -1,4 +1,4 @@
-/**
+/*
  * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
@@ -15,7 +15,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  *
  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
  * All rights reserved.
 #include <string.h>
 #include <math.h>
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 #ifndef WIN32
 #include <unistd.h>
 #else
 #include <io.h>
 #endif
 
-#include "MEM_guardedalloc.h"
-
-#include "DNA_action_types.h"
-#include "DNA_armature_types.h"
-#include "DNA_camera_types.h"
-#include "DNA_curve_types.h"
-#include "DNA_effect_types.h"
-#include "DNA_image_types.h"
-#include "DNA_ipo_types.h"
-#include "DNA_key_types.h"
-#include "DNA_lamp_types.h"
-#include "DNA_lattice_types.h"
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_meta_types.h"
+
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 #include "DNA_screen_types.h"
 #include "BIF_glutil.h"
 
 #include "BKE_context.h"
-#include "BKE_global.h"
-#include "BKE_utildefines.h"
+
 
 #include "ED_image.h"
 #include "ED_view3d.h"
 
 #include "BLI_math.h"
+#include "BLI_utildefines.h"
 
 //#include "blendef.h"
 //
 //#include "mydevice.h"
 
-#include "WM_types.h"
 #include "UI_resources.h"
 
 
@@ -88,7 +69,7 @@
 static void drawObjectConstraint(TransInfo *t);
 
 /* ************************** CONSTRAINTS ************************* */
-void constraintAutoValues(TransInfo *t, float vec[3])
+static void constraintAutoValues(TransInfo *t, float vec[3])
 {
        int mode = t->con.mode;
        if (mode & CON_APPLY)
@@ -174,14 +155,16 @@ static void postConstraintChecks(TransInfo *t, float vec[3], float pvec[3]) {
 
        if (hasNumInput(&t->num)) {
                applyNumInput(&t->num, vec);
+               removeAspectRatio(t, vec);
                constraintNumInput(t, vec);
        }
 
        /* autovalues is operator param, use that directly but not if snapping is forced */
        if (t->flag & T_AUTOVALUES && (t->tsnap.status & SNAP_FORCED) == 0)
        {
-               VECCOPY(vec, t->auto_values);
+               mul_v3_m3v3(vec, t->con.imtx, t->auto_values);
                constraintAutoValues(t, vec);
+               /* inverse transformation at the end */
        }
 
        if (t->con.mode & CON_AXIS0) {
@@ -198,15 +181,21 @@ static void postConstraintChecks(TransInfo *t, float vec[3], float pvec[3]) {
 }
 
 static void axisProjection(TransInfo *t, float axis[3], float in[3], float out[3]) {
-       float norm[3], vec[3], factor;
+       float norm[3], vec[3], factor, angle;
 
        if(in[0]==0.0f && in[1]==0.0f && in[2]==0.0f)
                return;
 
+       angle = fabs(angle_v3v3(axis, t->viewinv[2]));
+       if (angle > M_PI / 2) {
+               angle = M_PI - angle;
+       }
+       angle = 180.0f * angle / M_PI;
+
        /* For when view is parallel to constraint... will cause NaNs otherwise
           So we take vertical motion in 3D space and apply it to the
           constraint axis. Nice for camera grab + MMB */
-       if(1.0f - fabs(dot_v3v3(axis, t->viewinv[2])) < 0.000001f) {
+       if(angle < 5.0f) {
                project_v3_v3v3(vec, in, t->viewinv[1]);
                factor = dot_v3v3(t->viewinv[1], vec) * 2.0f;
                /* since camera distance is quite relative, use quadratic relationship. holding shift can compensate */
@@ -240,7 +229,7 @@ static void axisProjection(TransInfo *t, float axis[3], float in[3], float out[3
                                mul_v3_fl(out, 1000000000);
                        } else {
                                mul_v3_fl(out, -1000000000);
-                       }
+       }
                } else {
                        add_v3_v3v3(v2, t->con.center, axis);
                        add_v3_v3v3(v4, v, norm);
@@ -290,7 +279,7 @@ static void applyAxisConstraintVec(TransInfo *t, TransData *td, float in[3], flo
                mul_m3_v3(t->con.pmtx, out);
 
                // With snap, a projection is alright, no need to correct for view alignment
-               if ((t->tsnap.status & SNAP_ON) == 0) {
+               if (!(t->tsnap.mode != SCE_SNAP_MODE_INCREMENT && activeSnap(t))) {
                        if (getConstraintSpaceDimension(t) == 2) {
                                if (out[0] != 0.0f || out[1] != 0.0f || out[2] != 0.0f) {
                                        planeProjection(t, in, out);
@@ -316,7 +305,7 @@ static void applyAxisConstraintVec(TransInfo *t, TransData *td, float in[3], flo
 }
 
 /*
- * Generic callback for object based spacial constraints applied to linear motion
+ * Generic callback for object based spatial constraints applied to linear motion
  *
  * At first, the following is applied to the first data in the array
  * The IN vector in projected into the constrained space and then further
@@ -536,6 +525,7 @@ void setLocalConstraint(TransInfo *t, int mode, const char text[]) {
        if (t->flag & T_EDIT) {
                float obmat[3][3];
                copy_m3_m4(obmat, t->scene->obedit->obmat);
+               normalize_m3(obmat);
                setConstraint(t, obmat, mode, text);
        }
        else {
@@ -571,9 +561,8 @@ void setUserConstraint(TransInfo *t, short orientation, int mode, const char fte
        switch(orientation) {
        case V3D_MANIP_GLOBAL:
                {
-                       float mtx[3][3];
+                       float mtx[3][3]= MAT3_UNITY;
                        sprintf(text, ftext, "global");
-                       unit_m3(mtx);
                        setConstraint(t, mtx, mode, text);
                }
                break;
@@ -599,12 +588,14 @@ void setUserConstraint(TransInfo *t, short orientation, int mode, const char fte
                break;
        }
 
+       t->con.orientation = orientation;
+
        t->con.mode |= CON_USER;
 }
 
 /*----------------- DRAWING CONSTRAINTS -------------------*/
 
-void drawConstraint(const struct bContext *C, TransInfo *t)
+void drawConstraint(TransInfo *t)
 {
        TransCon *tc = &(t->con);
 
@@ -629,35 +620,40 @@ void drawConstraint(const struct bContext *C, TransInfo *t)
                if (tc->mode & CON_SELECT) {
                        float vec[3];
                        char col2[3] = {255,255,255};
+                       int depth_test_enabled;
+
                        convertViewVec(t, vec, (short)(t->mval[0] - t->con.imval[0]), (short)(t->mval[1] - t->con.imval[1]));
-                       add_v3_v3v3(vec, vec, tc->center);
+                       add_v3_v3(vec, tc->center);
 
-                       drawLine(t, tc->center, tc->mtx[0], 'x', 0);
-                       drawLine(t, tc->center, tc->mtx[1], 'y', 0);
-                       drawLine(t, tc->center, tc->mtx[2], 'z', 0);
+                       drawLine(t, tc->center, tc->mtx[0], 'X', 0);
+                       drawLine(t, tc->center, tc->mtx[1], 'Y', 0);
+                       drawLine(t, tc->center, tc->mtx[2], 'Z', 0);
 
                        glColor3ubv((GLubyte *)col2);
 
-                       glDisable(GL_DEPTH_TEST);
+                       depth_test_enabled = glIsEnabled(GL_DEPTH_TEST);
+                       if(depth_test_enabled)
+                               glDisable(GL_DEPTH_TEST);
+
                        setlinestyle(1);
                        glBegin(GL_LINE_STRIP);
                                glVertex3fv(tc->center);
                                glVertex3fv(vec);
                        glEnd();
                        setlinestyle(0);
-                       // TRANSFORM_FIX_ME
-                       //if(G.vd->zbuf)
+
+                       if(depth_test_enabled)
                                glEnable(GL_DEPTH_TEST);
                }
 
                if (tc->mode & CON_AXIS0) {
-                       drawLine(t, tc->center, tc->mtx[0], 'x', DRAWLIGHT);
+                       drawLine(t, tc->center, tc->mtx[0], 'X', DRAWLIGHT);
                }
                if (tc->mode & CON_AXIS1) {
-                       drawLine(t, tc->center, tc->mtx[1], 'y', DRAWLIGHT);
+                       drawLine(t, tc->center, tc->mtx[1], 'Y', DRAWLIGHT);
                }
                if (tc->mode & CON_AXIS2) {
-                       drawLine(t, tc->center, tc->mtx[2], 'z', DRAWLIGHT);
+                       drawLine(t, tc->center, tc->mtx[2], 'Z', DRAWLIGHT);
                }
        }
 }
@@ -668,6 +664,7 @@ void drawPropCircle(const struct bContext *C, TransInfo *t)
        if (t->flag & T_PROP_EDIT) {
                RegionView3D *rv3d = CTX_wm_region_view3d(C);
                float tmat[4][4], imat[4][4];
+               float center[3];
 
                UI_ThemeColor(TH_GRID);
 
@@ -684,9 +681,11 @@ void drawPropCircle(const struct bContext *C, TransInfo *t)
 
                glPushMatrix();
 
+               VECCOPY(center, t->center);
+
                if((t->spacetype == SPACE_VIEW3D) && t->obedit)
                {
-                       glMultMatrixf(t->obedit->obmat); /* because t->center is in local space */
+                       mul_m4_v3(t->obedit->obmat, center); /* because t->center is in local space */
                }
                else if(t->spacetype == SPACE_IMAGE)
                {
@@ -697,7 +696,7 @@ void drawPropCircle(const struct bContext *C, TransInfo *t)
                }
 
                set_inverted_drawing(1);
-               drawcircball(GL_LINE_LOOP, t->center, t->prop_size, imat);
+               drawcircball(GL_LINE_LOOP, center, t->prop_size, imat);
                set_inverted_drawing(0);
 
                glPopMatrix();
@@ -715,26 +714,26 @@ static void drawObjectConstraint(TransInfo *t) {
           Without drawing the first light, users have little clue what they are doing.
         */
        if (t->con.mode & CON_AXIS0) {
-               drawLine(t, td->ob->obmat[3], td->axismtx[0], 'x', DRAWLIGHT);
+               drawLine(t, td->ob->obmat[3], td->axismtx[0], 'X', DRAWLIGHT);
        }
        if (t->con.mode & CON_AXIS1) {
-               drawLine(t, td->ob->obmat[3], td->axismtx[1], 'y', DRAWLIGHT);
+               drawLine(t, td->ob->obmat[3], td->axismtx[1], 'Y', DRAWLIGHT);
        }
        if (t->con.mode & CON_AXIS2) {
-               drawLine(t, td->ob->obmat[3], td->axismtx[2], 'z', DRAWLIGHT);
+               drawLine(t, td->ob->obmat[3], td->axismtx[2], 'Z', DRAWLIGHT);
        }
 
        td++;
 
        for(i=1;i<t->total;i++,td++) {
                if (t->con.mode & CON_AXIS0) {
-                       drawLine(t, td->ob->obmat[3], td->axismtx[0], 'x', 0);
+                       drawLine(t, td->ob->obmat[3], td->axismtx[0], 'X', 0);
                }
                if (t->con.mode & CON_AXIS1) {
-                       drawLine(t, td->ob->obmat[3], td->axismtx[1], 'y', 0);
+                       drawLine(t, td->ob->obmat[3], td->axismtx[1], 'Y', 0);
                }
                if (t->con.mode & CON_AXIS2) {
-                       drawLine(t, td->ob->obmat[3], td->axismtx[2], 'z', 0);
+                       drawLine(t, td->ob->obmat[3], td->axismtx[2], 'Z', 0);
                }
        }
 }
@@ -859,14 +858,14 @@ static void setNearestAxis3d(TransInfo *t)
 
                mul_v3_fl(axis, zfac);
                /* now we can project to get window coordinate */
-               add_v3_v3v3(axis, axis, t->con.center);
+               add_v3_v3(axis, t->con.center);
                projectIntView(t, axis, icoord);
 
                axis[0] = (float)(icoord[0] - t->center2d[0]);
                axis[1] = (float)(icoord[1] - t->center2d[1]);
                axis[2] = 0.0f;
 
-               if (normalize_v3(axis) != 0.0f) {
+                if (normalize_v3(axis) != 0.0f) {
                        project_v3_v3v3(proj, mvec, axis);
                        sub_v3_v3v3(axis, mvec, proj);
                        len[i] = normalize_v3(axis);