svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r23023:HEAD
authorCampbell Barton <ideasman42@gmail.com>
Mon, 7 Sep 2009 08:37:28 +0000 (08:37 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Mon, 7 Sep 2009 08:37:28 +0000 (08:37 +0000)
1  2 
source/blender/blenkernel/intern/curve.c
source/blender/blenlib/BLI_arithb.h
source/blender/blenlib/intern/arithb.c
source/blender/imbuf/intern/anim5.c
source/blender/makesdna/DNA_curve_types.h

index 228523aa661c554201b30d07230d07cb76f911ee,709507a9b26c75f66ca59fed09d0e44a323feca6..ca0d4a5fdc3e1a42a831c56e6904b187188dfedd
  
  /* for dereferencing pointers */
  #include "DNA_ID.h"  
 -#include "DNA_vfont_types.h"  
  #include "DNA_key_types.h"  
 -#include "DNA_ipo_types.h"  
 +#include "DNA_scene_types.h"  
 +#include "DNA_vfont_types.h"  
  
 -#include "BKE_global.h" 
 -#include "BKE_main.h"  
 -#include "BKE_utildefines.h"  // VECCOPY
 -#include "BKE_object.h"  
 -#include "BKE_mesh.h" 
 +#include "BKE_animsys.h"
 +#include "BKE_anim.h"  
  #include "BKE_curve.h"  
  #include "BKE_displist.h"  
 -#include "BKE_ipo.h"  
 -#include "BKE_anim.h"  
 -#include "BKE_library.h"  
 +#include "BKE_font.h" 
 +#include "BKE_global.h" 
  #include "BKE_key.h"  
 +#include "BKE_library.h"  
 +#include "BKE_main.h"  
 +#include "BKE_mesh.h" 
 +#include "BKE_object.h"  
 +#include "BKE_utildefines.h"  // VECCOPY
  
  
  /* globals */
  
 -extern ListBase editNurb;  /* editcurve.c */
 -
  /* local */
  int cu_isectLL(float *v1, float *v2, float *v3, float *v4, 
                           short cox, short coy, 
@@@ -85,42 -86,20 +85,42 @@@ void unlink_curve(Curve *cu
        cu->vfont= 0;
        if(cu->key) cu->key->id.us--;
        cu->key= 0;
 -      if(cu->ipo) cu->ipo->id.us--;
 -      cu->ipo= 0;
  }
  
 +/* frees editcurve entirely */
 +void BKE_free_editfont(Curve *cu)
 +{
 +      if(cu->editfont) {
 +              EditFont *ef= cu->editfont;
 +              
 +              if(ef->oldstr) MEM_freeN(ef->oldstr);
 +              if(ef->oldstrinfo) MEM_freeN(ef->oldstrinfo);
 +              if(ef->textbuf) MEM_freeN(ef->textbuf);
 +              if(ef->textbufinfo) MEM_freeN(ef->textbufinfo);
 +              if(ef->copybuf) MEM_freeN(ef->copybuf);
 +              if(ef->copybufinfo) MEM_freeN(ef->copybufinfo);
 +              
 +              MEM_freeN(ef);
 +              cu->editfont= NULL;
 +      }
 +}
  
 -/* niet curve zelf vrijgeven */
 +/* don't free curve itself */
  void free_curve(Curve *cu)
  {
 -
        freeNurblist(&cu->nurb);
        BLI_freelistN(&cu->bev);
        freedisplist(&cu->disp);
 +      BKE_free_editfont(cu);
        
 +      if(cu->editnurb) {
 +              freeNurblist(cu->editnurb);
 +              MEM_freeN(cu->editnurb);
 +              cu->editnurb= NULL;
 +      }
 +
        unlink_curve(cu);
 +      BKE_free_animdata((ID *)cu);
        
        if(cu->mat) MEM_freeN(cu->mat);
        if(cu->str) MEM_freeN(cu->str);
@@@ -149,18 -128,6 +149,18 @@@ Curve *add_curve(char *name, int type
        
        cu->bb= unit_boundbox();
        
 +      if(type==OB_FONT) {
 +              cu->vfont= cu->vfontb= cu->vfonti= cu->vfontbi= get_builtin_font();
 +              cu->vfont->id.us+=4;
 +              cu->str= MEM_mallocN(12, "str");
 +              strcpy(cu->str, "Text");
 +              cu->pos= 4;
 +              cu->strinfo= MEM_callocN(12*sizeof(CharInfo), "strinfo new");
 +              cu->totbox= cu->actbox= 1;
 +              cu->tb= MEM_callocN(MAXTEXTBOX*sizeof(TextBox), "textbox");
 +              cu->tb[0].w = cu->tb[0].h = 0.0;
 +      }
 +      
        return cu;
  }
  
@@@ -190,12 -157,8 +190,12 @@@ Curve *copy_curve(Curve *cu
        cun->bev.first= cun->bev.last= 0;
        cun->path= 0;
  
 +      cun->editnurb= NULL;
 +
 +#if 0 // XXX old animation system
        /* single user ipo too */
        if(cun->ipo) cun->ipo= copy_ipo(cun->ipo);
 +#endif // XXX old animation system
  
        id_us_plus((ID *)cun->vfont);
        id_us_plus((ID *)cun->vfontb);  
@@@ -1070,7 -1033,7 +1070,7 @@@ float *make_orco_surf(Object *ob
        /* NOTE: This routine is tied to the order of vertex
         * built by displist and as passed to the renderer.
         */
 -float *make_orco_curve(Object *ob)
 +float *make_orco_curve(Scene *scene, Object *ob)
  {
        Curve *cu = ob->data;
        DispList *dl;
  
        if (!(cu->flag&CU_UV_ORCO) && cu->key && cu->key->refkey) {
                cp_cu_key(cu, cu->key->refkey, 0, count_curveverts(&cu->nurb));
 -              makeDispListCurveTypes(ob, 1);
 +              makeDispListCurveTypes(scene, ob, 1);
                remakeDisp = 1;
        }
  
        }
  
        if (remakeDisp) {
 -              makeDispListCurveTypes(ob, 0);
 +              makeDispListCurveTypes(scene, ob, 0);
        }
  
        return coord_array;
  
  /* ***************** BEVEL ****************** */
  
 -void makebevelcurve(Object *ob, ListBase *disp)
 +void makebevelcurve(Scene *scene, Object *ob, ListBase *disp)
  {
        DispList *dl, *dlnew;
        Curve *bevcu, *cu;
        disp->first = disp->last = NULL;
  
        /* if a font object is being edited, then do nothing */
 -      if( ob == G.obedit && ob->type == OB_FONT ) return;
 +// XXX        if( ob == obedit && ob->type == OB_FONT ) return;
  
        if(cu->bevobj && cu->bevobj!=ob) {
                if(cu->bevobj->type==OB_CURVE) {
  
                                dl= bevcu->disp.first;
                                if(dl==0) {
 -                                      makeDispListCurveTypes(cu->bevobj, 0);
 +                                      makeDispListCurveTypes(scene, cu->bevobj, 0);
                                        dl= bevcu->disp.first;
                                }
                                while(dl) {
@@@ -1566,7 -1529,7 +1566,7 @@@ void makeBevelList(Object *ob
        /* STEP 1: MAKE POLYS  */
  
        BLI_freelistN(&(cu->bev));
 -      if(ob==G.obedit && ob->type!=OB_FONT) nu= editNurb.first;
 +      if(cu->editnurb && ob->type!=OB_FONT) nu= cu->editnurb->first;
        else nu= cu->nurb.first;
        
        while(nu) {
                bl= blnext;
        }
  
--      /* STEP 3: COUNT POLYS TELLEN AND AUTOHOLE */
++      /* STEP 3: POLYS COUNT AND AUTOHOLE */
        bl= cu->bev.first;
        poly= 0;
        while(bl) {
                if(bl->nr && bl->poly>=0) {
                        poly++;
                        bl->poly= poly;
--                      bl->gat= 0;     /* 'gat' is dutch for hole */
++                      bl->hole= 0;
                }
                bl= bl->next;
        }
                        sd1= sortdata+ (a-1);
                        for(b=a-1; b>=0; b--, sd1--) {  /* all polys to the left */
                                if(bevelinside(sd1->bl, bl)) {
--                                      bl->gat= 1- sd1->bl->gat;
++                                      bl->hole= 1- sd1->bl->hole;
                                        break;
                                }
                        }
                if((cu->flag & CU_3D)==0) {
                        sd= sortdata;
                        for(a=0; a<poly; a++, sd++) {
--                              if(sd->bl->gat==sd->dir) {
++                              if(sd->bl->hole==sd->dir) {
                                        bl= sd->bl;
                                        bevp1= (BevPoint *)(bl+1);
                                        bevp2= bevp1+ (bl->nr-1);
                }       /* this has to be >2 points */
                else if(cu->flag & CU_NO_TWIST && cu->flag & CU_3D && bl->poly != -1) {
  
--                      /* Special case, cyclic curve with no twisy. tricky... */
++                      /* Special case, cyclic curve with no twist. tricky... */
  
                        float quat[4], q[4], cross[3];
  
                                while(nr--) {
        
                                        /* Normalizes */
--                                      Vec3ToTangent(vec, &bevp0->x, &bevp1->x, &bevp2->x);
++                                      VecBisect3(vec, &bevp0->x, &bevp1->x, &bevp2->x);
  
                                        if(bl->nr==nr+1) { /* first time */
                                                vectoquat(vec, 5, 1, quat);
                        nr= bl->nr;
                        while(nr--) {
  
--                              Vec3ToTangent(vec, &bevp0->x, &bevp1->x, &bevp2->x);
++                              VecBisect3(vec, &bevp0->x, &bevp1->x, &bevp2->x);
  
                                quat_tmp1= (float *)bevp1->mat;
                                quat_tmp2= quat_tmp1+4;
                                if(cu->flag & CU_3D) {  /* 3D */
  
                                        /* Normalizes */
--                                      Vec3ToTangent(vec, &bevp0->x, &bevp1->x, &bevp2->x);
++                                      VecBisect3(vec, &bevp0->x, &bevp1->x, &bevp2->x);
  
                                        if(bl->nr==nr+1 || !(cu->flag & CU_NO_TWIST)) { /* first time */
                                                vectoquat(vec, 5, 1, quat);
                                        }
                                        QUATCOPY(quat_prev, quat); /* quat_prev can't have the tilt applied */
                                        VECCOPY(vec_prev, vec);
--
++                                      
                                        AxisAngleToQuat(q, vec, bevp1->alfa);
                                        QuatMul(quat, q, quat);
                                        QuatToMat3(quat, bevp1->mat);
   *            1: nothing,  1:auto,  2:vector,  3:aligned
   */
  
 -/* mode: is not zero when IpoCurve, is 2 when forced horizontal for autohandles */
 +/* mode: is not zero when FCurve, is 2 when forced horizontal for autohandles */
  void calchandleNurb(BezTriple *bezt, BezTriple *prev, BezTriple *next, int mode)
  {
        float *p1,*p2,*p3, pt[3];
@@@ -2448,18 -2411,18 +2448,18 @@@ void autocalchandlesNurb(Nurb *nu, int 
        calchandlesNurb(nu);
  }
  
 -void autocalchandlesNurb_all(int flag)
 +void autocalchandlesNurb_all(ListBase *editnurb, int flag)
  {
        Nurb *nu;
        
 -      nu= editNurb.first;
 +      nu= editnurb->first;
        while(nu) {
                autocalchandlesNurb(nu, flag);
                nu= nu->next;
        }
  }
  
 -void sethandlesNurb(short code)
 +void sethandlesNurb(ListBase *editnurb, short code)
  {
        /* code==1: set autohandle */
        /* code==2: set vectorhandle */
        short a, ok=0;
  
        if(code==1 || code==2) {
 -              nu= editNurb.first;
 +              nu= editnurb->first;
                while(nu) {
                        if( (nu->type & 7)==CU_BEZIER) {
                                bezt= nu->bezt;
        else {
                /* there is 1 handle not FREE: FREE it all, else make ALIGNED  */
                
 -              nu= editNurb.first;
 +              nu= editnurb->first;
                if (code == 5) {
                        ok = HD_ALIGN;
                } else if (code == 6) {
                        if(ok) ok= HD_FREE;
                        else ok= HD_ALIGN;
                }
 -              nu= editNurb.first;
 +              nu= editnurb->first;
                while(nu) {
                        if( (nu->type & 7)==CU_BEZIER) {
                                bezt= nu->bezt;
index 2ce4e8e268c05532aea2208f3969e88933c12a8b,63b351016d49713dbe2c5e84fa9be36bd727f9a1..6deb6edf9fb6d42245384cf307fcd57638360a16
  extern "C" {
  #endif
  
 +#ifdef WIN32
 +#define _USE_MATH_DEFINES
 +#endif
 +
 +#include <math.h>
 +
  #ifndef M_PI
  #define M_PI          3.14159265358979323846
  #endif
  #define M_1_PI                0.318309886183790671538
  #endif
  
 +#ifndef M_E
 +#define M_E             2.7182818284590452354
 +#endif
 +#ifndef M_LOG2E
 +#define M_LOG2E         1.4426950408889634074
 +#endif
 +#ifndef M_LOG10E
 +#define M_LOG10E        0.43429448190325182765
 +#endif
 +#ifndef M_LN2
 +#define M_LN2           0.69314718055994530942
 +#endif
 +#ifndef M_LN10
 +#define M_LN10          2.30258509299404568402
 +#endif
 +
 +#ifndef sqrtf
 +#define sqrtf(a) ((float)sqrt(a))
 +#endif
 +#ifndef powf
 +#define powf(a, b) ((float)pow(a, b))
 +#endif
 +#ifndef cosf
 +#define cosf(a) ((float)cos(a))
 +#endif
 +#ifndef sinf
 +#define sinf(a) ((float)sin(a))
 +#endif
 +#ifndef acosf
 +#define acosf(a) ((float)acos(a))
 +#endif
 +#ifndef asinf
 +#define asinf(a) ((float)asin(a))
 +#endif
 +#ifndef atan2f
 +#define atan2f(a, b) ((float)atan2(a, b))
 +#endif
 +#ifndef tanf
 +#define tanf(a) ((float)tan(a))
 +#endif
 +#ifndef atanf
 +#define atanf(a) ((float)atan(a))
 +#endif
 +#ifndef floorf
 +#define floorf(a) ((float)floor(a))
 +#endif
 +#ifndef ceilf
 +#define ceilf(a) ((float)ceil(a))
 +#endif
 +#ifndef fabsf
 +#define fabsf(a) ((float)fabs(a))
 +#endif
 +#ifndef logf
 +#define logf(a) ((float)log(a))
 +#endif
 +#ifndef expf
 +#define expf(a) ((float)exp(a))
 +#endif
 +#ifndef fmodf
 +#define fmodf(a, b) ((float)fmod(a, b))
 +#endif
 +
  #ifdef WIN32
        #ifndef FREE_WINDOWS
                #define isnan(n) _isnan(n)
@@@ -157,9 -89,6 +157,9 @@@ double Sqrt3d(double d)
  float saacos(float fac);
  float saasin(float fac);
  float sasqrt(float fac);
 +float saacosf(float fac);
 +float saasinf(float fac);
 +float sasqrtf(float fac);
  
  int FloatCompare(float *v1, float *v2, float limit);
  int FloatCompare4(float *v1, float *v2, float limit);
@@@ -174,39 -103,7 +174,39 @@@ void CalcNormShort(short *v1, short *v2
  float power_of_2(float val);
  
  /**
 - * @section Euler conversion routines
 + * @section Euler conversion routines (With Custom Order)
 + */
 +
 +/* Defines for rotation orders 
 + * WARNING: must match the ePchan_RotMode in DNA_action_types.h
 + *               order matters - types are saved to file!
 + */
 +typedef enum eEulerRotationOrders {
 +      EULER_ORDER_DEFAULT = 1,        /* Blender 'default' (classic) is basically XYZ */
 +      EULER_ORDER_XYZ = 1,            /* Blender 'default' (classic) - must be as 1 to sync with PoseChannel rotmode */
 +      EULER_ORDER_XZY,
 +      EULER_ORDER_YXZ,
 +      EULER_ORDER_YZX,
 +      EULER_ORDER_ZXY,
 +      EULER_ORDER_ZYX,
 +      /* NOTE: there are about 6 more entries when including duplicated entries too */
 +} eEulerRotationOrders;
 +
 +void EulOToQuat(float eul[3], short order, float quat[4]);
 +void QuatToEulO(float quat[4], float eul[3], short order);
 +
 +void EulOToMat3(float eul[3], short order, float Mat[3][3]);
 +void EulOToMat4(float eul[3], short order, float Mat[4][4]);
 + 
 +void Mat3ToEulO(float Mat[3][3], float eul[3], short order);
 +void Mat4ToEulO(float Mat[4][4], float eul[3], short order);
 +
 +void Mat3ToCompatibleEulO(float mat[3][3], float eul[3], float oldrot[3], short order);
 +
 +void eulerO_rot(float beul[3], float ang, char axis, short order);
 + 
 +/**
 + * @section Euler conversion routines (Blender XYZ)
   */
  
  void EulToMat3(float *eul, float mat[][3]);
@@@ -217,19 -114,15 +217,19 @@@ void Mat4ToEul(float tmat[][4],float *e
  
  void EulToQuat(float *eul, float *quat);
  
 -void compatible_eul(float *eul, float *oldrot);
 -
  void Mat3ToCompatibleEul(float mat[][3], float *eul, float *oldrot);
  
  
 +
 +void compatible_eul(float *eul, float *oldrot);
 +void euler_rot(float *beul, float ang, char axis);
 +
 +
  /**
   * @section Quaternion arithmetic routines
   */
  
 +int  QuatIsNul(float *q);
  void QuatToEul(float *quat, float *eul);
  void QuatOne(float *);
  void QuatMul(float *, float *, float *);
@@@ -251,8 -144,6 +251,8 @@@ void printquat(char *str, float q[4])
  void QuatInterpol(float *result, float *quat1, float *quat2, float t);
  void QuatAdd(float *result, float *quat1, float *quat2, float t);
  
 +void QuatToMat3(float *q, float m[][3]);
 +void QuatToMat4(float *q, float m[][4]);
  
  /**
   * @section matrix multiplication and copying routines
@@@ -362,7 -253,6 +362,7 @@@ void printvec4f(char *str, float v[4])
  
  void VecAddf(float *v, float *v1, float *v2);
  void VecSubf(float *v, float *v1, float *v2);
 +void VecMulVecf(float *v, float *v1, float *v2);
  void VecLerpf(float *target, float *a, float *b, float t);
  void VecMidf(float *v, float *v1, float *v2);
  
@@@ -380,13 -270,15 +380,14 @@@ void AxisAngleToQuat(float *q, float *a
  void RotationBetweenVectorsToQuat(float *q, float v1[3], float v2[3]);
  void vectoquat(float *vec, short axis, short upflag, float *q);
  
--void Vec3ToTangent(float *v, float *v1, float *v2, float *v3);
++void VecReflect(float *out, float *v1, float *v2);
++void VecBisect3(float *v, float *v1, float *v2, float *v3);
  float VecAngle2(float *v1, float *v2);
  float VecAngle3(float *v1, float *v2, float *v3);
  float NormalizedVecAngle2(float *v1, float *v2);
  
  float VecAngle3_2D(float *v1, float *v2, float *v3);
  float NormalizedVecAngle2_2D(float *v1, float *v2);
 -
 -void euler_rot(float *beul, float ang, char axis);
        
  void NormalShortToFloat(float *out, short *in);
  void NormalFloatToShort(short *out, float *in);
@@@ -447,6 -339,7 +448,6 @@@ void rgb_to_ycc(float r, float g, floa
  void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv);
  void xyz_to_rgb(float x, float y, float z, float *r, float *g, float *b, int colorspace);
  int constrain_rgb(float *r, float *g, float *b);
 -void gamma_correct_rgb(float *r, float *g, float *b);
  unsigned int hsv_to_cpack(float h, float s, float v);
  unsigned int rgb_to_cpack(float r, float g, float b);
  void cpack_to_rgb(unsigned int col, float *r, float *g, float *b);
@@@ -458,6 -351,9 +459,6 @@@ void VecStar(float mat[][3],float *vec)
  
  short EenheidsMat(float mat[][3]);
  
 -void QuatToMat3(float *q, float m[][3]);
 -void QuatToMat4(float *q, float m[][4]);
 -
  void Mat3ToQuat_is_ok(float wmat[][3], float *q);
  
  void i_ortho(float left, float right, float bottom, float top, float nearClip, float farClip, float matrix[][4]);
@@@ -468,6 -364,8 +469,6 @@@ void i_rotate(float angle, char axis, f
  
  
  
 -
 -
  void MinMax3(float *min, float *max, float *vec);
  void SizeToMat3(float *size, float mat[][3]);
  void SizeToMat4(float *size, float mat[][4]);
@@@ -487,9 -385,8 +488,9 @@@ void Mat4ToSize(float mat[][4], float *
  
  void triatoquat(float *v1, float *v2, float *v3, float *quat);
  
 -void LocEulSizeToMat4(float mat[][4], float loc[3], float eul[3], float size[3]);
 -void LocQuatSizeToMat4(float mat[][4], float loc[3], float quat[4], float size[3]);
 +void LocEulSizeToMat4(float mat[4][4], float loc[3], float eul[3], float size[3]);
 +void LocEulOSizeToMat4(float mat[4][4], float loc[3], float eul[3], float size[3], short rotOrder);
 +void LocQuatSizeToMat4(float mat[4][4], float loc[3], float quat[4], float size[3]);
  
  void tubemap(float x, float y, float z, float *u, float *v);
  void spheremap(float x, float y, float z, float *u, float *v);
@@@ -505,8 -402,6 +506,8 @@@ int AabbIntersectAabb(float min1[3], fl
  void VecfCubicInterpol(float *x1, float *v1, float *x2, float *v2, float t, float *x, float *v);
  void PointInQuad2DUV(float v0[2], float v1[2], float v2[2], float v3[2], float pt[2], float *uv);
  void PointInFace2DUV(int isquad, float v0[2], float v1[2], float v2[2], float v3[2], float pt[2], float *uv);
 +int IsPointInTri2D(float v1[2], float v2[2], float v3[2], float pt[2]);
 +int IsPointInTri2DInts(int x1, int y1, int x2, int y2, int a, int b);
  int point_in_tri_prism(float p[3], float v1[3], float v2[3], float v3[3]);
  
  float lambda_cp_line_ex(float p[3], float l1[3], float l2[3], float cp[3]);
index 55bdc32c4e90198b166da38d54d1390a6dd9b038,970d8f7d0de111edb78fde0b5dcdc06ff9347c5c..96056ba77830a648cdc6f4d3554bdaddffbe8378
@@@ -34,7 -34,6 +34,7 @@@
  
  /* ************************ FUNKTIES **************************** */
  
 +#include <stdlib.h>
  #include <math.h>
  #include <sys/types.h>
  #include <string.h> 
  #define SWAP(type, a, b)      { type sw_ap; sw_ap=(a); (a)=(b); (b)=sw_ap; }
  #define CLAMP(a, b, c)                if((a)<(b)) (a)=(b); else if((a)>(c)) (a)=(c)
  
 -
 -#if defined(WIN32) || defined(__APPLE__)
 -#include <stdlib.h>
 +#ifndef M_PI
  #define M_PI 3.14159265358979323846
 -#define M_SQRT2 1.41421356237309504880   
 +#endif
  
 -#endif /* defined(WIN32) || defined(__APPLE__) */
 +#ifndef M_SQRT2
 +#define M_SQRT2 1.41421356237309504880   
 +#endif
  
  
  float saacos(float fac)
@@@ -92,41 -91,21 +92,41 @@@ float sasqrt(float fac
        return (float)sqrt(fac);
  }
  
 +float saacosf(float fac)
 +{
 +      if(fac<= -1.0f) return (float)M_PI;
 +      else if(fac>=1.0f) return 0.0f;
 +      else return (float)acosf(fac);
 +}
 +
 +float saasinf(float fac)
 +{
 +      if(fac<= -1.0f) return (float)-M_PI/2.0f;
 +      else if(fac>=1.0f) return (float)M_PI/2.0f;
 +      else return (float)asinf(fac);
 +}
 +
 +float sasqrtf(float fac)
 +{
 +      if(fac<=0.0) return 0.0;
 +      return (float)sqrtf(fac);
 +}
 +
  float Normalize(float *n)
  {
        float d;
        
        d= n[0]*n[0]+n[1]*n[1]+n[2]*n[2];
        /* A larger value causes normalize errors in a scaled down models with camera xtreme close */
 -      if(d>1.0e-35F) {
 +      if(d>1.0e-35f) {
                d= (float)sqrt(d);
  
                n[0]/=d; 
                n[1]/=d; 
                n[2]/=d;
        } else {
 -              n[0]=n[1]=n[2]= 0.0;
 -              d= 0.0;
 +              n[0]=n[1]=n[2]= 0.0f;
 +              d= 0.0f;
        }
        return d;
  }
@@@ -1108,10 -1087,6 +1108,10 @@@ void printmatrix3( char *str,  float m[
  
  /* **************** QUATERNIONS ********** */
  
 +int QuatIsNul(float *q)
 +{
 +      return (q[0] == 0 && q[1] == 0 && q[2] == 0 && q[3] == 0);
 +}
  
  void QuatMul(float *q, float *q1, float *q2)
  {
@@@ -1408,6 -1383,22 +1408,6 @@@ void RotationBetweenVectorsToQuat(floa
        AxisAngleToQuat(q, axis, angle);
  }
  
 -void AxisAngleToQuat(float *q, float *axis, float angle)
 -{
 -      float nor[3];
 -      float si;
 -      
 -      VecCopyf(nor, axis);
 -      Normalize(nor);
 -      
 -      angle /= 2;
 -      si = (float)sin(angle);
 -      q[0] = (float)cos(angle);
 -      q[1] = nor[0] * si;
 -      q[2] = nor[1] * si;
 -      q[3] = nor[2] * si;     
 -}
 -
  void vectoquat(float *vec, short axis, short upflag, float *q)
  {
        float q2[4], nor[3], *fp, mat[3][3], angle, si, co, x2, y2, z2, len1;
@@@ -1594,7 -1585,7 +1594,7 @@@ void VecUpMat3(float *vec, float mat[][
  }
  
  /* A & M Watt, Advanced animation and rendering techniques, 1992 ACM press */
 -void QuatInterpolW(float *, float *, float *, float );
 +void QuatInterpolW(float *, float *, float *, float ); // XXX why this?
  
  void QuatInterpolW(float *result, float *quat1, float *quat2, float t)
  {
        cosom = quat1[0]*quat2[0] + quat1[1]*quat2[1] + quat1[2]*quat2[2] + quat1[3]*quat2[3] ;
        
        /* rotate around shortest angle */
 -      if ((1.0 + cosom) > 0.0001) {
 +      if ((1.0f + cosom) > 0.0001f) {
                
 -              if ((1.0 - cosom) > 0.0001) {
 -                      omega = acos(cosom);
 -                      sinom = sin(omega);
 -                      sc1 = sin((1.0 - t) * omega) / sinom;
 -                      sc2 = sin(t * omega) / sinom;
 +              if ((1.0f - cosom) > 0.0001f) {
 +                      omega = (float)acos(cosom);
 +                      sinom = (float)sin(omega);
 +                      sc1 = (float)sin((1.0 - t) * omega) / sinom;
 +                      sc2 = (float)sin(t * omega) / sinom;
                } 
                else {
 -                      sc1 = 1.0 - t;
 +                      sc1 = 1.0f - t;
                        sc2 = t;
                }
                result[0] = sc1*quat1[0] + sc2*quat2[0];
                result[2] = quat2[1];
                result[3] = -quat2[0];
                
 -              sc1 = sin((1.0 - t)*M_PI_2);
 -              sc2 = sin(t*M_PI_2);
 -
 +              sc1 = (float)sin((1.0 - t)*M_PI_2);
 +              sc2 = (float)sin(t*M_PI_2);
 +              
                result[0] = sc1*quat1[0] + sc2*result[0];
                result[1] = sc1*quat1[1] + sc2*result[1];
                result[2] = sc1*quat1[2] + sc2*result[2];
@@@ -1643,7 -1634,7 +1643,7 @@@ void QuatInterpol(float *result, float 
        cosom = quat1[0]*quat2[0] + quat1[1]*quat2[1] + quat1[2]*quat2[2] + quat1[3]*quat2[3] ;
        
        /* rotate around shortest angle */
 -      if (cosom < 0.0) {
 +      if (cosom < 0.0f) {
                cosom = -cosom;
                quat[0]= -quat1[0];
                quat[1]= -quat1[1];
                quat[3]= quat1[3];
        }
        
 -      if ((1.0 - cosom) > 0.0001) {
 -              omega = acos(cosom);
 -              sinom = sin(omega);
 -              sc1 = sin((1 - t) * omega) / sinom;
 -              sc2 = sin(t * omega) / sinom;
 +      if ((1.0f - cosom) > 0.0001f) {
 +              omega = (float)acos(cosom);
 +              sinom = (float)sin(omega);
 +              sc1 = (float)sin((1 - t) * omega) / sinom;
 +              sc2 = (float)sin(t * omega) / sinom;
        } else {
 -              sc1= 1.0 - t;
 +              sc1= 1.0f - t;
                sc2= t;
        }
        
@@@ -1779,7 -1770,7 +1779,7 @@@ void DQuatToMat4(DualQuat *dq, float ma
        QuatCopy(q0, dq->quat);
  
        /* normalize */
 -      len= sqrt(QuatDot(q0, q0)); 
 +      len= (float)sqrt(QuatDot(q0, q0)); 
        if(len != 0.0f)
                QuatMulf(q0, 1.0f/len);
        
  
        /* translation */
        t= dq->trans;
 -      mat[3][0]= 2.0*(-t[0]*q0[1] + t[1]*q0[0] - t[2]*q0[3] + t[3]*q0[2]);
 -      mat[3][1]= 2.0*(-t[0]*q0[2] + t[1]*q0[3] + t[2]*q0[0] - t[3]*q0[1]);
 -      mat[3][2]= 2.0*(-t[0]*q0[3] - t[1]*q0[2] + t[2]*q0[1] + t[3]*q0[0]);
 +      mat[3][0]= 2.0f*(-t[0]*q0[1] + t[1]*q0[0] - t[2]*q0[3] + t[3]*q0[2]);
 +      mat[3][1]= 2.0f*(-t[0]*q0[2] + t[1]*q0[3] + t[2]*q0[0] - t[3]*q0[1]);
 +      mat[3][2]= 2.0f*(-t[0]*q0[3] - t[1]*q0[2] + t[2]*q0[1] + t[3]*q0[0]);
  
        /* note: this does not handle scaling */
  }     
@@@ -1819,10 -1810,10 +1819,10 @@@ void DQuatAddWeighted(DualQuat *dqsum, 
        /* interpolate scale - but only if needed */
        if (dq->scale_weight) {
                float wmat[4][4];
 -
 +              
                if(flipped)     /* we don't want negative weights for scaling */
                        weight= -weight;
 -
 +              
                Mat4CpyMat4(wmat, dq->scale);
                Mat4MulFloat((float*)wmat, weight);
                Mat4AddMat4(dqsum->scale, dqsum->scale, wmat);
@@@ -1839,7 -1830,7 +1839,7 @@@ void DQuatNormalize(DualQuat *dq, floa
        
        if(dq->scale_weight) {
                float addweight= totweight - dq->scale_weight;
 -
 +              
                if(addweight) {
                        dq->scale[0][0] += addweight;
                        dq->scale[1][1] += addweight;
@@@ -2160,13 -2151,6 +2160,13 @@@ void VecSubf(float *v, float *v1, floa
        v[2]= v1[2]- v2[2];
  }
  
 +void VecMulVecf(float *v, float *v1, float *v2)
 +{
 +      v[0] = v1[0] * v2[0];
 +      v[1] = v1[1] * v2[1];
 +      v[2] = v1[2] * v2[2];
 +}
 +
  void VecLerpf(float *target, float *a, float *b, float t)
  {
        float s = 1.0f-t;
@@@ -2208,23 -2192,25 +2208,23 @@@ void VecNegf(float *v1
  
  void VecOrthoBasisf(float *v, float *v1, float *v2)
  {
 -      float f = sqrt(v[0]*v[0] + v[1]*v[1]);
 +      const float f = (float)sqrt(v[0]*v[0] + v[1]*v[1]);
  
        if (f < 1e-35f) {
                // degenerate case
 -              v1[0] = 0.0f; v1[1] = 1.0f; v1[2] = 0.0f;
 -              if (v[2] > 0.0f) {
 -                      v2[0] = 1.0f; v2[1] = v2[2] = 0.0f;
 -              }
 -              else {
 -                      v2[0] = -1.0f; v2[1] = v2[2] = 0.0f;
 -              }
 +              v1[0] = (v[2] < 0.0f) ? -1.0f : 1.0f;
 +              v1[1] = v1[2] = v2[0] = v2[2] = 0.0f;
 +              v2[1] = 1.0f;
        }
        else  {
 -              f = 1.0f/f;
 -              v1[0] = v[1]*f;
 -              v1[1] = -v[0]*f;
 -              v1[2] = 0.0f;
 +              const float d= 1.0f/f;
  
 -              Crossf(v2, v, v1);
 +              v1[0] =  v[1]*d;
 +              v1[1] = -v[0]*d;
 +              v1[2] = 0.0f;
 +              v2[0] = -v[2]*v1[1];
 +              v2[1] = v[2]*v1[0];
 +              v2[2] = v[0]*v1[1] - v[1]*v1[0];
        }
  }
  
@@@ -2358,9 -2344,9 +2358,9 @@@ double Sqrt3d(double d
  
  void NormalShortToFloat(float *out, short *in)
  {
 -      out[0] = in[0] / 32767.0;
 -      out[1] = in[1] / 32767.0;
 -      out[2] = in[2] / 32767.0;
 +      out[0] = in[0] / 32767.0f;
 +      out[1] = in[1] / 32767.0f;
 +      out[2] = in[2] / 32767.0f;
  }
  
  void NormalFloatToShort(short *out, float *in)
@@@ -2497,15 -2483,15 +2497,15 @@@ short IsectLL2Ds(short *v1, short *v2, 
        */
        float div, labda, mu;
        
 -      div= (v2[0]-v1[0])*(v4[1]-v3[1])-(v2[1]-v1[1])*(v4[0]-v3[0]);
 -      if(div==0.0) return -1;
 +      div= (float)((v2[0]-v1[0])*(v4[1]-v3[1])-(v2[1]-v1[1])*(v4[0]-v3[0]));
 +      if(div==0.0f) return -1;
        
        labda= ((float)(v1[1]-v3[1])*(v4[0]-v3[0])-(v1[0]-v3[0])*(v4[1]-v3[1]))/div;
        
        mu= ((float)(v1[1]-v3[1])*(v2[0]-v1[0])-(v1[0]-v3[0])*(v2[1]-v1[1]))/div;
        
 -      if(labda>=0.0 && labda<=1.0 && mu>=0.0 && mu<=1.0) {
 -              if(labda==0.0 || labda==1.0 || mu==0.0 || mu==1.0) return 1;
 +      if(labda>=0.0f && labda<=1.0f && mu>=0.0f && mu<=1.0f) {
 +              if(labda==0.0f || labda==1.0f || mu==0.0f || mu==1.0f) return 1;
                return 2;
        }
        return 0;
@@@ -2664,9 -2650,9 +2664,9 @@@ static int BarycentricWeights(float *v1
  
        /* find best projection of face XY, XZ or YZ: barycentric weights of
           the 2d projected coords are the same and faster to compute */
 -      xn= fabs(n[0]);
 -      yn= fabs(n[1]);
 -      zn= fabs(n[2]);
 +      xn= (float)fabs(n[0]);
 +      yn= (float)fabs(n[1]);
 +      zn= (float)fabs(n[2]);
        if(zn>=xn && zn>=yn) {i= 0; j= 1;}
        else if(yn>=xn && yn>=zn) {i= 0; j= 2;}
        else {i= 1; j= 2;} 
@@@ -2791,241 -2777,6 +2791,241 @@@ void MeanValueWeights(float v[][3], in
  
  /* ************ EULER *************** */
  
 +/* Euler Rotation Order Code:
 + * was adapted from  
 +              ANSI C code from the article
 +              "Euler Angle Conversion"
 +              by Ken Shoemake, shoemake@graphics.cis.upenn.edu
 +              in "Graphics Gems IV", Academic Press, 1994
 + * for use in Blender
 + */
 +
 +/* Type for rotation order info - see wiki for derivation details */
 +typedef struct RotOrderInfo {
 +      short i;                /* first axis index */
 +      short j;                /* second axis index */
 +      short k;                /* third axis index */
 +      short parity;   /* parity of axis permuation (even=0, odd=1) - 'n' in original code */
 +} RotOrderInfo;
 +
 +/* Array of info for Rotation Order calculations 
 + * WARNING: must be kept in same order as eEulerRotationOrders
 + */
 +static RotOrderInfo rotOrders[]= {
 +      /* i, j, k, n */
 +      {0, 1, 2, 0}, // XYZ
 +      {0, 2, 1, 1}, // XZY
 +      {1, 0, 2, 1}, // YXZ
 +      {1, 2, 0, 0}, // YZX
 +      {2, 0, 1, 0}, // ZXY
 +      {2, 1, 0, 1}  // ZYZ
 +};
 +
 +/* Get relevant pointer to rotation order set from the array 
 + * NOTE: since we start at 1 for the values, but arrays index from 0, 
 + *             there is -1 factor involved in this process...
 + */
 +#define GET_ROTATIONORDER_INFO(order) (((order)>=1) ? &rotOrders[(order)-1] : &rotOrders[0])
 +
 +/* Construct quaternion from Euler angles (in radians). */
 +void EulOToQuat(float e[3], short order, float q[4])
 +{
 +      RotOrderInfo *R= GET_ROTATIONORDER_INFO(order); 
 +      short i=R->i,  j=R->j,  k=R->k;
 +      double ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
 +      double a[3];
 +      
 +      ti = e[i]/2; tj = e[j]/2; th = e[k]/2;
 +      
 +      if (R->parity) e[j] = -e[j];
 +      
 +      ci = cos(ti);  cj = cos(tj);  ch = cos(th);
 +      si = sin(ti);  sj = sin(tj);  sh = sin(th);
 +      
 +      cc = ci*ch; cs = ci*sh; 
 +      sc = si*ch; ss = si*sh;
 +      
 +      a[i] = cj*sc - sj*cs;
 +      a[j] = cj*ss + sj*cc;
 +      a[k] = cj*cs - sj*sc;
 +      
 +      q[0] = cj*cc + sj*ss;
 +      q[1] = a[0];
 +      q[2] = a[1];
 +      q[3] = a[2];
 +      
 +      if (R->parity) q[j] = -q[j];
 +}
 +
 +/* Convert quaternion to Euler angles (in radians). */
 +void QuatToEulO(float q[4], float e[3], short order)
 +{
 +      float M[3][3];
 +      
 +      QuatToMat3(q, M);
 +      Mat3ToEulO(M, e, order);
 +}
 +
 +/* Construct 3x3 matrix from Euler angles (in radians). */
 +void EulOToMat3(float e[3], short order, float M[3][3])
 +{
 +      RotOrderInfo *R= GET_ROTATIONORDER_INFO(order); 
 +      short i=R->i,  j=R->j,  k=R->k;
 +      double ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
 +      
 +      if (R->parity) {
 +              ti = -e[i];       tj = -e[j];   th = -e[k];
 +      }
 +      else {
 +              ti = e[i];        tj = e[j];    th = e[k];
 +      }
 +      
 +      ci = cos(ti); cj = cos(tj); ch = cos(th);
 +      si = sin(ti); sj = sin(tj); sh = sin(th);
 +      
 +      cc = ci*ch; cs = ci*sh; 
 +      sc = si*ch; ss = si*sh;
 +      
 +      M[i][i] = cj*ch; M[j][i] = sj*sc-cs; M[k][i] = sj*cc+ss;
 +      M[i][j] = cj*sh; M[j][j] = sj*ss+cc; M[k][j] = sj*cs-sc;
 +      M[i][k] = -sj;   M[j][k] = cj*si;        M[k][k] = cj*ci;
 +}
 +
 +/* Construct 4x4 matrix from Euler angles (in radians). */
 +void EulOToMat4(float e[3], short order, float M[4][4])
 +{
 +      float m[3][3];
 +      
 +      /* for now, we'll just do this the slow way (i.e. copying matrices) */
 +      Mat3Ortho(m);
 +      EulOToMat3(e, order, m);
 +      Mat4CpyMat3(M, m);
 +}
 +
 +/* Convert 3x3 matrix to Euler angles (in radians). */
 +void Mat3ToEulO(float M[3][3], float e[3], short order)
 +{
 +      RotOrderInfo *R= GET_ROTATIONORDER_INFO(order); 
 +      short i=R->i,  j=R->j,  k=R->k;
 +      double cy = sqrt(M[i][i]*M[i][i] + M[i][j]*M[i][j]);
 +      
 +      if (cy > 16*FLT_EPSILON) {
 +              e[i] = atan2(M[j][k], M[k][k]);
 +              e[j] = atan2(-M[i][k], cy);
 +              e[k] = atan2(M[i][j], M[i][i]);
 +      } 
 +      else {
 +              e[i] = atan2(-M[k][j], M[j][j]);
 +              e[j] = atan2(-M[i][k], cy);
 +              e[k] = 0;
 +      }
 +      
 +      if (R->parity) {
 +              e[0] = -e[0]; 
 +              e[1] = -e[1]; 
 +              e[2] = -e[2];
 +      }
 +}
 +
 +/* Convert 4x4 matrix to Euler angles (in radians). */
 +void Mat4ToEulO(float M[4][4], float e[3], short order)
 +{
 +      float m[3][3];
 +      
 +      /* for now, we'll just do this the slow way (i.e. copying matrices) */
 +      Mat3CpyMat4(m, M);
 +      Mat3Ortho(m);
 +      Mat3ToEulO(m, e, order);
 +}
 +
 +/* returns two euler calculation methods, so we can pick the best */
 +static void mat3_to_eulo2(float M[3][3], float *e1, float *e2, short order)
 +{
 +      RotOrderInfo *R= GET_ROTATIONORDER_INFO(order); 
 +      short i=R->i,  j=R->j,  k=R->k;
 +      float m[3][3];
 +      double cy;
 +      
 +      /* process the matrix first */
 +      Mat3CpyMat3(m, M);
 +      Mat3Ortho(m);
 +      
 +      cy= sqrt(m[i][i]*m[i][i] + m[i][j]*m[i][j]);
 +      
 +      if (cy > 16*FLT_EPSILON) {
 +              e1[i] = atan2(m[j][k], m[k][k]);
 +              e1[j] = atan2(-m[i][k], cy);
 +              e1[k] = atan2(m[i][j], m[i][i]);
 +              
 +              e2[i] = atan2(-m[j][k], -m[k][k]);
 +              e2[j] = atan2(-m[i][k], -cy);
 +              e2[k] = atan2(-m[i][j], -m[i][i]);
 +      } 
 +      else {
 +              e1[i] = atan2(-m[k][j], m[j][j]);
 +              e1[j] = atan2(-m[i][k], cy);
 +              e1[k] = 0;
 +              
 +              VecCopyf(e2, e1);
 +      }
 +      
 +      if (R->parity) {
 +              e1[0] = -e1[0]; 
 +              e1[1] = -e1[1]; 
 +              e1[2] = -e1[2];
 +              
 +              e2[0] = -e2[0]; 
 +              e2[1] = -e2[1]; 
 +              e2[2] = -e2[2];
 +      }
 +}
 +
 +/* uses 2 methods to retrieve eulers, and picks the closest */
 +void Mat3ToCompatibleEulO(float mat[3][3], float eul[3], float oldrot[3], short order)
 +{
 +      float eul1[3], eul2[3];
 +      float d1, d2;
 +      
 +      mat3_to_eulo2(mat, eul1, eul2, order);
 +      
 +      compatible_eul(eul1, oldrot);
 +      compatible_eul(eul2, oldrot);
 +      
 +      d1= (float)fabs(eul1[0]-oldrot[0]) + (float)fabs(eul1[1]-oldrot[1]) + (float)fabs(eul1[2]-oldrot[2]);
 +      d2= (float)fabs(eul2[0]-oldrot[0]) + (float)fabs(eul2[1]-oldrot[1]) + (float)fabs(eul2[2]-oldrot[2]);
 +      
 +      /* return best, which is just the one with lowest difference */
 +      if (d1 > d2)
 +              VecCopyf(eul, eul2);
 +      else
 +              VecCopyf(eul, eul1);
 +}
 +
 +/* rotate the given euler by the given angle on the specified axis */
 +// NOTE: is this safe to do with different axis orders?
 +void eulerO_rot(float beul[3], float ang, char axis, short order)
 +{
 +      float eul[3], mat1[3][3], mat2[3][3], totmat[3][3];
 +      
 +      eul[0]= eul[1]= eul[2]= 0.0f;
 +      if (axis=='x') 
 +              eul[0]= ang;
 +      else if (axis=='y') 
 +              eul[1]= ang;
 +      else 
 +              eul[2]= ang;
 +      
 +      EulOToMat3(eul, order, mat1);
 +      EulOToMat3(beul, order, mat2);
 +      
 +      Mat3MulMat3(totmat, mat2, mat1);
 +      
 +      Mat3ToEulO(totmat, beul, order);
 +}
 +
 +/* ************ EULER (old XYZ) *************** */
 +
 +/* XYZ order */
  void EulToMat3( float *eul, float mat[][3])
  {
        double ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
  
  }
  
 +/* XYZ order */
  void EulToMat4( float *eul,float mat[][4])
  {
        double ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
  }
  
  /* returns two euler calculation methods, so we can pick the best */
 +/* XYZ order */
  static void mat3_to_eul2(float tmat[][3], float *eul1, float *eul2)
  {
        float cy, quat[4], mat[3][3];
        }
  }
  
 +/* XYZ order */
  void Mat3ToEul(float tmat[][3], float *eul)
  {
        float eul1[3], eul2[3];
        }
  }
  
 +/* XYZ order */
  void Mat4ToEul(float tmat[][4], float *eul)
  {
        float tempMat[3][3];
  
 -      Mat3CpyMat4 (tempMat, tmat);
 +      Mat3CpyMat4(tempMat, tmat);
        Mat3Ortho(tempMat);
        Mat3ToEul(tempMat, eul);
  }
  
 -void QuatToEul( float *quat, float *eul)
 +/* XYZ order */
 +void QuatToEul(float *quat, float *eul)
  {
        float mat[3][3];
        
        Mat3ToEul(mat, eul);
  }
  
 -
 -void EulToQuat( float *eul, float *quat)
 +/* XYZ order */
 +void EulToQuat(float *eul, float *quat)
  {
      float ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
   
        quat[3] = cj*cs - sj*sc;
  }
  
 -void VecRotToMat3( float *vec, float phi, float mat[][3])
 +/* XYZ order */
 +void euler_rot(float *beul, float ang, char axis)
 +{
 +      float eul[3], mat1[3][3], mat2[3][3], totmat[3][3];
 +      
 +      eul[0]= eul[1]= eul[2]= 0.0f;
 +      if(axis=='x') eul[0]= ang;
 +      else if(axis=='y') eul[1]= ang;
 +      else eul[2]= ang;
 +      
 +      EulToMat3(eul, mat1);
 +      EulToMat3(beul, mat2);
 +      
 +      Mat3MulMat3(totmat, mat2, mat1);
 +      
 +      Mat3ToEul(totmat, beul);
 +      
 +}
 +
 +/* exported to transform.c */
 +/* order independent! */
 +void compatible_eul(float *eul, float *oldrot)
 +{
 +      float dx, dy, dz;
 +      
 +      /* correct differences of about 360 degrees first */
 +      dx= eul[0] - oldrot[0];
 +      dy= eul[1] - oldrot[1];
 +      dz= eul[2] - oldrot[2];
 +      
 +      while(fabs(dx) > 5.1) {
 +              if(dx > 0.0f) eul[0] -= 2.0f*(float)M_PI; else eul[0]+= 2.0f*(float)M_PI;
 +              dx= eul[0] - oldrot[0];
 +      }
 +      while(fabs(dy) > 5.1) {
 +              if(dy > 0.0f) eul[1] -= 2.0f*(float)M_PI; else eul[1]+= 2.0f*(float)M_PI;
 +              dy= eul[1] - oldrot[1];
 +      }
 +      while(fabs(dz) > 5.1) {
 +              if(dz > 0.0f) eul[2] -= 2.0f*(float)M_PI; else eul[2]+= 2.0f*(float)M_PI;
 +              dz= eul[2] - oldrot[2];
 +      }
 +      
 +      /* is 1 of the axis rotations larger than 180 degrees and the other small? NO ELSE IF!! */      
 +      if( fabs(dx) > 3.2 && fabs(dy)<1.6 && fabs(dz)<1.6 ) {
 +              if(dx > 0.0) eul[0] -= 2.0f*(float)M_PI; else eul[0]+= 2.0f*(float)M_PI;
 +      }
 +      if( fabs(dy) > 3.2 && fabs(dz)<1.6 && fabs(dx)<1.6 ) {
 +              if(dy > 0.0) eul[1] -= 2.0f*(float)M_PI; else eul[1]+= 2.0f*(float)M_PI;
 +      }
 +      if( fabs(dz) > 3.2 && fabs(dx)<1.6 && fabs(dy)<1.6 ) {
 +              if(dz > 0.0) eul[2] -= 2.0f*(float)M_PI; else eul[2]+= 2.0f*(float)M_PI;
 +      }
 +      
 +      /* the method below was there from ancient days... but why! probably because the code sucks :)
 +              */
 +#if 0 
 +      /* calc again */
 +      dx= eul[0] - oldrot[0];
 +      dy= eul[1] - oldrot[1];
 +      dz= eul[2] - oldrot[2];
 +      
 +      /* special case, tested for x-z  */
 +      
 +      if( (fabs(dx) > 3.1 && fabs(dz) > 1.5 ) || ( fabs(dx) > 1.5 && fabs(dz) > 3.1 ) ) {
 +              if(dx > 0.0) eul[0] -= M_PI; else eul[0]+= M_PI;
 +              if(eul[1] > 0.0) eul[1]= M_PI - eul[1]; else eul[1]= -M_PI - eul[1];
 +              if(dz > 0.0) eul[2] -= M_PI; else eul[2]+= M_PI;
 +              
 +      }
 +      else if( (fabs(dx) > 3.1 && fabs(dy) > 1.5 ) || ( fabs(dx) > 1.5 && fabs(dy) > 3.1 ) ) {
 +              if(dx > 0.0) eul[0] -= M_PI; else eul[0]+= M_PI;
 +              if(dy > 0.0) eul[1] -= M_PI; else eul[1]+= M_PI;
 +              if(eul[2] > 0.0) eul[2]= M_PI - eul[2]; else eul[2]= -M_PI - eul[2];
 +      }
 +      else if( (fabs(dy) > 3.1 && fabs(dz) > 1.5 ) || ( fabs(dy) > 1.5 && fabs(dz) > 3.1 ) ) {
 +              if(eul[0] > 0.0) eul[0]= M_PI - eul[0]; else eul[0]= -M_PI - eul[0];
 +              if(dy > 0.0) eul[1] -= M_PI; else eul[1]+= M_PI;
 +              if(dz > 0.0) eul[2] -= M_PI; else eul[2]+= M_PI;
 +      }
 +#endif        
 +}
 +
 +/* uses 2 methods to retrieve eulers, and picks the closest */
 +/* XYZ order */
 +void Mat3ToCompatibleEul(float mat[][3], float *eul, float *oldrot)
 +{
 +      float eul1[3], eul2[3];
 +      float d1, d2;
 +      
 +      mat3_to_eul2(mat, eul1, eul2);
 +      
 +      compatible_eul(eul1, oldrot);
 +      compatible_eul(eul2, oldrot);
 +      
 +      d1= (float)fabs(eul1[0]-oldrot[0]) + (float)fabs(eul1[1]-oldrot[1]) + (float)fabs(eul1[2]-oldrot[2]);
 +      d2= (float)fabs(eul2[0]-oldrot[0]) + (float)fabs(eul2[1]-oldrot[1]) + (float)fabs(eul2[2]-oldrot[2]);
 +      
 +      /* return best, which is just the one with lowest difference */
 +      if( d1 > d2) {
 +              VecCopyf(eul, eul2);
 +      }
 +      else {
 +              VecCopyf(eul, eul1);
 +      }
 +      
 +}
 +
 +/* ************ AXIS ANGLE *************** */
 +
 +/* Axis angle to Quaternions */
 +void AxisAngleToQuat(float *q, float *axis, float angle)
 +{
 +      float nor[3];
 +      float si;
 +      
 +      VecCopyf(nor, axis);
 +      Normalize(nor);
 +      
 +      angle /= 2;
 +      si = (float)sin(angle);
 +      q[0] = (float)cos(angle);
 +      q[1] = nor[0] * si;
 +      q[2] = nor[1] * si;
 +      q[3] = nor[2] * si;     
 +}
 +
 +/* Quaternions to Axis Angle */
 +void QuatToAxisAngle(float q[4], float axis[3], float *angle)
 +{
 +      float ha, si;
 +      
 +      /* calculate angle/2, and sin(angle/2) */
 +      ha= (float)acos(q[0]);
 +      si= (float)sin(ha);
 +      
 +      /* from half-angle to angle */
 +      *angle= ha * 2;
 +      
 +      /* prevent division by zero for axis conversion */
 +      if (fabs(si) < 0.0005)
 +              si= 1.0f;
 +      
 +      axis[0]= q[1] / si;
 +      axis[1]= q[2] / si;
 +      axis[2]= q[3] / si;
 +}
 +
 +/* axis angle to 3x3 matrix */
 +void VecRotToMat3(float *vec, float phi, float mat[][3])
  {
        /* rotation of phi radials around vec */
        float vx, vx2, vy, vy2, vz, vz2, co, si;
        
  }
  
 -void VecRotToMat4( float *vec, float phi, float mat[][4])
 +/* axis angle to 4x4 matrix */
 +void VecRotToMat4(float *vec, float phi, float mat[][4])
  {
        float tmat[3][3];
        
        Mat4CpyMat3(mat, tmat);
  }
  
 -void VecRotToQuat( float *vec, float phi, float *quat)
 +/* axis angle to quaternion */
 +void VecRotToQuat(float *vec, float phi, float *quat)
  {
        /* rotation of phi radials around vec */
        float si;
        quat[2]= vec[1];
        quat[3]= vec[2];
        
 -      if( Normalize(quat+1) == 0.0) {
 +      if( Normalize(quat+1) == 0.0f) {
                QuatOne(quat);
        }
        else {
        }
  }
  
--/* get a direction from 3 vectors that wont depend
-- * on the distance between the points */
--void Vec3ToTangent(float *v, float *v1, float *v2, float *v3)
++/* Returns a vector bisecting the angle at v2 formed by v1, v2 and v3 */
++void VecBisect3(float *out, float *v1, float *v2, float *v3)
  {
        float d_12[3], d_23[3];
        VecSubf(d_12, v2, v1);
        VecSubf(d_23, v3, v2);
        Normalize(d_12);
        Normalize(d_23);
--      VecAddf(v, d_12, d_23);
--      Normalize(v);
++      VecAddf(out, d_12, d_23);
++      Normalize(out);
++}
++
++/* Returns a reflection vector from a vector and a normal vector
++reflect = vec - ((2 * DotVecs(vec, mirror)) * mirror)
++*/
++void VecReflect(float *out, float *v1, float *v2)
++{
++      float vec[3], normal[3];
++      float reflect[3] = {0.0f, 0.0f, 0.0f};
++      float dot2;
++
++      VecCopyf(vec, v1);
++      VecCopyf(normal, v2);
++
++      Normalize(normal);
++
++      dot2 = 2 * Inpf(vec, normal);
++
++      reflect[0] = vec[0] - (dot2 * normal[0]);
++      reflect[1] = vec[1] - (dot2 * normal[1]);
++      reflect[2] = vec[2] - (dot2 * normal[2]);
++
++      VecCopyf(out, reflect);
  }
  
  /* Return the angle in degrees between vecs 1-2 and 2-3 in degrees
@@@ -3399,7 -2994,7 +3421,7 @@@ float VecAngle3(float *v1, float *v2, f
        Normalize(vec1);
        Normalize(vec2);
  
 -      return NormalizedVecAngle2(vec1, vec2) * 180.0/M_PI;
 +      return NormalizedVecAngle2(vec1, vec2) * (float)(180.0/M_PI);
  }
  
  float VecAngle3_2D(float *v1, float *v2, float *v3)
        Normalize2(vec1);
        Normalize2(vec2);
  
 -      return NormalizedVecAngle2_2D(vec1, vec2) * 180.0/M_PI;
 +      return NormalizedVecAngle2_2D(vec1, vec2) * (float)(180.0/M_PI);
  }
  
  /* Return the shortest angle in degrees between the 2 vectors */
@@@ -3428,7 -3023,7 +3450,7 @@@ float VecAngle2(float *v1, float *v2
        Normalize(vec1);
        Normalize(vec2);
  
 -      return NormalizedVecAngle2(vec1, vec2)* 180.0/M_PI;
 +      return NormalizedVecAngle2(vec1, vec2)* (float)(180.0/M_PI);
  }
  
  float NormalizedVecAngle2(float *v1, float *v2)
                vec[0]= -v2[0];
                vec[1]= -v2[1];
                vec[2]= -v2[2];
 -
 -              return (float)M_PI - 2.0f*saasin(VecLenf(vec, v1)/2.0f);
 +              
 +              return (float)M_PI - 2.0f*(float)saasin(VecLenf(vec, v1)/2.0f);
        }
        else
 -              return 2.0f*saasin(VecLenf(v2, v1)/2.0);
 +              return 2.0f*(float)saasin(VecLenf(v2, v1)/2.0f);
  }
  
  float NormalizedVecAngle2_2D(float *v1, float *v2)
                
                vec[0]= -v2[0];
                vec[1]= -v2[1];
 -
 +              
                return (float)M_PI - 2.0f*saasin(Vec2Lenf(vec, v1)/2.0f);
        }
        else
 -              return 2.0f*saasin(Vec2Lenf(v2, v1)/2.0);
 -}
 -
 -void euler_rot(float *beul, float ang, char axis)
 -{
 -      float eul[3], mat1[3][3], mat2[3][3], totmat[3][3];
 -      
 -      eul[0]= eul[1]= eul[2]= 0.0;
 -      if(axis=='x') eul[0]= ang;
 -      else if(axis=='y') eul[1]= ang;
 -      else eul[2]= ang;
 -      
 -      EulToMat3(eul, mat1);
 -      EulToMat3(beul, mat2);
 -      
 -      Mat3MulMat3(totmat, mat2, mat1);
 -      
 -      Mat3ToEul(totmat, beul);
 -      
 -}
 -
 -/* exported to transform.c */
 -void compatible_eul(float *eul, float *oldrot)
 -{
 -      float dx, dy, dz;
 -      
 -      /* correct differences of about 360 degrees first */
 -      
 -      dx= eul[0] - oldrot[0];
 -      dy= eul[1] - oldrot[1];
 -      dz= eul[2] - oldrot[2];
 -      
 -      while( fabs(dx) > 5.1) {
 -              if(dx > 0.0) eul[0] -= 2.0*M_PI; else eul[0]+= 2.0*M_PI;
 -              dx= eul[0] - oldrot[0];
 -      }
 -      while( fabs(dy) > 5.1) {
 -              if(dy > 0.0) eul[1] -= 2.0*M_PI; else eul[1]+= 2.0*M_PI;
 -              dy= eul[1] - oldrot[1];
 -      }
 -      while( fabs(dz) > 5.1 ) {
 -              if(dz > 0.0) eul[2] -= 2.0*M_PI; else eul[2]+= 2.0*M_PI;
 -              dz= eul[2] - oldrot[2];
 -      }
 -      
 -      /* is 1 of the axis rotations larger than 180 degrees and the other small? NO ELSE IF!! */      
 -      if( fabs(dx) > 3.2 && fabs(dy)<1.6 && fabs(dz)<1.6 ) {
 -              if(dx > 0.0) eul[0] -= 2.0*M_PI; else eul[0]+= 2.0*M_PI;
 -      }
 -      if( fabs(dy) > 3.2 && fabs(dz)<1.6 && fabs(dx)<1.6 ) {
 -              if(dy > 0.0) eul[1] -= 2.0*M_PI; else eul[1]+= 2.0*M_PI;
 -      }
 -      if( fabs(dz) > 3.2 && fabs(dx)<1.6 && fabs(dy)<1.6 ) {
 -              if(dz > 0.0) eul[2] -= 2.0*M_PI; else eul[2]+= 2.0*M_PI;
 -      }
 -      
 -      /* the method below was there from ancient days... but why! probably because the code sucks :)
 -              */
 -#if 0 
 -      /* calc again */
 -      dx= eul[0] - oldrot[0];
 -      dy= eul[1] - oldrot[1];
 -      dz= eul[2] - oldrot[2];
 -      
 -      /* special case, tested for x-z  */
 -      
 -      if( (fabs(dx) > 3.1 && fabs(dz) > 1.5 ) || ( fabs(dx) > 1.5 && fabs(dz) > 3.1 ) ) {
 -              if(dx > 0.0) eul[0] -= M_PI; else eul[0]+= M_PI;
 -              if(eul[1] > 0.0) eul[1]= M_PI - eul[1]; else eul[1]= -M_PI - eul[1];
 -              if(dz > 0.0) eul[2] -= M_PI; else eul[2]+= M_PI;
 -              
 -      }
 -      else if( (fabs(dx) > 3.1 && fabs(dy) > 1.5 ) || ( fabs(dx) > 1.5 && fabs(dy) > 3.1 ) ) {
 -              if(dx > 0.0) eul[0] -= M_PI; else eul[0]+= M_PI;
 -              if(dy > 0.0) eul[1] -= M_PI; else eul[1]+= M_PI;
 -              if(eul[2] > 0.0) eul[2]= M_PI - eul[2]; else eul[2]= -M_PI - eul[2];
 -      }
 -      else if( (fabs(dy) > 3.1 && fabs(dz) > 1.5 ) || ( fabs(dy) > 1.5 && fabs(dz) > 3.1 ) ) {
 -              if(eul[0] > 0.0) eul[0]= M_PI - eul[0]; else eul[0]= -M_PI - eul[0];
 -              if(dy > 0.0) eul[1] -= M_PI; else eul[1]+= M_PI;
 -              if(dz > 0.0) eul[2] -= M_PI; else eul[2]+= M_PI;
 -      }
 -#endif        
 -}
 -
 -/* uses 2 methods to retrieve eulers, and picks the closest */
 -void Mat3ToCompatibleEul(float mat[][3], float *eul, float *oldrot)
 -{
 -      float eul1[3], eul2[3];
 -      float d1, d2;
 -      
 -      mat3_to_eul2(mat, eul1, eul2);
 -      
 -      compatible_eul(eul1, oldrot);
 -      compatible_eul(eul2, oldrot);
 -      
 -      d1= fabs(eul1[0]-oldrot[0]) + fabs(eul1[1]-oldrot[1]) + fabs(eul1[2]-oldrot[2]);
 -      d2= fabs(eul2[0]-oldrot[0]) + fabs(eul2[1]-oldrot[1]) + fabs(eul2[2]-oldrot[2]);
 -      
 -      /* return best, which is just the one with lowest difference */
 -      if( d1 > d2) {
 -              VecCopyf(eul, eul2);
 -      }
 -      else {
 -              VecCopyf(eul, eul1);
 -      }
 -      
 +              return 2.0f*(float)saasin(Vec2Lenf(v2, v1)/2.0f);
  }
  
  /* ******************************************** */
  void SizeToMat3( float *size, float mat[][3])
  {
        mat[0][0]= size[0];
 -      mat[0][1]= 0.0;
 -      mat[0][2]= 0.0;
 +      mat[0][1]= 0.0f;
 +      mat[0][2]= 0.0f;
        mat[1][1]= size[1];
 -      mat[1][0]= 0.0;
 -      mat[1][2]= 0.0;
 +      mat[1][0]= 0.0f;
 +      mat[1][2]= 0.0f;
        mat[2][2]= size[2];
 -      mat[2][1]= 0.0;
 -      mat[2][0]= 0.0;
 +      mat[2][1]= 0.0f;
 +      mat[2][0]= 0.0f;
  }
  
  void SizeToMat4( float *size, float mat[][4])
@@@ -3506,7 -3207,7 +3528,7 @@@ void Mat4ToSize( float mat[][4], float 
  float Mat3ToScalef(float mat[][3])
  {
        /* unit length vector */
 -      float unit_vec[3] = {0.577350269189626, 0.577350269189626, 0.577350269189626};
 +      float unit_vec[3] = {0.577350269189626f, 0.577350269189626f, 0.577350269189626f};
        Mat3MulVecfl(mat, unit_vec);
        return VecLength(unit_vec);
  }
@@@ -3531,12 -3232,12 +3553,12 @@@ void triatoquat( float *v1,  float *v2
  
        n[0]= vec[1];
        n[1]= -vec[0];
 -      n[2]= 0.0;
 +      n[2]= 0.0f;
        Normalize(n);
        
 -      if(n[0]==0.0 && n[1]==0.0) n[0]= 1.0;
 +      if(n[0]==0.0f && n[1]==0.0f) n[0]= 1.0f;
        
 -      angle= -0.5f*saacos(vec[2]);
 +      angle= -0.5f*(float)saacos(vec[2]);
        co= (float)cos(angle);
        si= (float)sin(angle);
        q1[0]= co;
        Mat3MulVecfl(imat, vec);
  
        /* what angle has this line with x-axis? */
 -      vec[2]= 0.0;
 +      vec[2]= 0.0f;
        Normalize(vec);
  
        angle= (float)(0.5*atan2(vec[1], vec[0]));
@@@ -3624,13 -3325,14 +3646,13 @@@ float Normalize2(float *n
        
        d= n[0]*n[0]+n[1]*n[1];
  
 -      if(d>1.0e-35F) {
 +      if(d>1.0e-35f) {
                d= (float)sqrt(d);
 -
                n[0]/=d; 
                n[1]/=d; 
        } else {
 -              n[0]=n[1]= 0.0;
 -              d= 0.0;
 +              n[0]=n[1]= 0.0f;
 +              d= 0.0f;
        }
        return d;
  }
@@@ -3642,15 -3344,15 +3664,15 @@@ void hsv_to_rgb(float h, float s, floa
  
        h *= 360.0f;
        
 -      if(s==0.0) {
 +      if(s==0.0f) {
                *r = v;
                *g = v;
                *b = v;
        }
        else {
 -              if(h==360) h = 0;
 +              if(h== 360.0f) h = 0.0f;
                
 -              h /= 60;
 +              h /= 60.0f;
                i = (int)floor(h);
                f = h - i;
                p = v*(1.0f-s);
  void rgb_to_yuv(float r, float g, float b, float *ly, float *lu, float *lv)
  {
        float y, u, v;
 -      y= 0.299*r + 0.587*g + 0.114*b;
 -      u=-0.147*r - 0.289*g + 0.436*b;
 -      v= 0.615*r - 0.515*g - 0.100*b;
 +      y= 0.299f*r + 0.587f*g + 0.114f*b;
 +      u=-0.147f*r - 0.289f*g + 0.436f*b;
 +      v= 0.615f*r - 0.515f*g - 0.100f*b;
        
        *ly=y;
        *lu=u;
  void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb)
  {
        float r, g, b;
 -      r=y+1.140*v;
 -      g=y-0.394*u - 0.581*v;
 -      b=y+2.032*u;
 +      r=y+1.140f*v;
 +      g=y-0.394f*u - 0.581f*v;
 +      b=y+2.032f*u;
        
        *lr=r;
        *lg=g;
@@@ -3721,14 -3423,14 +3743,14 @@@ void rgb_to_ycc(float r, float g, floa
        float sr,sg, sb;
        float y, cr, cb;
        
 -      sr=255.0*r;
 -      sg=255.0*g;
 -      sb=255.0*b;
 +      sr=255.0f*r;
 +      sg=255.0f*g;
 +      sb=255.0f*b;
        
        
 -      y=(0.257*sr)+(0.504*sg)+(0.098*sb)+16.0;
 -      cb=(-0.148*sr)-(0.291*sg)+(0.439*sb)+128.0;
 -      cr=(0.439*sr)-(0.368*sg)-(0.071*sb)+128.0;
 +      y=(0.257f*sr)+(0.504f*sg)+(0.098f*sb)+16.0f;
 +      cb=(-0.148f*sr)-(0.291f*sg)+(0.439f*sb)+128.0f;
 +      cr=(0.439f*sr)-(0.368f*sg)-(0.071f*sb)+128.0f;
        
        *ly=y;
        *lcb=cb;
@@@ -3739,13 -3441,13 +3761,13 @@@ void ycc_to_rgb(float y, float cb, floa
  {
        float r,g,b;
        
 -      r=1.164*(y-16)+1.596*(cr-128);
 -      g=1.164*(y-16)-0.813*(cr-128)-0.392*(cb-128);
 -      b=1.164*(y-16)+2.017*(cb-128);
 +      r=1.164f*(y-16.0f)+1.596f*(cr-128.0f);
 +      g=1.164f*(y-16.0f)-0.813f*(cr-128.0f)-0.392f*(cb-128.0f);
 +      b=1.164f*(y-16.0f)+2.017f*(cb-128.0f);
        
 -      *lr=r/255.0;
 -      *lg=g/255.0;
 -      *lb=b/255.0;
 +      *lr=r/255.0f;
 +      *lg=g/255.0f;
 +      *lb=b/255.0f;
  }
  
  void hex_to_rgb(char *hexcol, float *r, float *g, float *b)
        if (hexcol[0] == '#') hexcol++;
        
        if (sscanf(hexcol, "%02x%02x%02x", &ri, &gi, &bi)) {
 -              *r = ri / 255.0;
 -              *g = gi / 255.0               
 -              *b = bi / 255.0;
 +              *r = ri / 255.0f;
 +              *g = gi / 255.0f;               
 +              *b = bi / 255.0f;
        }
  }
  
@@@ -3775,14 -3477,14 +3797,14 @@@ void rgb_to_hsv(float r, float g, floa
        cmin = (b<cmin ? b:cmin);
  
        v = cmax;               /* value */
 -      if (cmax!=0.0)
 +      if (cmax != 0.0f)
                s = (cmax - cmin)/cmax;
        else {
 -              s = 0.0;
 -              h = 0.0;
 +              s = 0.0f;
 +              h = 0.0f;
        }
 -      if (s == 0.0)
 -              h = -1.0;
 +      if (s == 0.0f)
 +              h = -1.0f;
        else {
                cdelta = cmax-cmin;
                rc = (cmax-r)/cdelta;
                        else
                                h = 4.0f+gc-rc;
                h = h*60.0f;
 -              if (h<0.0f)
 +              if (h < 0.0f)
                        h += 360.0f;
        }
        
        *ls = s;
 -      *lh = h/360.0f;
 -      if( *lh < 0.0) *lh= 0.0;
 +      *lh = h / 360.0f;
 +      if(*lh < 0.0f) *lh= 0.0f;
        *lv = v;
  }
  
@@@ -3812,14 -3514,14 +3834,14 @@@ void xyz_to_rgb(float xc, float yc, flo
  {
        switch (colorspace) { 
        case BLI_CS_SMPTE:
 -              *r = (3.50570   * xc) + (-1.73964       * yc) + (-0.544011      * zc);
 -              *g = (-1.06906  * xc) + (1.97781        * yc) + (0.0351720      * zc);
 -              *b = (0.0563117 * xc) + (-0.196994      * yc) + (1.05005        * zc);
 +              *r = (3.50570f   * xc) + (-1.73964f      * yc) + (-0.544011f * zc);
 +              *g = (-1.06906f  * xc) + (1.97781f       * yc) + (0.0351720f * zc);
 +              *b = (0.0563117f * xc) + (-0.196994f * yc) + (1.05005f   * zc);
                break;
        case BLI_CS_REC709:
 -              *r = (3.240476  * xc) + (-1.537150      * yc) + (-0.498535      * zc);
 -              *g = (-0.969256 * xc) + (1.875992 * yc) + (0.041556 * zc);
 -              *b = (0.055648  * xc) + (-0.204043      * yc) + (1.057311       * zc);
 +              *r = (3.240476f  * xc) + (-1.537150f * yc) + (-0.498535f * zc);
 +              *g = (-0.969256f * xc) + (1.875992f  * yc) + (0.041556f  * zc);
 +              *b = (0.055648f  * xc) + (-0.204043f * yc) + (1.057311f  * zc);
                break;
        case BLI_CS_CIE:
                *r = (2.28783848734076f * xc) + (-0.833367677835217f    * yc) + (-0.454470795871421f    * zc);
@@@ -3850,10 -3552,34 +3872,10 @@@ int constrain_rgb(float *r, float *g, f
      
      if (w > 0) {
          *r += w;  *g += w; *b += w;
 -        return 1;                     /* Colour modified to fit RGB gamut */
 +        return 1;                     /* Color modified to fit RGB gamut */
      }
  
 -    return 0;                         /* Colour within RGB gamut */
 -}
 -
 -/*Transform linear RGB values to nonlinear RGB values. Rec.
 -  709 is ITU-R Recommendation BT. 709 (1990) ``Basic
 -  Parameter Values for the HDTV Standard for the Studio and
 -  for International Programme Exchange'', formerly CCIR Rec.
 -  709.*/
 -static void gamma_correct(float *c)
 -{
 -      /* Rec. 709 gamma correction. */
 -      float cc = 0.018;
 -      
 -      if (*c < cc) {
 -          *c *= ((1.099 * pow(cc, 0.45)) - 0.099) / cc;
 -      } else {
 -          *c = (1.099 * pow(*c, 0.45)) - 0.099;
 -      }
 -}
 -
 -void gamma_correct_rgb(float *r, float *g, float *b)
 -{
 -    gamma_correct(r);
 -    gamma_correct(g);
 -    gamma_correct(b);
 +    return 0;                         /* Color within RGB gamut */
  }
  
  
@@@ -3912,13 -3638,14 +3934,13 @@@ void tubemap(float x, float y, float z
  {
        float len;
        
 -      *v = (z + 1.0) / 2.0;
 +      *v = (z + 1.0f) / 2.0f;
        
 -      len= sqrt(x*x+y*y);
 -      if(len>0) {
 -              *u = (1.0 - (atan2(x/len,y/len) / M_PI)) / 2.0;
 -      } else {
 +      len= (float)sqrt(x*x+y*y);
 +      if(len > 0.0f)
 +              *u = (float)((1.0 - (atan2(x/len,y/len) / M_PI)) / 2.0);
 +      else
                *v = *u = 0.0f; /* to avoid un-initialized variables */
 -      }
  }
  
  /* ------------------------------------------------------------------------- */
@@@ -3927,13 -3654,14 +3949,13 @@@ void spheremap(float x, float y, float 
  {
        float len;
        
 -      len= sqrt(x*x+y*y+z*z);
 -      if(len>0.0) {
 -              
 -              if(x==0.0 && y==0.0) *u= 0.0;   /* othwise domain error */
 -              else *u = (1.0 - atan2(x,y)/M_PI )/2.0;
 +      len= (float)sqrt(x*x+y*y+z*z);
 +      if(len > 0.0f) {
 +              if(x==0.0f && y==0.0f) *u= 0.0f;        /* othwise domain error */
 +              else *u = (float)((1.0 - (float)atan2(x,y) / M_PI) / 2.0);
                
                z/=len;
 -              *v = 1.0- saacos(z)/M_PI;
 +              *v = 1.0f - (float)saacos(z)/(float)M_PI;
        } else {
                *v = *u = 0.0f; /* to avoid un-initialized variables */
        }
@@@ -4244,7 -3972,7 +4266,7 @@@ static int getLowestRoot(float a, floa
        {
                // calculate the two roots: (if determinant == 0 then
                // x1==x2 but let’s disregard that slight optimization)
 -              float sqrtD = sqrt(determinant);
 +              float sqrtD = (float)sqrt(determinant);
                float r1 = (-b - sqrtD) / (2.0f*a);
                float r2 = (-b + sqrtD) / (2.0f*a);
                
@@@ -4663,7 -4391,6 +4685,7 @@@ float lambda_cp_line_ex(float p[3], flo
        return lambda;
  }
  
 +#if 0
  /* little sister we only need to know lambda */
  static float lambda_cp_line(float p[3], float l1[3], float l2[3])
  {
        VecSubf(h, p, l1);
        return(Inpf(u,h)/Inpf(u,u));
  }
 +#endif
  
  /* Similar to LineIntersectsTriangleUV, except it operates on a quad and in 2d, assumes point is in quad */
  void PointInQuad2DUV(float v0[2], float v1[2], float v2[2], float v3[2], float pt[2], float *uv)
@@@ -4800,79 -4526,6 +4822,79 @@@ void PointInFace2DUV(int isquad, float 
        }
  }
  
 +int IsPointInTri2D(float v1[2], float v2[2], float v3[2], float pt[2])
 +{
 +      float inp1, inp2, inp3;
 +      
 +      inp1= (v2[0]-v1[0])*(v1[1]-pt[1]) + (v1[1]-v2[1])*(v1[0]-pt[0]);
 +      inp2= (v3[0]-v2[0])*(v2[1]-pt[1]) + (v2[1]-v3[1])*(v2[0]-pt[0]);
 +      inp3= (v1[0]-v3[0])*(v3[1]-pt[1]) + (v3[1]-v1[1])*(v3[0]-pt[0]);
 +      
 +      if(inp1<=0.0f && inp2<=0.0f && inp3<=0.0f) return 1;
 +      if(inp1>=0.0f && inp2>=0.0f && inp3>=0.0f) return 1;
 +      
 +      return 0;
 +}
 +
 +#if 0
 +int IsPointInTri2D(float v0[2], float v1[2], float v2[2], float pt[2])
 +{
 +              /* not for quads, use for our abuse of LineIntersectsTriangleUV */
 +              float p1_3d[3], p2_3d[3], v0_3d[3], v1_3d[3], v2_3d[3];
 +              /* not used */
 +              float lambda, uv[3];
 +                      
 +              p1_3d[0] = p2_3d[0] = uv[0]= pt[0];
 +              p1_3d[1] = p2_3d[1] = uv[1]= uv[2]= pt[1];
 +              p1_3d[2] = 1.0f;
 +              p2_3d[2] = -1.0f;
 +              v0_3d[2] = v1_3d[2] = v2_3d[2] = 0.0;
 +              
 +              /* generate a new fuv, (this is possibly a non optimal solution,
 +               * since we only need 2d calculation but use 3d func's)
 +               * 
 +               * this method makes an imaginary triangle in 2d space using the UV's from the derived mesh face
 +               * Then find new uv coords using the fuv and this face with LineIntersectsTriangleUV.
 +               * This means the new values will be correct in relation to the derived meshes face. 
 +               */
 +              Vec2Copyf(v0_3d, v0);
 +              Vec2Copyf(v1_3d, v1);
 +              Vec2Copyf(v2_3d, v2);
 +              
 +              /* Doing this in 3D is not nice */
 +              return LineIntersectsTriangle(p1_3d, p2_3d, v0_3d, v1_3d, v2_3d, &lambda, uv);
 +}
 +#endif
 +
 +/*
 +
 +      x1,y2
 +      |  \
 +      |   \     .(a,b)
 +      |    \
 +      x1,y1-- x2,y1
 +
 +*/
 +int IsPointInTri2DInts(int x1, int y1, int x2, int y2, int a, int b)
 +{
 +      float v1[2], v2[2], v3[2], p[2];
 +      
 +      v1[0]= (float)x1;
 +      v1[1]= (float)y1;
 +      
 +      v2[0]= (float)x1;
 +      v2[1]= (float)y2;
 +      
 +      v3[0]= (float)x2;
 +      v3[1]= (float)y1;
 +      
 +      p[0]= (float)a;
 +      p[1]= (float)b;
 +      
 +      return IsPointInTri2D(v1, v2, v3, p);
 +      
 +}
 +
  /* (x1,v1)(t1=0)------(x2,v2)(t2=1), 0<t<1 --> (x,v)(t) */
  void VecfCubicInterpol(float *x1, float *v1, float *x2, float *v2, float t, float *x, float *v)
  {
@@@ -4923,7 -4576,6 +4945,7 @@@ but see a 'spat' which is a deformed cu
        return 1;
  }
  
 +#if 0
  /*adult sister defining the slice planes by the origin and the normal  
  NOTE |normal| may not be 1 but defining the thickness of the slice*/
  static int point_in_slice_as(float p[3],float origin[3],float normal[3])
@@@ -4944,7 -4596,6 +4966,7 @@@ static int point_in_slice_m(float p[3],
        if (h < 0.0f || h > 1.0f) return 0;
        return 1;
  }
 +#endif
  
  
  int point_in_tri_prism(float p[3], float v1[3], float v2[3], float v3[3])
@@@ -4984,8 -4635,7 +5006,8 @@@ float PdistVL3Dfl(float *v1, float *v2
  
  /* make a 4x4 matrix out of 3 transform components */
  /* matrices are made in the order: scale * rot * loc */
 -void LocEulSizeToMat4(float mat[][4], float loc[3], float eul[3], float size[3])
 +// TODO: need to have a version that allows for rotation order...
 +void LocEulSizeToMat4(float mat[4][4], float loc[3], float eul[3], float size[3])
  {
        float rmat[3][3], smat[3][3], tmat[3][3];
        
  
  /* make a 4x4 matrix out of 3 transform components */
  /* matrices are made in the order: scale * rot * loc */
 -void LocQuatSizeToMat4(float mat[][4], float loc[3], float quat[4], float size[3])
 +void LocEulOSizeToMat4(float mat[4][4], float loc[3], float eul[3], float size[3], short rotOrder)
 +{
 +      float rmat[3][3], smat[3][3], tmat[3][3];
 +      
 +      /* initialise new matrix */
 +      Mat4One(mat);
 +      
 +      /* make rotation + scaling part */
 +      EulOToMat3(eul, rotOrder, rmat);
 +      SizeToMat3(size, smat);
 +      Mat3MulMat3(tmat, rmat, smat);
 +      
 +      /* copy rot/scale part to output matrix*/
 +      Mat4CpyMat3(mat, tmat);
 +      
 +      /* copy location to matrix */
 +      mat[3][0] = loc[0];
 +      mat[3][1] = loc[1];
 +      mat[3][2] = loc[2];
 +}
 +
 +
 +/* make a 4x4 matrix out of 3 transform components */
 +/* matrices are made in the order: scale * rot * loc */
 +void LocQuatSizeToMat4(float mat[4][4], float loc[3], float quat[4], float size[3])
  {
        float rmat[3][3], smat[3][3], tmat[3][3];
        
        mat[3][2] = loc[2];
  }
  
 +/********************************************************/
 +
  /* Tangents */
  
  /* For normal map tangents we need to detect uv boundaries, and only average
@@@ -5129,5 -4753,5 +5151,5 @@@ void tangent_from_uv(float *uv1, float 
  
  /* used for zoom values*/
  float power_of_2(float val) {
 -      return pow(2, ceil(log(val) / log(2)));
 +      return (float)pow(2, ceil(log(val) / log(2)));
  }
index 4fe4217cd2ccc03508cc2e12af29bc7c69faf38d,b6f29b6a1457e813df68e48c99b7e0b58c92a391..43a6b0d2c5df977b8b0220a05acef673968311d4
@@@ -31,7 -31,6 +31,7 @@@
  
  #include "BLI_blenlib.h" /* BLI_remlink BLI_filesize BLI_addtail
                              BLI_countlist BLI_stringdec */
 +
  #include "imbuf.h"
  #include "imbuf_patch.h"
  
  
  #include "IMB_anim5.h"
  
 +#ifdef _WIN32
 +#include <io.h>
 +#include "BLI_winstuff.h"
 +#endif
 +
  typedef struct Anhd{
        unsigned char type, mask;
        unsigned short w, h;
@@@ -210,12 -204,12 +210,12 @@@ static void anim5decode(struct ImBuf * 
        int *ofspoint;
        uchar **planes;
  
--      /*      samenstelling delta:
--              lijst met ofsets voor delta's per bitplane (ofspoint)
--              per kolom in delta (point)
--                      aantal handelingen (noops)
++      /*      composition delta:
++              list with ofsets for delta' s by bitplane (ofspoint)
++              by column in delta (point)
++                      number of operations (noops)
                                code
--                                      bijbehorende data
++                                      associated data
                                ...
                        ...
        */
index 3655c57558a61d41a6806d89b7af85549cd791dc,88c03a41160073fac27c151ebfe3bddd817c9e20..0466ea148fd32482ba59e1ce95bc07ea37c62d2b
@@@ -45,9 -45,6 +45,9 @@@ struct Ipo
  struct Key;
  struct Material;
  struct VFont;
 +struct AnimData;
 +struct SelBox;
 +struct EditFont;
  
  /* These two Lines with # tell makesdna this struct can be excluded. */
  #
@@@ -64,7 -61,7 +64,7 @@@ typedef struct Path 
  typedef struct BevList {
        struct BevList *next, *prev;
        int nr, flag;
--      short poly, gat;
++      short poly, hole;
  } BevList;
  
  /* These two Lines with # tell makesdna this struct can be excluded. */
@@@ -75,28 -72,24 +75,28 @@@ typedef struct BevPoint 
        short f1, f2;
  } BevPoint;
  
 -/* Keyframes on IPO curves and Points on Bezier Curves/Paths are generally BezTriples */
 +/* Keyframes on F-Curves (allows code reuse of Bezier eval code) and 
 + * Points on Bezier Curves/Paths are generally BezTriples 
 + */
  /* note: alfa location in struct is abused by Key system */
  /* vec in BezTriple looks like this:
        vec[0][0]=x location of handle 1
        vec[0][1]=y location of handle 1
 -      vec[0][2]=z location of handle 1 (not used for IpoCurve Points(2d))
 +      vec[0][2]=z location of handle 1 (not used for FCurve Points(2d))
        vec[1][0]=x location of control point
        vec[1][1]=y location of control point
        vec[1][2]=z location of control point
        vec[2][0]=x location of handle 2
        vec[2][1]=y location of handle 2
 -      vec[2][2]=z location of handle 2 (not used for IpoCurve Points(2d))
 +      vec[2][2]=z location of handle 2 (not used for FCurve Points(2d))
  */
  typedef struct BezTriple {
        float vec[3][3];
        float alfa, weight, radius;     /* alfa: tilt in 3D View, weight: used for softbody goal weight, radius: for bevel tapering */
 -      short h1, h2;                           /* h1, h2: the handle type of the two handles */
 -      char f1, f2, f3, hide;          /* f1, f2, f3: used for selection status,  hide: used to indicate whether BezTriple is hidden */
 +      short ipo;                                      /* ipo: interpolation mode for segment from this BezTriple to the next */
 +      char h1, h2;                            /* h1, h2: the handle type of the two handles */
 +      char f1, f2, f3;                        /* f1, f2, f3: used for selection status */
 +      char hide;                                      /* hide: used to indicate whether BezTriple is hidden (3D), type of keyframe (eBezTriple_KeyframeTypes) */
  } BezTriple;
  
  /* note; alfa location in struct is abused by Key system */
@@@ -141,17 -134,13 +141,17 @@@ typedef struct TextBox 
  
  typedef struct Curve {
        ID id;
 +      struct AnimData *adt;           /* animation data (must be immediately after id for utilities to use it) */ 
        
        struct BoundBox *bb;
        
 -      ListBase nurb;
 +      ListBase nurb;          /* actual data */
        ListBase disp;
 +      
 +      ListBase *editnurb;     /* edited data, not in file, use pointer so we can check for it */
 +      
        struct Object *bevobj, *taperobj, *textoncurve;
 -      struct Ipo *ipo;
 +      struct Ipo *ipo;        // XXX depreceated... old animation system
        Path *path;
        struct Key *key;
        struct Material **mat;
        /* default */
        short resolu, resolv;
        short resolu_ren, resolv_ren;
 -      int pad2;
 +      
 +      /* edit, index in nurb list */
 +      int actnu;
 +      /* edit, last selected bpoint */
 +      BPoint *lastselbp;
        
        /* font part */
        short len, lines, pos, spacemode;
        float linewidth;
  
        char *str;
 +      struct SelBox *selboxes;
 +      struct EditFont *editfont;
 +      
        char family[24];
        struct VFont *vfont;
        struct VFont *vfontb;
  
        int sepchar;
        
 -      int totbox, actbox, pad;
 +      float ctime;                    /* current evaltime - for use by Objects parented to curves */
 +      int totbox, actbox;
        struct TextBox *tb;     
        
        int selstart, selend;   
        
        struct CharInfo *strinfo;       
 -      struct CharInfo curinfo;        
 +      struct CharInfo curinfo;
  } Curve;
  
  /* **************** CURVE ********************* */
  #define CU_OFFS_PATHDIST      256
  #define CU_FAST                       512 /* Font: no filling inside editmode */
  #define CU_RETOPO               1024
 +#define CU_DS_EXPAND  2048
  
  #define CU_NO_TWIST           4096
  
  #define CU_BSPLINE            2
  #define CU_CARDINAL           3
  #define CU_NURBS              4
 +#define CU_TYPE                       7
 +
  #define CU_2D                 8
  
 +              /* only for adding */
 +#define CU_PRIMITIVE  0xF00
 +
 +              /* 2 or 4 points */
 +#define CU_PRIM_CURVE 0x100
 +              /* 8 points circle */
 +#define CU_PRIM_CIRCLE        0x200
 +              /* 4x4 patch Nurb */
 +#define CU_PRIM_PATCH 0x300
 +#define CU_PRIM_TUBE  0x400
 +#define CU_PRIM_SPHERE        0x500
 +#define CU_PRIM_DONUT 0x600
 +              /* 5 points,  5th order straight line (for anim path) */
 +#define CU_PRIM_PATH  0x700
 +
 +
  /* flagu flagv (nurb) */
  #define CU_CYCLIC             1
  
 +/* *************** BEZTRIPLE **************** */
 +
  /* h1 h2 (beztriple) */
 -#define HD_FREE                       0
 -#define HD_AUTO                       1
 -#define HD_VECT                       2
 -#define HD_ALIGN              3
 -#define HD_AUTO_ANIM  4
 +typedef enum eBezTriple_Handle {
 +      HD_FREE = 0,
 +      HD_AUTO,
 +      HD_VECT,
 +      HD_ALIGN,
 +      HD_AUTO_ANIM
 +} eBezTriple_Handle;
 +
 +/* interpolation modes (used only for BezTriple->ipo) */
 +typedef enum eBezTriple_Interpolation {
 +      BEZT_IPO_CONST = 0,     /* constant interpolation */
 +      BEZT_IPO_LIN,           /* linear interpolation */
 +      BEZT_IPO_BEZ,           /* bezier interpolation */
 +} eBezTriple_Interpolation;
 +
 +/* types of keyframe (used only for BezTriple->hide when BezTriple is used in F-Curves) */
 +typedef enum eBezTriple_KeyframeType {
 +      BEZT_KEYTYPE_KEYFRAME = 0,      /* default - 'proper' Keyframe */
 +      BEZT_KEYTYPE_BREAKDOWN,         /* 'breakdown' keyframe */
 +} eBezTriple_KeyframeType;
  
  /* *************** CHARINFO **************** */