Radians -> Degrees (in UI)
authorMatt Ebb <matt@mke3.net>
Mon, 25 Jan 2010 06:24:05 +0000 (06:24 +0000)
committerMatt Ebb <matt@mke3.net>
Mon, 25 Jan 2010 06:24:05 +0000 (06:24 +0000)
Rotations are now stored internally as radians, while exposing degrees in the UI -
in the graph editor and UI controls. This is done in two areas:
1) Using the unit system to convert RNA data to display as degrees in the UI controls
2) FCurves now use degrees for rotation, so you can edit in the graph editor what
you see in the UI.

All rotation data is consistently accessible in DNA and RNA as radians, degrees are only
used for the UI controls and graph editor.

This commit includes conversions will convert old files (stored data and also fcurve data)
to the new units, hopefully everything should go smoothly!

Part of this also changes a few properties that were hard-coded as degrees before (such
as IK pole angle and brush texture rotation) to also use the same consistent system of
radians (dna/rna) and degrees (ui).

Thanks to Joshua for hints and review here too.

15 files changed:
source/blender/blenkernel/intern/anim_sys.c
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/unit.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/animation/keyframing.c
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_regions.c
source/blender/ikplugin/intern/iksolver_plugin.c
source/blender/makesdna/DNA_anim_types.h
source/blender/makesrna/intern/rna_brush.c
source/blender/makesrna/intern/rna_constraint.c
source/blender/makesrna/intern/rna_curve.c
source/blender/makesrna/intern/rna_fcurve.c
source/blender/makesrna/intern/rna_pose.c
source/gameengine/Converter/BL_BlenderDataConversion.cpp

index c617ca33e8a27fde0c6a9b77efa2eded61382d6c..46f569a531016119e79cf5913ca7db7db8843dc6 100644 (file)
@@ -730,6 +730,11 @@ static short animsys_write_rna_setting (PointerRNA *ptr, char *path, int array_i
                /* set value - only for animatable numerical values */
                if (RNA_property_animateable(&new_ptr, prop)) 
                {
+                       /* convert to radians */
+                       if (RNA_SUBTYPE_UNIT(RNA_property_subtype(prop)) == PROP_UNIT_ROTATION) {
+                               value *= M_PI/180.0;
+                       }
+                       
                        switch (RNA_property_type(prop)) 
                        {
                                case PROP_BOOLEAN:
@@ -1466,6 +1471,11 @@ void nladata_flush_channels (ListBase *channels)
                int array_index= nec->index;
                float value= nec->value;
                
+               /* convert to radians */
+               if (RNA_SUBTYPE_UNIT(RNA_property_subtype(prop)) == PROP_UNIT_ROTATION) {
+                       value *= M_PI/180.0;
+               }
+               
                /* write values - see animsys_write_rna_setting() to sync the code */
                switch (RNA_property_type(prop)) 
                {
index 4de148803f8e15be0ebf1d7c95490b001bfb3bab..5338f1c96ba0d7b4a7402c51fcee32271b078282 100644 (file)
@@ -1353,10 +1353,7 @@ static void rotlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *t
        
        mat4_to_eulO( eul, cob->rotOrder,cob->matrix);
        
-       /* eulers: radians to degrees! */
-       eul[0] = (float)(eul[0] / M_PI * 180);
-       eul[1] = (float)(eul[1] / M_PI * 180);
-       eul[2] = (float)(eul[2] / M_PI * 180);
+       /* constraint data uses radians internally */
        
        /* limiting of euler values... */
        if (data->flag & LIMIT_XROT) {
@@ -1381,11 +1378,6 @@ static void rotlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *t
                        eul[2] = data->zmax;
        }
                
-       /* eulers: degrees to radians ! */
-       eul[0] = (float)(eul[0] / 180 * M_PI); 
-       eul[1] = (float)(eul[1] / 180 * M_PI);
-       eul[2] = (float)(eul[2] / 180 * M_PI);
-       
        loc_eulO_size_to_mat4(cob->matrix, loc, eul, size, cob->rotOrder);
 }
 
index 1f72c894cc8b410702a55d47411d11a387416e06..1025bee6b8eccd43f1b554d8828f8398224ed5ea 100644 (file)
@@ -119,11 +119,18 @@ static struct bUnitDef buNaturalTimeDef[] = {
 };
 static struct bUnitCollection buNaturalTimeCollecton = {buNaturalTimeDef, 3, 0, sizeof(buNaturalTimeDef)/sizeof(bUnitDef)};
 
+
+static struct bUnitDef buNaturalRotDef[] = {
+       {"degree", "degrees",                   "°", NULL, "Degrees",          M_PI/180.f, 0.0,        B_UNIT_DEF_NONE},
+       {NULL, NULL, NULL, NULL, NULL, 0.0, 0.0}
+};
+static struct bUnitCollection buNaturalRotCollection = {buNaturalRotDef, 0, 0, sizeof(buNaturalRotDef)/sizeof(bUnitDef)};
+
 #define UNIT_SYSTEM_MAX 3
 static struct bUnitCollection *bUnitSystems[][8] = {
-       {0,0,0,0,0,0,0,0},
-       {0,&buMetricLenCollecton, 0,0,0,0, &buNaturalTimeCollecton,0}, /* metric */
-       {0,&buImperialLenCollecton, 0,0,0,0, &buNaturalTimeCollecton,0}, /* imperial */
+       {0,0,0,0,0,&buNaturalRotCollection,&buNaturalTimeCollecton,0},
+       {0,&buMetricLenCollecton, 0,0,0, &buNaturalRotCollection, &buNaturalTimeCollecton,0}, /* metric */
+       {0,&buImperialLenCollecton, 0,0,0,&buNaturalRotCollection, &buNaturalTimeCollecton,0}, /* imperial */
        {0,0,0,0,0,0,0,0}
 };
 
@@ -451,23 +458,25 @@ int bUnit_ReplaceString(char *str, int len_max, char *str_prev, double scale_pre
                bUnitCollection *usys_iter;
                int system_iter;
 
-               for(system_iter= 1; system_iter<UNIT_SYSTEM_MAX; system_iter++) {
+               for(system_iter= 0; system_iter<UNIT_SYSTEM_MAX; system_iter++) {
                        if (system_iter != system) {
                                usys_iter= unit_get_system(system_iter, type);
-                               for(unit= usys_iter->units; unit->name; unit++) {
-
-                                       if((unit->flag & B_UNIT_DEF_SUPPRESS) == 0) {
-                                               int ofs = 0;
-                                               /* incase there are multiple instances */
-                                               while((ofs=unit_replace(str+ofs, len_max-ofs, str_tmp, scale_pref, unit)))
-                                                       change= 1;
+                               if (usys_iter) {
+                                       for(unit= usys_iter->units; unit->name; unit++) {
+
+                                               if((unit->flag & B_UNIT_DEF_SUPPRESS) == 0) {
+                                                       int ofs = 0;
+                                                       /* incase there are multiple instances */
+                                                       while((ofs=unit_replace(str+ofs, len_max-ofs, str_tmp, scale_pref, unit)))
+                                                               change= 1;
+                                               }
                                        }
                                }
                        }
                }
        }
        unit= NULL;
-
+       
        if(change==0) {
                /* no units given so infer a unit from the previous string or default */
                if(str_prev) {
@@ -482,9 +491,10 @@ int bUnit_ReplaceString(char *str, int len_max, char *str_prev, double scale_pre
                        }
                }
 
-               if(unit==NULL)
+               if(unit==NULL || unit->name == NULL)
                        unit= unit_default(usys);
 
+
                /* add the unit prefix and re-run, use brackets incase there was an expression given */
                if(snprintf(str_tmp, sizeof(str_tmp), "(%s)%s", str, unit->name) < sizeof(str_tmp)) {
                        strncpy(str, str_tmp, len_max);
@@ -530,7 +540,6 @@ int bUnit_ReplaceString(char *str, int len_max, char *str_prev, double scale_pre
                }
        }
 
-       // printf("replace %s\n", str);
        return change;
 }
 
index b10c13eef8dbced5368f9d88f26afb6f7f760fae..dcebd5d69e2b72387663831cf9e7fdacf6b9cb59 100644 (file)
@@ -6439,6 +6439,30 @@ static void do_version_mtex_factor_2_50(MTex **mtex_array, short idtype)
        }
 }
 
+static void do_version_fcurve_radians_degrees_250(FCurve *fcu)
+{
+       int i;
+       
+       if (fcu->bezt) {
+               for (i=0; i<fcu->totvert; i++) {
+                       BezTriple *bt = fcu->bezt+i;
+                       
+                       bt->vec[0][1] *= 180.0/M_PI;
+                       bt->vec[1][1] *= 180.0/M_PI;
+                       bt->vec[2][1] *= 180.0/M_PI;
+               }
+       }
+       else if (fcu->fpt) {
+               for (i=0; i<fcu->totvert; i++) {
+                       FPoint *fpt = fcu->fpt+i;
+                       
+                       fpt->vec[1] *= 180.0/M_PI;
+               }
+       }
+       
+       fcu->flag |= FCURVE_ROTATION_DEGREES;
+}
+
 static void do_versions(FileData *fd, Library *lib, Main *main)
 {
        /* WATCH IT!!!: pointers from libdata have not been converted */
@@ -10493,7 +10517,68 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
        
        /* put 2.50 compatibility code here until next subversion bump */
        if (1) {
-               ;
+               {
+                       /* still missing:
+                          - Pose channel IK (min x/y/z, max x/y/z)
+                        */
+                       bAction *act;
+                       Object *ob;
+                       
+                       float rads_per_deg = M_PI / 180.0;
+                       
+                       /* convert degrees to radians for internal use */
+                       for (ob=main->object.first; ob; ob=ob->id.next) {
+                               AnimData *adt = BKE_animdata_from_id((ID *)ob);
+                               bConstraint *con;
+                               
+                               for     (con=ob->constraints.first; con; con=con->next) {
+                                       
+                                       if(con->type==CONSTRAINT_TYPE_RIGIDBODYJOINT) {
+                                               bRigidBodyJointConstraint *data = con->data;
+                                               data->axX *= rads_per_deg;
+                                               data->axY *= rads_per_deg;
+                                               data->axZ *= rads_per_deg;
+                                       }
+                                       else if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
+                                               bKinematicConstraint *data = con->data;
+                                               data->poleangle *= rads_per_deg;
+                                       }
+                                       else if(con->type==CONSTRAINT_TYPE_ROTLIMIT) {
+                                               bRotLimitConstraint *data = con->data;
+                                               FCurve *fcu;
+
+                                               /* do it here, slightly less chance of getting a false positive */
+                                               for (fcu=adt->action->curves.first; fcu; fcu=fcu->next) {
+                                                       if (strcmp(fcu->rna_path, "minimum_x")==0)
+                                                               do_version_fcurve_radians_degrees_250(fcu);
+                                               }
+                                               
+                                               data->xmin *= rads_per_deg;
+                                               data->xmax *= rads_per_deg;
+                                               data->ymin *= rads_per_deg;
+                                               data->ymax *= rads_per_deg;
+                                               data->zmin *= rads_per_deg;
+                                               data->zmax *= rads_per_deg;
+
+                                       }
+                               }
+                       }
+                       
+                       /* convert fcurve values to be stored in degrees */
+                       for (act = main->action.first; act; act=act->id.next) {
+                               FCurve *fcu;
+                               
+                               /* convert over named properties with PROP_UNIT_ROTATION time of this change */
+                               for (fcu=act->curves.first; fcu; fcu=fcu->next) {
+                                       if (strcmp(fcu->rna_path, "rotation_euler")==0)
+                                               do_version_fcurve_radians_degrees_250(fcu);
+                                       else if (strcmp(fcu->rna_path, "delta_rotation_euler")==0)
+                                               do_version_fcurve_radians_degrees_250(fcu);
+                                       else if (strcmp(fcu->rna_path, "pole_angle")==0)
+                                               do_version_fcurve_radians_degrees_250(fcu);
+                               }
+                       }
+               }
        }
 
        /* WATCH IT!!!: pointers from libdata have not been converted yet here! */
index e042d2731fde6cc9931a8505b896a11c581c5161..b88592fc66fabea1f8d78c2475c3dd7fdbc1a7af 100644 (file)
@@ -783,6 +783,11 @@ short insert_keyframe_direct (PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, fl
                curval= setting_get_rna_value(&ptr, prop, fcu->array_index);
        }
        
+       /* convert to degrees */
+       if (RNA_SUBTYPE_UNIT(RNA_property_subtype(prop)) == PROP_UNIT_ROTATION) {
+               curval *= 180.0/M_PI;
+       }
+       
        /* only insert keyframes where they are needed */
        if (flag & INSERTKEY_NEEDED) {
                short insert_mode;
@@ -895,6 +900,10 @@ short insert_keyframe (ID *id, bAction *act, const char group[], const char rna_
                        }
                }
                
+               /* mark the curve if it's a new rotation curve */
+               if ((fcu->totvert == 0) && (RNA_SUBTYPE_UNIT(RNA_property_subtype(prop)) == PROP_UNIT_ROTATION))
+                       fcu->flag |= FCURVE_ROTATION_DEGREES;
+               
                /* insert keyframe */
                ret += insert_keyframe_direct(ptr, prop, fcu, cfra, flag);
        }
index 8b59ff604b9418760a5e0edd400fdd9a996b1900..82b53840ed3330abd66850704e93455abf407d3f 100644 (file)
@@ -1225,13 +1225,19 @@ int ui_is_but_float(uiBut *but)
 int ui_is_but_unit(uiBut *but)
 {
        Scene *scene= CTX_data_scene((bContext *)but->block->evil_C);
-       if(scene->unit.system == USER_UNIT_NONE)
-               return 0;
-
+       int unit_type;
+       
        if(but->rnaprop==NULL)
                return 0;
+       
+       unit_type = RNA_SUBTYPE_UNIT(RNA_property_subtype(but->rnaprop));
+       
+       if(scene->unit.system == USER_UNIT_NONE) {
+          if (unit_type != PROP_UNIT_ROTATION)
+                       return 0;
+       }
 
-       if(RNA_SUBTYPE_UNIT_VALUE(RNA_property_subtype(but->rnaprop))==0)
+       if(unit_type == PROP_UNIT_NONE)
                return 0;
 
        return 1;
@@ -1406,12 +1412,12 @@ int ui_get_but_string_max_length(uiBut *but)
 static double ui_get_but_scale_unit(uiBut *but, double value)
 {
        Scene *scene= CTX_data_scene((bContext *)but->block->evil_C);
-       int subtype= RNA_property_subtype(but->rnaprop);
+       int subtype= RNA_SUBTYPE_UNIT(RNA_property_subtype(but->rnaprop));
 
-       if(subtype & PROP_UNIT_LENGTH) {
+       if(subtype == PROP_UNIT_LENGTH) {
                return value * scene->unit.scale_length;
        }
-       else if(subtype & PROP_UNIT_TIME) { /* WARNING - using evil_C :| */
+       else if(subtype == PROP_UNIT_TIME) { /* WARNING - using evil_C :| */
                return FRA2TIME(value);
        }
        else {
@@ -1596,7 +1602,7 @@ int ui_set_but_string(bContext *C, uiBut *but, const char *str)
 
                        BLI_strncpy(str_unit_convert, str, sizeof(str_unit_convert));
 
-                       if(scene->unit.system != USER_UNIT_NONE && unit_type) {
+                       if(ui_is_but_unit(but)) {
                                /* ugly, use the draw string to get the value, this could cause problems if it includes some text which resolves to a unit */
                                bUnit_ReplaceString(str_unit_convert, sizeof(str_unit_convert), but->drawstr, ui_get_but_scale_unit(but, 1.0), scene->unit.system, unit_type);
                        }
index cbc005c0f8e02b7fd67821dee1369129fb9a5f80..b3a3da5e91686ecca3759342228443e694b2f9fa 100644 (file)
@@ -390,6 +390,16 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
        }
 
        if(but->rnaprop) {
+               int unit_type = RNA_SUBTYPE_UNIT(RNA_property_subtype(but->rnaprop));
+               
+               if (unit_type == PROP_UNIT_ROTATION) {
+                       if (RNA_property_type(but->rnaprop) == PROP_FLOAT) {
+                               BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "Radians: %f", RNA_property_float_get_index(&but->rnapoin, but->rnaprop, but->rnaindex));
+                               data->linedark[data->totline]= 1;
+                               data->totline++;
+                       }
+               }
+               
                if(but->flag & UI_BUT_DRIVEN) {
                        if(ui_but_anim_expression_get(but, buf, sizeof(buf))) {
                                /* expression */
index e9378a7e12b796c55fad652f36539c7ec6bb90ac..c80bf43ce00d53e1665e9a7bb3de02617e1f3e86 100644 (file)
@@ -413,7 +413,7 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree)
                if(data->weight != 0.0) {
                        if(poleconstrain)
                                IK_SolverSetPoleVectorConstraint(solver, iktarget, goalpos,
-                                       polepos, data->poleangle*M_PI/180, (poleangledata == data));
+                                       polepos, data->poleangle, (poleangledata == data));
                        IK_SolverAddGoal(solver, iktarget, goalpos, data->weight);
                }
                if((data->flag & CONSTRAINT_IK_ROT) && (data->orientweight != 0.0))
@@ -426,7 +426,7 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree)
        IK_Solve(solver, 0.0f, tree->iterations);
 
        if(poleangledata)
-               poleangledata->poleangle= IK_SolverGetPoleAngle(solver)*180/M_PI;
+               poleangledata->poleangle= IK_SolverGetPoleAngle(solver);
 
        IK_FreeSolver(solver);
 
index d1fa4616cbcc3c11ea6d8305ad0415438c716580..8230c7b46d0ed11fccb3ae300eadf3bd89294afe 100644 (file)
@@ -445,6 +445,9 @@ typedef enum eFCurve_Flags {
        FCURVE_INT_VALUES               = (1<<11),
                /* curve can only have certain discrete-number values (no interpolation at all, for enums/booleans) */
        FCURVE_DISCRETE_VALUES  = (1<<12),
+               /* curve represents a rotation value stored internally in the curve in degrees */
+       FCURVE_ROTATION_DEGREES = (1<<13),
+       
 } eFCurve_Flags;
 
 /* extrapolation modes (only simple value 'extending') */
index 1c5ea81a2853f6fc43ec72193120fb9116789419..5504daf29943f63febcce74447097c5d4b4c7bdd 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <stdlib.h>
+#include <math.h>
 
 #include "RNA_define.h"
 #include "RNA_types.h"
@@ -49,20 +50,6 @@ static void rna_Brush_update(Main *bmain, Scene *scene, PointerRNA *ptr)
        WM_main_add_notifier(NC_BRUSH|NA_EDITED, br);
 }
 
-static float rna_BrushTextureSlot_angle_get(PointerRNA *ptr)
-{
-       MTex *tex= (MTex*)ptr->data;
-       const float conv = 57.295779506;
-       return tex->rot * conv;
-}
-
-static void rna_BrushTextureSlot_angle_set(PointerRNA *ptr, float v)
-{
-       MTex *tex= (MTex*)ptr->data;
-       const float conv = 0.017453293;
-       tex->rot = v * conv;
-}
-
 #else
 
 static void rna_def_brush_texture_slot(BlenderRNA *brna)
@@ -82,8 +69,7 @@ static void rna_def_brush_texture_slot(BlenderRNA *brna)
 
        prop= RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE);
        RNA_def_property_float_sdna(prop, NULL, "rot");
-       RNA_def_property_range(prop, 0, 360);
-       RNA_def_property_float_funcs(prop, "rna_BrushTextureSlot_angle_get", "rna_BrushTextureSlot_angle_set", NULL);
+       RNA_def_property_range(prop, 0, M_PI*2);
        RNA_def_property_ui_text(prop, "Angle", "Defines brush texture rotation.");
        RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
 
index 5ec8d438c42462335c78e7b12ca2377e6b852d0b..1f023555456a1a2cf2f40f36adc4fd4c622779f7 100644 (file)
@@ -29,6 +29,8 @@
 
 #include "rna_internal.h"
 
+#include "BLI_math.h"
+
 #include "DNA_action_types.h"
 #include "DNA_constraint_types.h"
 #include "DNA_modifier_types.h"
@@ -488,9 +490,9 @@ static void rna_def_constraint_kinematic(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Pole Sub-Target", "");
        RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_dependency_update");
 
-       prop= RNA_def_property(srna, "pole_angle", PROP_FLOAT, PROP_ANGLE); // XXX - todo, convert to rad
+       prop= RNA_def_property(srna, "pole_angle", PROP_FLOAT, PROP_ANGLE);
        RNA_def_property_float_sdna(prop, NULL, "poleangle");
-       RNA_def_property_range(prop, -180.0f, 180.f);
+       RNA_def_property_range(prop, -M_PI, M_PI);
        RNA_def_property_ui_text(prop, "Pole Angle", "Pole rotation offset.");
        RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
 
@@ -1190,21 +1192,21 @@ static void rna_def_constraint_rigid_body_joint(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Pivot Z", "Offset pivot on Z.");
        RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
 
-       prop= RNA_def_property(srna, "axis_x", PROP_FLOAT, PROP_ANGLE); // XXX - convert to radians
+       prop= RNA_def_property(srna, "axis_x", PROP_FLOAT, PROP_ANGLE);
        RNA_def_property_float_sdna(prop, NULL, "axX");
-       RNA_def_property_range(prop, -360.0, 360.f);
+       RNA_def_property_range(prop, -M_PI*2, M_PI*2);
        RNA_def_property_ui_text(prop, "Axis X", "Rotate pivot on X axis in degrees.");
        RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
 
-       prop= RNA_def_property(srna, "axis_y", PROP_FLOAT, PROP_ANGLE); // XXX - convert to radians
+       prop= RNA_def_property(srna, "axis_y", PROP_FLOAT, PROP_ANGLE);
        RNA_def_property_float_sdna(prop, NULL, "axY");
-       RNA_def_property_range(prop, -360.0, 360.f);
+       RNA_def_property_range(prop, -M_PI*2, M_PI*2);
        RNA_def_property_ui_text(prop, "Axis Y", "Rotate pivot on Y axis in degrees.");
        RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
 
-       prop= RNA_def_property(srna, "axis_z", PROP_FLOAT, PROP_ANGLE); // XXX - convert to radians
+       prop= RNA_def_property(srna, "axis_z", PROP_FLOAT, PROP_ANGLE);
        RNA_def_property_float_sdna(prop, NULL, "axZ");
-       RNA_def_property_range(prop, -360.0, 360.f);
+       RNA_def_property_range(prop, -M_PI*2, M_PI*2);
        RNA_def_property_ui_text(prop, "Axis Z", "Rotate pivot on Z axis in degrees.");
        RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
        
index 72efdc48bf2b91e66e505efc5fd3e5f6b7f98dd3..652352c0ecb5d16e4da8519488a958b77ef3d6e7 100644 (file)
@@ -50,12 +50,6 @@ EnumPropertyItem beztriple_interpolation_mode_items[] = {
                {BEZT_IPO_LIN, "LINEAR", 0, "Linear", ""},
                {BEZT_IPO_BEZ, "BEZIER", 0, "Bezier", ""},
                {0, NULL, 0, NULL, NULL}};
-               
-EnumPropertyItem beztriple_keyframe_type_items[] = {
-               {BEZT_KEYTYPE_KEYFRAME, "KEYFRAME", 0, "Keyframe", ""},
-               {BEZT_KEYTYPE_BREAKDOWN, "BREAKDOWN", 0, "Breakdown", ""},
-               {BEZT_KEYTYPE_EXTREME, "EXTREME", 0, "Extreme", ""},
-               {0, NULL, 0, NULL, NULL}};
 
 #ifdef RNA_RUNTIME
 
@@ -427,12 +421,6 @@ static void rna_def_beztriple(BlenderRNA *brna)
        RNA_def_property_ui_text(prop, "Interpolation", "(For F-Curves Only) Interpolation to use for segment of curve starting from current BezTriple.");
        //RNA_def_property_update(prop, 0, "rna_Curve_update_data"); // this should be an F-Curve update call instead...
        
-       prop= RNA_def_property(srna, "keyframe_type", PROP_ENUM, PROP_NONE);
-       RNA_def_property_enum_sdna(prop, NULL, "hide");
-       RNA_def_property_enum_items(prop, beztriple_keyframe_type_items);
-       RNA_def_property_ui_text(prop, "Keyframe Type", "(For F-Curves only) The type of keyframe this control point defines.");
-       //RNA_def_property_update(prop, 0, "rna_Curve_update_data"); // this should be an F-Curve update call instead...
-
        /* Vector values */
        prop= RNA_def_property(srna, "handle1", PROP_FLOAT, PROP_TRANSLATION);
        RNA_def_property_array(prop, 3);
index c8b20f2de542e493636d560da70976c8b6a59039..ee94d761f03b581a8380fc49cd56a9e8c0904bbd 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 #include <stdlib.h>
+#include <math.h>
 
 #include "RNA_access.h"
 #include "RNA_define.h"
@@ -51,6 +52,12 @@ EnumPropertyItem fmodifier_type_items[] = {
        {FMODIFIER_TYPE_LIMITS, "LIMITS", 0, "Limits", ""},
        {0, NULL, 0, NULL, NULL}};
 
+EnumPropertyItem beztriple_keyframe_type_items[] = {
+       {BEZT_KEYTYPE_KEYFRAME, "KEYFRAME", 0, "Keyframe", ""},
+       {BEZT_KEYTYPE_BREAKDOWN, "BREAKDOWN", 0, "Breakdown", ""},
+       {BEZT_KEYTYPE_EXTREME, "EXTREME", 0, "Extreme", ""},
+       {0, NULL, 0, NULL, NULL}};
+
 #ifdef RNA_RUNTIME
 
 #include "WM_api.h"
@@ -225,6 +232,159 @@ static void rna_DriverVariable_type_set(PointerRNA *ptr, int value)
 
 /* ****************************** */
 
+static int rna_fpoint_is_rotation(ID *id, FPoint *fpt)
+{
+       bAction *act = (bAction *)id;
+       FCurve *fcu;
+       int found=0;
+       
+       for (fcu=act->curves.first; fcu; fcu=fcu->next) {
+               if (fcu->fpt) {
+                       /* the following check works because 
+                        * the fpoints are always allocated in contiguous blocks */
+                       if (fpt >= fcu->fpt && fpt < fcu->fpt+fcu->totvert) {
+                               found=1;
+                               break;
+                       }
+               }
+       }
+       
+       if (!found)
+               return 0;
+       
+       return (fcu->flag & FCURVE_ROTATION_DEGREES);
+}
+
+
+static void rna_FPoint_vec_get(PointerRNA *ptr, float *values)
+{
+       ID *id = (ID *)ptr->id.data;
+       FPoint *fpt= (FPoint*)ptr->data;
+       
+       values[0]= fpt->vec[0];
+       
+       if (rna_fpoint_is_rotation(id, fpt))
+               values[1]= fpt->vec[1] * M_PI/180.0;
+       else
+               values[1]= fpt->vec[1];
+}
+
+static void rna_FPoint_vec_set(PointerRNA *ptr, const float *values)
+{
+       ID *id = (ID *)ptr->id.data;
+       FPoint *fpt= (FPoint*)ptr->data;
+       
+        fpt->vec[0] = values[0];
+       
+       if (rna_fpoint_is_rotation(id, fpt))
+               fpt->vec[1]= values[1] * 180.0 / M_PI;
+       else
+               fpt->vec[1]= values[1];
+}
+
+static int rna_beztriple_is_rotation(ID *id, BezTriple *bt)
+{
+       bAction *act = (bAction *)id;
+       FCurve *fcu;
+       int found=0;
+       
+       for (fcu=act->curves.first; fcu; fcu=fcu->next) {
+               if (fcu->bezt) {
+                       /* the following check works because 
+                        * the beztriples are always allocated in contiguous blocks */
+                       if (bt >= fcu->bezt && bt < fcu->bezt+fcu->totvert) {
+                               found=1;
+                               break;
+                       }
+               }
+       }
+       
+       if (!found)
+               return 0;
+       
+       return (fcu->flag & FCURVE_ROTATION_DEGREES);
+}
+
+static void rna_BezTriple_handle1_get(PointerRNA *ptr, float *values)
+{
+       ID *id = (ID *)ptr->id.data;
+       BezTriple *bt= (BezTriple*)ptr->data;
+       
+       values[0]= bt->vec[0][0];
+       
+       if (rna_beztriple_is_rotation(id, bt))
+               values[1]= bt->vec[0][1] * M_PI/180.0;
+       else
+               values[1]= bt->vec[0][1];
+}
+
+static void rna_BezTriple_handle1_set(PointerRNA *ptr, const float *values)
+{
+       ID *id = (ID *)ptr->id.data;
+       BezTriple *bt= (BezTriple*)ptr->data;
+       
+       bt->vec[0][0]= values[0];
+       
+       if (rna_beztriple_is_rotation(id, bt))
+               bt->vec[0][1]= values[1] * 180.0 / M_PI;
+       else
+               bt->vec[0][1]= values[1];
+}
+
+static void rna_BezTriple_handle2_get(PointerRNA *ptr, float *values)
+{
+       ID *id = (ID *)ptr->id.data;
+       BezTriple *bt= (BezTriple*)ptr->data;
+       
+       values[0]= bt->vec[2][0];
+       
+       if (rna_beztriple_is_rotation(id, bt))
+               values[1]= bt->vec[2][1] * M_PI/180.0;
+       else
+               values[1]= bt->vec[2][1];
+}
+
+static void rna_BezTriple_handle2_set(PointerRNA *ptr, const float *values)
+{
+       ID *id = (ID *)ptr->id.data;
+       BezTriple *bt= (BezTriple*)ptr->data;
+       
+       bt->vec[2][0]= values[0];
+       
+       if (rna_beztriple_is_rotation(id, bt))
+               bt->vec[2][1]= values[1] * 180.0 / M_PI;
+       else
+               bt->vec[2][1]= values[1];
+}
+
+static void rna_BezTriple_ctrlpoint_get(PointerRNA *ptr, float *values)
+{
+       ID *id = (ID *)ptr->id.data;
+       BezTriple *bt= (BezTriple*)ptr->data;
+
+       values[0]= bt->vec[1][0];
+       
+       if (rna_beztriple_is_rotation(id, bt))
+               values[1]= bt->vec[1][1] * M_PI/180.0;
+       else
+               values[1]= bt->vec[1][1];
+}
+
+static void rna_BezTriple_ctrlpoint_set(PointerRNA *ptr, const float *values)
+{
+       ID *id = (ID *)ptr->id.data;
+       BezTriple *bt= (BezTriple*)ptr->data;
+       
+       bt->vec[1][0]= values[0];
+       
+       if (rna_beztriple_is_rotation(id, bt))
+               bt->vec[1][1]= values[1] * 180.0 / M_PI;
+       else
+               bt->vec[1][1]= values[1];
+}
+
+/* ****************************** */
+
 static void rna_FCurve_RnaPath_get(PointerRNA *ptr, char *value)
 {
        FCurve *fcu= (FCurve *)ptr->data;
@@ -903,10 +1063,105 @@ static void rna_def_fpoint(BlenderRNA *brna)
        /* Vector value */
        prop= RNA_def_property(srna, "point", PROP_FLOAT, PROP_XYZ);
        RNA_def_property_array(prop, 2);
-       RNA_def_property_float_sdna(prop, NULL, "vec");
+       RNA_def_property_float_funcs(prop, "rna_FPoint_vec_get", "rna_FPoint_vec_set", NULL);
        RNA_def_property_ui_text(prop, "Point", "Point coordinates");
 }
 
+
+/* duplicate of BezTriple in rna_curve.c
+ * but with F-Curve specific options updates/functionality */
+static void rna_def_fcurvebeztriple(BlenderRNA *brna)
+{
+       StructRNA *srna;
+       PropertyRNA *prop;
+       
+       static EnumPropertyItem beztriple_handle_type_items[] = {
+               {HD_FREE, "FREE", 0, "Free", ""},
+               {HD_AUTO, "AUTO", 0, "Auto", ""},
+               {HD_VECT, "VECTOR", 0, "Vector", ""},
+               {HD_ALIGN, "ALIGNED", 0, "Aligned", ""},
+               {HD_AUTO_ANIM, "AUTO_CLAMPED", 0, "Auto Clamped", ""},
+               {0, NULL, 0, NULL, NULL}};
+       
+       static EnumPropertyItem beztriple_interpolation_mode_items[] = {
+               {BEZT_IPO_CONST, "CONSTANT", 0, "Constant", ""},
+               {BEZT_IPO_LIN, "LINEAR", 0, "Linear", ""},
+               {BEZT_IPO_BEZ, "BEZIER", 0, "Bezier", ""},
+               {0, NULL, 0, NULL, NULL}};
+       
+       srna= RNA_def_struct(brna, "FCurveBezierSplinePoint", NULL);
+       RNA_def_struct_sdna(srna, "BezTriple");
+       RNA_def_struct_ui_text(srna, "FCurve Bezier Curve Point", "Bezier curve point with two handles, used in F-Curves.");
+       
+       /* Boolean values */
+       prop= RNA_def_property(srna, "selected_handle1", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "f1", 0);
+       RNA_def_property_ui_text(prop, "Handle 1 selected", "Handle 1 selection status");
+       RNA_def_property_update(prop, 0, NULL);
+       
+       prop= RNA_def_property(srna, "selected_handle2", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "f3", 0);
+       RNA_def_property_ui_text(prop, "Handle 2 selected", "Handle 2 selection status");
+       RNA_def_property_update(prop, 0, NULL);
+       
+       prop= RNA_def_property(srna, "selected_control_point", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "f2", 0);
+       RNA_def_property_ui_text(prop, "Control Point selected", "Control point selection status");
+       RNA_def_property_update(prop, 0, NULL);
+       
+       prop= RNA_def_property(srna, "hidden", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "hide", 0);
+       RNA_def_property_ui_text(prop, "Hidden", "Visibility status");
+       RNA_def_property_update(prop, 0, NULL);
+       
+       /* Enums */
+       prop= RNA_def_property(srna, "handle1_type", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "h1");
+       RNA_def_property_enum_items(prop, beztriple_handle_type_items);
+       RNA_def_property_ui_text(prop, "Handle 1 Type", "Handle types");
+       RNA_def_property_update(prop, 0, NULL);
+       
+       prop= RNA_def_property(srna, "handle2_type", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "h2");
+       RNA_def_property_enum_items(prop, beztriple_handle_type_items);
+       RNA_def_property_ui_text(prop, "Handle 2 Type", "Handle types");
+       RNA_def_property_update(prop, 0, NULL);
+       
+       prop= RNA_def_property(srna, "interpolation", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "ipo");
+       RNA_def_property_enum_items(prop, beztriple_interpolation_mode_items);
+       RNA_def_property_ui_text(prop, "Interpolation", "(For F-Curves Only) Interpolation to use for segment of curve starting from current BezTriple.");
+       //RNA_def_property_update(prop, 0, "rna_Curve_update_data"); // this should be an F-Curve update call instead...
+       
+       prop= RNA_def_property(srna, "keyframe_type", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "hide");
+       RNA_def_property_enum_items(prop, beztriple_keyframe_type_items);
+       RNA_def_property_ui_text(prop, "Keyframe Type", "(For F-Curves only) The type of keyframe this control point defines.");
+       //RNA_def_property_update(prop, 0, "rna_Curve_update_data"); // this should be an F-Curve update call instead...
+       
+       /* Vector values */
+       prop= RNA_def_property(srna, "handle1", PROP_FLOAT, PROP_TRANSLATION);
+       RNA_def_property_array(prop, 2);
+       RNA_def_property_float_funcs(prop, "rna_BezTriple_handle1_get", "rna_BezTriple_handle1_set", NULL);
+       RNA_def_property_ui_text(prop, "Handle 1", "Coordinates of the first handle");
+       RNA_def_property_update(prop, 0, NULL);
+       
+       prop= RNA_def_property(srna, "co", PROP_FLOAT, PROP_TRANSLATION);
+       RNA_def_property_array(prop, 2);
+       RNA_def_property_float_funcs(prop, "rna_BezTriple_ctrlpoint_get", "rna_BezTriple_ctrlpoint_set", NULL);
+       RNA_def_property_ui_text(prop, "Control Point", "Coordinates of the control point");
+       RNA_def_property_update(prop, 0, NULL);
+       
+       prop= RNA_def_property(srna, "handle2", PROP_FLOAT, PROP_TRANSLATION);
+       RNA_def_property_array(prop, 2);
+       RNA_def_property_float_funcs(prop, "rna_BezTriple_handle2_get", "rna_BezTriple_handle2_set", NULL);
+       RNA_def_property_ui_text(prop, "Handle 2", "Coordinates of the second handle");
+       RNA_def_property_update(prop, 0, NULL);
+       
+       /* Number values */
+}
+
+
 static void rna_def_fcurve_modifiers(BlenderRNA *brna, PropertyRNA *cprop)
 {
        /* add modifiers */
@@ -1016,7 +1271,7 @@ static void rna_def_fcurve(BlenderRNA *brna)
 
        prop= RNA_def_property(srna, "keyframe_points", PROP_COLLECTION, PROP_NONE);
        RNA_def_property_collection_sdna(prop, NULL, "bezt", "totvert");
-       RNA_def_property_struct_type(prop, "BezierSplinePoint");
+       RNA_def_property_struct_type(prop, "FCurveBezierSplinePoint");
        RNA_def_property_ui_text(prop, "Keyframes", "User-editable keyframes");
        
        prop= RNA_def_property(srna, "modifiers", PROP_COLLECTION, PROP_NONE);
@@ -1030,6 +1285,7 @@ static void rna_def_fcurve(BlenderRNA *brna)
 
 void RNA_def_fcurve(BlenderRNA *brna)
 {
+       rna_def_fcurvebeztriple(brna);
        rna_def_fcurve(brna);
        rna_def_fpoint(brna);
        
index 0616894e9029651539cf5488b27c88dbf3b69546..b7a656eee1efa49011c2a52e5193645bcac88677 100644 (file)
@@ -860,42 +860,42 @@ static void rna_def_pose_channel(BlenderRNA *brna)
        RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
        RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_IK_update");
        
-       prop= RNA_def_property(srna, "ik_min_x", PROP_FLOAT, PROP_ANGLE);
+       prop= RNA_def_property(srna, "ik_min_x", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "limitmin[0]");
        RNA_def_property_range(prop, -180.0f, 0.0f);
        RNA_def_property_ui_text(prop, "IK X Minimum", "Minimum angles for IK Limit");
        RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
        RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_IK_update");
 
-       prop= RNA_def_property(srna, "ik_max_x", PROP_FLOAT, PROP_ANGLE);
+       prop= RNA_def_property(srna, "ik_max_x", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "limitmax[0]");
        RNA_def_property_range(prop, 0.0f, 180.0f);
        RNA_def_property_ui_text(prop, "IK X Maximum", "Maximum angles for IK Limit");
        RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
        RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_IK_update");
 
-       prop= RNA_def_property(srna, "ik_min_y", PROP_FLOAT, PROP_ANGLE);
+       prop= RNA_def_property(srna, "ik_min_y", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "limitmin[1]");
        RNA_def_property_range(prop, -180.0f, 0.0f);
        RNA_def_property_ui_text(prop, "IK Y Minimum", "Minimum angles for IK Limit");
        RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
        RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_IK_update");
 
-       prop= RNA_def_property(srna, "ik_max_y", PROP_FLOAT, PROP_ANGLE);
+       prop= RNA_def_property(srna, "ik_max_y", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "limitmax[1]");
        RNA_def_property_range(prop, 0.0f, 180.0f);
        RNA_def_property_ui_text(prop, "IK Y Maximum", "Maximum angles for IK Limit");
        RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
        RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_IK_update");
 
-       prop= RNA_def_property(srna, "ik_min_z", PROP_FLOAT, PROP_ANGLE);
+       prop= RNA_def_property(srna, "ik_min_z", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "limitmin[2]");
        RNA_def_property_range(prop, -180.0f, 0.0f);
        RNA_def_property_ui_text(prop, "IK Z Minimum", "Minimum angles for IK Limit");
        RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
        RNA_def_property_update(prop, NC_OBJECT|ND_POSE, "rna_Pose_IK_update");
 
-       prop= RNA_def_property(srna, "ik_max_z", PROP_FLOAT, PROP_ANGLE);
+       prop= RNA_def_property(srna, "ik_max_z", PROP_FLOAT, PROP_NONE);
        RNA_def_property_float_sdna(prop, NULL, "limitmax[2]");
        RNA_def_property_range(prop, 0.0f, 180.0f);
        RNA_def_property_ui_text(prop, "IK Z Maximum", "Maximum angles for IK Limit");
index a54c229593fdbf5d94e8cb7094f973848054b99c..1d95ef13ca8a1dc6d16e0b5bdda05f47a632af8b 100644 (file)
@@ -2584,13 +2584,11 @@ void BL_ConvertBlenderObjects(struct Main* maggie,
 
                                                if (gameobj->GetPhysicsController())
                                                {
-                                                       float radsPerDeg = 6.283185307179586232f / 360.f;
-
                                                        PHY_IPhysicsController* physctrl = (PHY_IPhysicsController*) gameobj->GetPhysicsController()->GetUserData();
                                                        //we need to pass a full constraint frame, not just axis
                                    
                                                        //localConstraintFrameBasis
-                                                       MT_Matrix3x3 localCFrame(MT_Vector3(radsPerDeg*dat->axX,radsPerDeg*dat->axY,radsPerDeg*dat->axZ));
+                                                       MT_Matrix3x3 localCFrame(MT_Vector3(dat->axX,dat->axY,dat->axZ));
                                                        MT_Vector3 axis0 = localCFrame.getColumn(0);
                                                        MT_Vector3 axis1 = localCFrame.getColumn(1);
                                                        MT_Vector3 axis2 = localCFrame.getColumn(2);