Merge with trunk: svn merge -r 12151:12179 https://svn.blender.org/svnroot/bf-blender...
authorDaniel Genrich <daniel.genrich@gmx.net>
Mon, 1 Oct 2007 21:36:39 +0000 (21:36 +0000)
committerDaniel Genrich <daniel.genrich@gmx.net>
Mon, 1 Oct 2007 21:36:39 +0000 (21:36 +0000)
47 files changed:
config/linux2-config.py
extern/SConscript
source/blender/blenkernel/intern/constraint.c
source/blender/blenlib/BLI_editVert.h
source/blender/include/BIF_drawseq.h
source/blender/include/BIF_editsima.h
source/blender/include/BIF_space.h
source/blender/include/BIF_spacetypes.h
source/blender/include/BSE_editipo.h
source/blender/include/BSE_sequence.h
source/blender/include/transform.h
source/blender/makesdna/DNA_userdef_types.h
source/blender/python/api2_2x/Modifier.c
source/blender/python/api2_2x/doc/Modifier.py
source/blender/src/buttons_editing.c
source/blender/src/drawimage.c
source/blender/src/drawobject.c
source/blender/src/drawseq.c
source/blender/src/drawview.c
source/blender/src/editipo.c
source/blender/src/editmesh.c
source/blender/src/editmesh_mods.c
source/blender/src/editmesh_tools.c
source/blender/src/editscreen.c
source/blender/src/editsima.c
source/blender/src/header_image.c
source/blender/src/header_ipo.c
source/blender/src/header_seq.c
source/blender/src/header_view3d.c
source/blender/src/interface_draw.c
source/blender/src/seqaudio.c
source/blender/src/sequence.c
source/blender/src/space.c
source/blender/src/spacetypes.c
source/blender/src/transform.c
source/blender/src/transform_conversions.c
source/blender/src/transform_generics.c
source/gameengine/BlenderRoutines/KX_BlenderRenderTools.cpp
source/gameengine/BlenderRoutines/KX_BlenderRenderTools.h
source/gameengine/GamePlayer/common/GPC_RenderTools.cpp
source/gameengine/GamePlayer/common/GPC_RenderTools.h
source/gameengine/Ketsji/KX_KetsjiEngine.cpp
source/gameengine/Ketsji/KX_PythonInit.cpp
source/gameengine/Rasterizer/RAS_IRasterizer.h
source/gameengine/Rasterizer/RAS_IRenderTools.h
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h

index 90fe74cee6bf61285c1b30037fc8ab3c9f74eeef..4bf7e755c49292429ce6d58e871c836178344788 100644 (file)
@@ -115,11 +115,14 @@ BF_ICONV_LIB = 'iconv'
 BF_ICONV_LIBPATH = '${BF_ICONV}/lib'
 
 # enable ffmpeg  support
-WITH_BF_FFMPEG = 'false'  # -DWITH_FFMPEG
-BF_FFMPEG = '/usr'
+WITH_BF_FFMPEG = 'true'  # -DWITH_FFMPEG
+BF_FFMPEG = '#extern/ffmpeg'
+BF_FFMPEG_LIB = ''
+# Uncomment the following two lines to use system's ffmpeg
+# BF_FFMPEG = '/usr'
+# BF_FFMPEG_LIB = 'avformat avcodec swscale avutil'
 BF_FFMPEG_INC = '${BF_FFMPEG}/include'
 BF_FFMPEG_LIBPATH='${BF_FFMPEG}/lib'
-BF_FFMPEG_LIB = 'avformat avcodec swscale avutil'
 
 # Mesa Libs should go here if your using them as well....
 WITH_BF_STATICOPENGL = 'false'
index 77e8998e359c450b61003720f6297796f5d004c2..766e2a5b188ad0c5af2f8685f9678481e98de468 100644 (file)
@@ -14,3 +14,6 @@ if env['WITH_BF_INTERNATIONAL']:
 
 if env['WITH_BF_VERSE']:
     SConscript(['verse/dist/SConstruct'])
+
+if env['WITH_BF_FFMPEG'] and env['BF_FFMPEG_LIB'] == '':
+    SConscript(['ffmpeg/SConscript']);
index 8445fe887972f392111b50cc9cd0402caa2e95f6..9ee158be531a9783a8515e0954ac64e29c55714f 100644 (file)
@@ -1146,56 +1146,58 @@ static void contarget_get_mesh_mat (Object *ob, char *substring, float mat[][4])
                int i, j, count = 0;
                float co[3], nor[3];
                
-               
-               /* get the average of all verts with that are in the vertex-group */
-               for (i = 0; i < numVerts; i++, index++) {       
-                       for (j = 0; j < dvert[i].totweight; j++) {
-                               /* does this vertex belong to nominated vertex group? */
-                               if (dvert[i].dw[j].def_nr == dgroup) {
-                                       dm->getVertCo(dm, i, co);
-                                       dm->getVertNo(dm, i, nor);
-                                       VecAddf(vec, vec, co);
-                                       VecAddf(normal, normal, nor);
-                                       count++;
-                                       break;
+               /* check that dvert and index are valid pointers (just in case) */
+               if (dvert && index) {
+                       /* get the average of all verts with that are in the vertex-group */
+                       for (i = 0; i < numVerts; i++, index++) {       
+                               for (j = 0; j < dvert[i].totweight; j++) {
+                                       /* does this vertex belong to nominated vertex group? */
+                                       if (dvert[i].dw[j].def_nr == dgroup) {
+                                               dm->getVertCo(dm, i, co);
+                                               dm->getVertNo(dm, i, nor);
+                                               VecAddf(vec, vec, co);
+                                               VecAddf(normal, normal, nor);
+                                               count++;
+                                               break;
+                                       }
+                                       
                                }
-                               
                        }
+                       
+                       
+                       /* calculate averages of normal and coordinates */
+                       if (count > 0) {
+                               VecMulf(vec, 1.0f / count);
+                               VecMulf(normal, 1.0f / count);
+                       }
+                       
+                       
+                       /* derive the rotation from the average normal: 
+                        *              - code taken from transform_manipulator.c, 
+                        *                      calc_manipulator_stats, V3D_MANIP_NORMAL case
+                        */
+                       /*      we need the transpose of the inverse for a normal... */
+                       Mat3CpyMat4(imat, ob->obmat);
+                       
+                       Mat3Inv(tmat, imat);
+                       Mat3Transp(tmat);
+                       Mat3MulVecfl(tmat, normal);
+                       
+                       Normalize(normal);
+                       VECCOPY(plane, tmat[1]);
+                       
+                       VECCOPY(tmat[2], normal);
+                       Crossf(tmat[0], normal, plane);
+                       Crossf(tmat[1], tmat[2], tmat[0]);
+                       
+                       Mat4CpyMat3(mat, tmat);
+                       Mat4Ortho(mat);
+                       
+                       
+                       /* apply the average coordinate as the new location */
+                       VecMat4MulVecfl(tvec, ob->obmat, vec);
+                       VECCOPY(mat[3], tvec);
                }
-               
-               
-               /* calculate averages of normal and coordinates */
-               if (count > 0) {
-                       VecMulf(vec, 1.0f / count);
-                       VecMulf(normal, 1.0f / count);
-               }
-               
-               
-               /* derive the rotation from the average normal: 
-                *              - code taken from transform_manipulator.c, 
-                *                      calc_manipulator_stats, V3D_MANIP_NORMAL case
-                */
-               /*      we need the transpose of the inverse for a normal... */
-               Mat3CpyMat4(imat, ob->obmat);
-               
-               Mat3Inv(tmat, imat);
-               Mat3Transp(tmat);
-               Mat3MulVecfl(tmat, normal);
-
-               Normalize(normal);
-               VECCOPY(plane, tmat[1]);
-               
-               VECCOPY(tmat[2], normal);
-               Crossf(tmat[0], normal, plane);
-               Crossf(tmat[1], tmat[2], tmat[0]);
-               
-               Mat4CpyMat3(mat, tmat);
-               Mat4Ortho(mat);
-               
-               
-               /* apply the average coordinate as the new location */
-               VecMat4MulVecfl(tvec, ob->obmat, vec);
-               VECCOPY(mat[3], tvec);
        }
        
        /* free temporary DerivedMesh created (in EditMode case) */
@@ -1225,6 +1227,7 @@ static void contarget_get_lattice_mat (Object *ob, char *substring, float mat[][
        /* get index of vertex group */
        dgroup = get_named_vertexgroup_num(ob, substring);
        if (dgroup < 0) return;
+       if (dvert == NULL) return;
        
        /* 1. Loop through control-points checking if in nominated vertex-group.
         * 2. If it is, add it to vec to find the average point.
index fd217e479edacdc1e7bf5c5423d4f2b6753783c5..795f67818941e743dfd20701f68c6aa67461443e 100644 (file)
@@ -55,9 +55,9 @@ typedef struct EditVert
                struct EditVert *v;
                struct EditEdge *e;
                struct EditFace *f;
-               float           *fp;
                void            *p;
                long             l;
+               float            fp;
        } tmp;
        float no[3]; /*vertex normal */
        float co[3]; /*vertex location */
index 986044d9c7eab8849fb0f9243feca01fae6b1128..4571267a09c6cb09937549ff851625f5d606440c 100644 (file)
@@ -36,6 +36,7 @@
 struct ScrArea;
 struct Sequence;
 
+void drawprefetchseqspace(struct ScrArea *sa, void *spacedata);
 void drawseqspace(struct ScrArea *sa, void *spacedata);
 void set_special_seq_update(int val);
 
index b85749f9f95524554ccd23e278119fae53f65135..a515a01061aa85fe40c1df54bd653347b6cbc07f 100644 (file)
@@ -93,7 +93,8 @@ void mirrormenu_tface_uv(void);
 void mirror_tface_uv(char mirroraxis);
 void hide_tface_uv(int swap);
 void reveal_tface_uv(void);
-void stitch_uv_tface(int mode);
+void stitch_limit_uv_tface(void);
+void stitch_vert_uv_tface(void);
 void unlink_selection(void);
 void select_linked_tface_uv(int mode);
 void pin_tface_uv(int mode);
index 7c88610cf3ac9411a26ef9e4d2a37b8f46b97e57..855773b34976e3915d685dbb14f70ce320e88dcd 100644 (file)
@@ -94,6 +94,7 @@ struct SpaceOops;
 #define B_RECALCLIGHT  3310
 
 
+void   scrarea_do_winprefetchdraw      (struct ScrArea *sa);
 void   scrarea_do_windraw              (struct ScrArea *sa);
 void   scrarea_do_winchange    (struct ScrArea *sa);
 void   scrarea_do_winhandle    (struct ScrArea *sa, struct BWinEvent *evt);
index e825acf676f0acda8067916400a5eaba6229ed0e..6125cfd5926fce29cca81f6105a6a9eb3ce805cf 100644 (file)
@@ -35,6 +35,7 @@ struct BWinEvent;
 
 typedef struct _SpaceType      SpaceType;
 
+typedef        void    (*SpacePrefetchDrawFP)  (struct ScrArea *sa, void *spacedata);
 typedef        void    (*SpaceDrawFP)          (struct ScrArea *sa, void *spacedata);
 typedef        void    (*SpaceChangeFP)        (struct ScrArea *sa, void *spacedata);
 typedef        void    (*SpaceHandleFP)        (struct ScrArea *sa, void *spacedata, struct BWinEvent *evt);
@@ -43,7 +44,7 @@ typedef       void    (*SpaceHandleFP)        (struct ScrArea *sa, void *spacedata, struct BWinE
 
 SpaceType*     spacetype_new                   (char *name);
 
-void           spacetype_set_winfuncs  (SpaceType *st, SpaceDrawFP draw, SpaceChangeFP change, SpaceHandleFP handle);
+void           spacetype_set_winfuncs  (SpaceType *st, SpacePrefetchDrawFP prefetch, SpaceDrawFP draw, SpaceChangeFP change, SpaceHandleFP handle);
 
        /***/
 
index 617710e1b28eb982327b0e76087b50e00599f4b1..37cae858656384970d8630dd5daa7de336acde76 100644 (file)
@@ -44,6 +44,7 @@ struct Object;
 struct IpoKey;
 struct TransOb;
 struct Tex;
+struct TransInfo;
 
 void remake_object_ipos(struct Object *ob);
 char *getname_ac_ei(int nr);
@@ -138,11 +139,13 @@ void movekey_ipo(int dir);
 void movekey_obipo(int dir);
 void nextkey_ipo(int dir);
 void nextkey_obipo(int dir);
-void remake_ipo_transverts(struct TransVert *transmain, float *dvec, int tot);
-void transform_ipo(int mode);
 void filter_sampledata(float *data, int sfra, int efra);
 void sampledata_to_ipocurve(float *data, int sfra, int efra, struct IpoCurve *icu);
-void ipo_record(void);    
+void ipo_record(void); 
+
+void make_ipo_transdata(struct TransInfo *t);
+void remake_ipo_transdata(struct TransInfo *t);
+void transform_ipo(int mode);   
 
 void actstrip_map_ipo_keys(struct Object *ob, struct Ipo *ipo, short restore, short only_keys);
 
index c975e8de8ff13178676f826b1fd8bb3c296e8adf..47a09e154dfd7c9259c877effcc3857390ff1c1e 100644 (file)
@@ -60,6 +60,15 @@ void set_meta_stripdata(struct Sequence *seqm);
 struct ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chansel); 
 /* chansel: render this channel. Default=0 (renders end result)*/
 
+/* sequence prefetch API */
+void seq_start_threads();
+void seq_stop_threads();
+void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown);
+void seq_wait_for_prefetch_ready();
+struct ImBuf * give_ibuf_threaded(int rectx, int recty, int cfra, 
+                                 int chanshown);
+
+
 void free_imbuf_seq_except(int cfra);
 void free_imbuf_seq_with_ipo(struct Ipo * ipo);
 void free_imbuf_seq(void);
index b81ec202210a7294d7389b79c4dd919b7ca17e77..5ee4f9e84fef67ddfd7908e79d1cab8b90a23cba 100644 (file)
@@ -265,9 +265,10 @@ typedef struct TransInfo {
 #define TD_NOTCONNECTED                8
 #define TD_SINGLESIZE          16      /* used for scaling of MetaElem->rad */
 #ifdef WITH_VERSE
-#define TD_VERSE_OBJECT                32
-#define TD_VERSE_VERT          64
+       #define TD_VERSE_OBJECT         32
+       #define TD_VERSE_VERT           64
 #endif
+#define TD_TIMEONLY                    128
 
 /* transsnap->status */
 #define SNAP_ON                        1
@@ -350,6 +351,7 @@ int TimeScale(TransInfo *t, short mval[2]);
 
 /*********************** transform_conversions.c ********** */
 struct ListBase;
+void flushTransIpoData(TransInfo *t);
 void flushTransUVs(TransInfo *t);
 int clipUVTransform(TransInfo *t, float *vec, int resize);
 
index 5860ca13a5d653a16c498683def2669a523a0cb0..7aa4dbdcf788138feed1b045ad2bfe08364400e1 100644 (file)
@@ -171,6 +171,7 @@ typedef struct UserDef {
        short tw_hotspot, tw_flag, tw_handlesize, tw_size;
        int textimeout, texcollectrate;
        int memcachelimit;
+       int prefetchframes;
        short frameserverport;
        short pad_rot_angle;    /*control the rotation step of the view when PAD2,PAD4,PAD6&PAD8 is use*/
        short obcenter_dia;
@@ -181,7 +182,6 @@ typedef struct UserDef {
        short recent_files;             /* maximum number of recently used files to remember  */
        short smooth_viewtx;    /* miliseconds to spend spinning the view */
        short glreslimit;
-       char pad[4];
 } UserDef;
 
 extern UserDef U; /* from usiblender.c !!!! */
index 97231c8fff337b99fbe771c35cee0e4b978c28ec..a1b052eb67453e455b752848fcd0e81c0c21702d 100644 (file)
@@ -749,11 +749,11 @@ static int wave_setter( BPy_Modifier *self, int type, PyObject *value )
        case EXPP_MOD_SPEED:
                return EXPP_setFloatClamped( value, &md->speed, -2.0, 2.0 );
        case EXPP_MOD_DAMP:
-               return EXPP_setFloatClamped( value, &md->damp, -1000.0, 1000.0 );
+               return EXPP_setFloatClamped( value, &md->damp, -MAXFRAMEF, MAXFRAMEF );
        case EXPP_MOD_LIFETIME:
-               return EXPP_setFloatClamped( value, &md->lifetime, -1000.0, 1000.0 );
+               return EXPP_setFloatClamped( value, &md->lifetime, -MAXFRAMEF, MAXFRAMEF );
        case EXPP_MOD_TIMEOFFS:
-               return EXPP_setFloatClamped( value, &md->timeoffs, -1000.0, 1000.0 );
+               return EXPP_setFloatClamped( value, &md->timeoffs, -MAXFRAMEF, MAXFRAMEF );
        case EXPP_MOD_FLAG:
                return EXPP_setIValueRange( value, &md->flag, 0, 
                                MOD_WAVE_X | MOD_WAVE_Y | MOD_WAVE_CYCL, 'h' );
index 2770f66b318c7995c88605d782449ad17b3b7adb..0c53f470b63bedfe73e16d6bca63ca1f15d35071 100644 (file)
@@ -110,9 +110,9 @@ Example::
        - WIDTH - Used for Wave only (float [0.0 - 5.0])
        - NARROW - Used for Wave only (float [0.0 - 10.0])
        - SPEED - Used for Wave only (float [-2.0 - 2.0])
-       - DAMP - Used for Wave only (float [-1000.0 - 1000.0])
-       - LIFETIME - Used for Wave only (float [-1000.0 - 1000.0])
-       - TIMEOFFS - Used for Wave only (float [-1000.0 - 1000.0])
+       - DAMP - Used for Wave only (float [-MAXFRAME - MAXFRAME])
+       - LIFETIME - Used for Wave only (float [-MAXFRAME - MAXFRAME])
+       - TIMEOFFS - Used for Wave only (float [-MAXFRAME - MAXFRAME])
        
        - OPERATION - Used for boolean only (int 0,1,2 : Intersect, Union, Difference)
        
index 892b2529bbede4c5b1ed8f6a6492ecac6388f11c..0567cd6fb67ec9ba0efa3727d907fc1139f582b8 100644 (file)
@@ -1858,11 +1858,11 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
 
                        uiBlockBeginAlign(block);
                        if(wmd->speed >= 0)
-                               uiDefButF(block, NUM, B_MODIFIER_RECALC, "Time sta:",   lx,(cy-=19),buttonWidth,19, &wmd->timeoffs, -1000.0, 1000.0, 100, 0, "Specify starting frame of the wave");
+                               uiDefButF(block, NUM, B_MODIFIER_RECALC, "Time sta:",   lx,(cy-=19),buttonWidth,19, &wmd->timeoffs, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify starting frame of the wave");
                        else
-                               uiDefButF(block, NUM, B_MODIFIER_RECALC, "Time end:",   lx,(cy-=19),buttonWidth,19, &wmd->timeoffs, -1000.0, 1000.0, 100, 0, "Specify ending frame of the wave");
-                       uiDefButF(block, NUM, B_MODIFIER_RECALC, "Lifetime:",   lx,(cy-=19),buttonWidth,19, &wmd->lifetime,  -1000.0, 1000.0, 100, 0, "Specify the lifespan of the wave");
-                       uiDefButF(block, NUM, B_MODIFIER_RECALC, "Damptime:",   lx,(cy-=19),buttonWidth,19, &wmd->damp,  -1000.0, 1000.0, 100, 0, "Specify the dampingtime of the wave");
+                               uiDefButF(block, NUM, B_MODIFIER_RECALC, "Time end:",   lx,(cy-=19),buttonWidth,19, &wmd->timeoffs, -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify ending frame of the wave");
+                       uiDefButF(block, NUM, B_MODIFIER_RECALC, "Lifetime:",   lx,(cy-=19),buttonWidth,19, &wmd->lifetime,  -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify the lifespan of the wave");
+                       uiDefButF(block, NUM, B_MODIFIER_RECALC, "Damptime:",   lx,(cy-=19),buttonWidth,19, &wmd->damp,  -MAXFRAMEF, MAXFRAMEF, 100, 0, "Specify the dampingtime of the wave");
                        cy -= 9;
                        uiBlockBeginAlign(block);
                        uiDefButF(block, NUM, B_MODIFIER_RECALC, "Sta x:",              lx,(cy-=19),113,19, &wmd->startx, -100.0, 100.0, 100, 0, "Starting position for the X axis");
index 25e0ceed1ca2eeba3a46fd58c62f7a03f5b8b7bb..27862091a45ffae2cd7be51787ec4c86c3ce7eac 100644 (file)
@@ -445,10 +445,31 @@ static void drawcursor_sima(float xuser_asp, float yuser_asp)
        setlinestyle(0);
 }
 
-/* draws uv's in the image space */
+// checks if we are selecting only faces
+static int draw_uvs_face_check(void)
+{
+       if (G.sima==NULL)
+               return 0;
+       if (G.sima->flag & SI_SYNC_UVSEL && G.scene->selectmode == SCE_SELECT_FACE)
+               return 2;
+       if (G.sima->flag & SI_SELACTFACE)
+               return 1;
+       return 0;
+}
 
+void tface_center(MTFace *tf, float cent[2], void * isquad)
+{
 
+       if (isquad) {
+               cent[0] = (tf->uv[0][0] + tf->uv[1][0] + tf->uv[2][0] + tf->uv[3][0]) / 4.0;
+               cent[1] = (tf->uv[0][1] + tf->uv[1][1] + tf->uv[2][1] + tf->uv[3][1]) / 4.0;            
+       } else {
+               cent[0] = (tf->uv[0][0] + tf->uv[1][0] + tf->uv[2][0]) / 3.0;
+               cent[1] = (tf->uv[0][1] + tf->uv[1][1] + tf->uv[2][1]) / 3.0;           
+       }
+}
 
+/* draws uv's in the image space */
 void draw_uvs_sima(void)
 {
        MTFace *tface,*activetface = NULL;
@@ -457,10 +478,13 @@ void draw_uvs_sima(void)
        
        char col1[4], col2[4];
        float pointsize;
+       int drawface;
        
        if (!G.obedit || !CustomData_has_layer(&em->fdata, CD_MTFACE))
                return;
        
+       drawface = draw_uvs_face_check();
+       
        calc_image_view(G.sima, 'f');   /* float */
        myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax);
        glLoadIdentity();
@@ -624,7 +648,7 @@ void draw_uvs_sima(void)
                break;
        case SI_UVDT_BLACK: /* black/white */
        case SI_UVDT_WHITE: 
-               cpack((G.sima->dt_uv==SI_UVDT_WHITE) ? 0x0 : 0xFFFFFF);
+               cpack((G.sima->dt_uv==SI_UVDT_WHITE) ? 0xFFFFFF : 0x0);
                for (efa= em->faces.first; efa; efa= efa->next) {
 //                     tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
 //                     if (SIMA_FACEDRAW_CHECK(efa, tface)) {
@@ -686,74 +710,121 @@ void draw_uvs_sima(void)
                glDisable(GL_BLEND);
        }
 
-    /* unselected uv's */
-       BIF_ThemeColor(TH_VERTEX);
-       pointsize = BIF_GetThemeValuef(TH_VERTEX_SIZE);
-       glPointSize(pointsize);
-
-       bglBegin(GL_POINTS);
-       for (efa= em->faces.first; efa; efa= efa->next) {
+       if (drawface) {
+               // draw UV face points
+               float cent[2];
                
-//             tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-//             if (SIMA_FACEDRAW_CHECK(efa, tface)) {
                
-               /*this is a shortcut to do the same as above but a faster for drawing */
-               if ((tface=(MTFace *)efa->tmp.p)) {
+           /* unselected faces's */
+               pointsize = BIF_GetThemeValuef(TH_FACEDOT_SIZE);
+               // TODO - drawobject.c changes this value after - Investiagate!
+               glPointSize(pointsize);
                
-                       if(SIMA_UVSEL_CHECK(efa, tface, 0)); else bglVertex2fv(tface->uv[0]);
-                       if(SIMA_UVSEL_CHECK(efa, tface, 1)); else bglVertex2fv(tface->uv[1]);
-                       if(SIMA_UVSEL_CHECK(efa, tface, 2)); else bglVertex2fv(tface->uv[2]);
-                       if(efa->v4) {
-                               if(SIMA_UVSEL_CHECK(efa, tface, 3)); else bglVertex2fv(tface->uv[3]);
+               BIF_ThemeColor(TH_WIRE);
+               bglBegin(GL_POINTS);
+               for (efa= em->faces.first; efa; efa= efa->next) {
+                       
+//                     tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+//                     if (SIMA_FACEDRAW_CHECK(efa, tface)) {
+                       
+                       /*this is a shortcut to do the same as above but a faster for drawing */
+                       if ((tface=(MTFace *)efa->tmp.p)) {
+                               if( ! SIMA_FACESEL_CHECK(efa, tface) ) {
+                                       tface_center(tface, cent, (void *)efa->v4);
+                                       bglVertex2fv(cent);
+                               }
                        }
                }
-       }
-       bglEnd();
-
-       /* pinned uv's */
-       /* give odd pointsizes odd pin pointsizes */
-    glPointSize(pointsize*2 + (((int)pointsize % 2)? (-1): 0));
-       cpack(0xFF);
-
-       bglBegin(GL_POINTS);
-       for (efa= em->faces.first; efa; efa= efa->next) {
-//             tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-//             if (SIMA_FACEDRAW_CHECK(efa, tface)) {
-               
-               /*this is a shortcut to do the same as above but a faster for drawing */
-               if ((tface=(MTFace *)efa->tmp.p)) {
+               bglEnd();
+               /* selected faces's */
+               BIF_ThemeColor(TH_FACE_DOT);
+               bglBegin(GL_POINTS);
+               for (efa= em->faces.first; efa; efa= efa->next) {
                        
-                       if(tface->unwrap & TF_PIN1) bglVertex2fv(tface->uv[0]);
-                       if(tface->unwrap & TF_PIN2) bglVertex2fv(tface->uv[1]);
-                       if(tface->unwrap & TF_PIN3) bglVertex2fv(tface->uv[2]);
-                       if(efa->v4) {
-                               if(tface->unwrap & TF_PIN4) bglVertex2fv(tface->uv[3]);
+//                     tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+//                     if (SIMA_FACEDRAW_CHECK(efa, tface)) {
+                       
+                       /*this is a shortcut to do the same as above but a faster for drawing */
+                       if ((tface=(MTFace *)efa->tmp.p)) {
+                               if( SIMA_FACESEL_CHECK(efa, tface) ) {
+                                       tface_center(tface, cent, (void *)efa->v4);
+                                       bglVertex2fv(cent);
+                               }
                        }
                }
+               bglEnd();
        }
-       bglEnd();
-
-       /* selected uv's */
-       BIF_ThemeColor(TH_VERTEX_SELECT);
-    glPointSize(pointsize);
-
-       bglBegin(GL_POINTS);
-       for (efa= em->faces.first; efa; efa= efa->next) {
-//             tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-//             if (SIMA_FACEDRAW_CHECK(efa, tface)) {
-               
-               /*this is a shortcut to do the same as above but a faster for drawing */
-               if ((tface=(MTFace *)efa->tmp.p)) {
-               
-                       if(!SIMA_UVSEL_CHECK(efa, tface, 0)); else bglVertex2fv(tface->uv[0]);
-                       if(!SIMA_UVSEL_CHECK(efa, tface, 1)); else bglVertex2fv(tface->uv[1]);
-                       if(!SIMA_UVSEL_CHECK(efa, tface, 2)); else bglVertex2fv(tface->uv[2]);
-                       if(efa->v4) {
-                               if(!SIMA_UVSEL_CHECK(efa, tface, 3)); else bglVertex2fv(tface->uv[3]);
+       
+       if (drawface != 2) { /* 2 means Mesh Face Mode */
+           /* unselected uv's */
+               BIF_ThemeColor(TH_VERTEX);
+               pointsize = BIF_GetThemeValuef(TH_VERTEX_SIZE);
+               glPointSize(pointsize);
+       
+               bglBegin(GL_POINTS);
+               for (efa= em->faces.first; efa; efa= efa->next) {
+                       
+//                     tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+//                     if (SIMA_FACEDRAW_CHECK(efa, tface)) {
+                       
+                       /*this is a shortcut to do the same as above but a faster for drawing */
+                       if ((tface=(MTFace *)efa->tmp.p)) {
+                       
+                               if(SIMA_UVSEL_CHECK(efa, tface, 0)); else bglVertex2fv(tface->uv[0]);
+                               if(SIMA_UVSEL_CHECK(efa, tface, 1)); else bglVertex2fv(tface->uv[1]);
+                               if(SIMA_UVSEL_CHECK(efa, tface, 2)); else bglVertex2fv(tface->uv[2]);
+                               if(efa->v4) {
+                                       if(SIMA_UVSEL_CHECK(efa, tface, 3)); else bglVertex2fv(tface->uv[3]);
+                               }
+                       }
+               }
+               bglEnd();
+       
+               /* pinned uv's */
+               /* give odd pointsizes odd pin pointsizes */
+           glPointSize(pointsize*2 + (((int)pointsize % 2)? (-1): 0));
+               cpack(0xFF);
+       
+               bglBegin(GL_POINTS);
+               for (efa= em->faces.first; efa; efa= efa->next) {
+//                     tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+//                     if (SIMA_FACEDRAW_CHECK(efa, tface)) {
+                       
+                       /*this is a shortcut to do the same as above but a faster for drawing */
+                       if ((tface=(MTFace *)efa->tmp.p)) {
+                               
+                               if(tface->unwrap & TF_PIN1) bglVertex2fv(tface->uv[0]);
+                               if(tface->unwrap & TF_PIN2) bglVertex2fv(tface->uv[1]);
+                               if(tface->unwrap & TF_PIN3) bglVertex2fv(tface->uv[2]);
+                               if(efa->v4) {
+                                       if(tface->unwrap & TF_PIN4) bglVertex2fv(tface->uv[3]);
+                               }
+                       }
+               }
+               bglEnd();
+       
+               /* selected uv's */
+               BIF_ThemeColor(TH_VERTEX_SELECT);
+           glPointSize(pointsize);
+       
+               bglBegin(GL_POINTS);
+               for (efa= em->faces.first; efa; efa= efa->next) {
+//                     tface= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+//                     if (SIMA_FACEDRAW_CHECK(efa, tface)) {
+                       
+                       /*this is a shortcut to do the same as above but a faster for drawing */
+                       if ((tface=(MTFace *)efa->tmp.p)) {
+                       
+                               if(!SIMA_UVSEL_CHECK(efa, tface, 0)); else bglVertex2fv(tface->uv[0]);
+                               if(!SIMA_UVSEL_CHECK(efa, tface, 1)); else bglVertex2fv(tface->uv[1]);
+                               if(!SIMA_UVSEL_CHECK(efa, tface, 2)); else bglVertex2fv(tface->uv[2]);
+                               if(efa->v4) {
+                                       if(!SIMA_UVSEL_CHECK(efa, tface, 3)); else bglVertex2fv(tface->uv[3]);
+                               }
                        }
                }
+               bglEnd();       
        }
-       bglEnd();       
        glPointSize(1.0);
 }
 
@@ -1165,8 +1236,8 @@ static void image_panel_view_properties(short cntrl)      // IMAGE_HANDLER_VIEW_PROPE
                uiDefBut(block, LABEL, B_NOP, "Draw Type:",             10, 20,120,19, 0, 0, 0, 0, 0, "");
                uiBlockBeginAlign(block);
                uiDefButC(block,  ROW, B_REDR, "Dash",                  10, 0,58,19, &G.sima->dt_uv, 0.0, SI_UVDT_DASH, 0, 0, "Dashed Wire UV drawtype");
-               uiDefButC(block,  ROW, B_REDR, "Black",                 68, 0,58,19, &G.sima->dt_uv, 0.0, SI_UVDT_WHITE, 0, 0, "Black Wire UV drawtype");
-               uiDefButC(block,  ROW, B_REDR, "White",                 126,0,58,19, &G.sima->dt_uv, 0.0, SI_UVDT_BLACK, 0, 0, "White Wire UV drawtype");
+               uiDefButC(block,  ROW, B_REDR, "Black",                 68, 0,58,19, &G.sima->dt_uv, 0.0, SI_UVDT_BLACK, 0, 0, "Black Wire UV drawtype");
+               uiDefButC(block,  ROW, B_REDR, "White",                 126,0,58,19, &G.sima->dt_uv, 0.0, SI_UVDT_WHITE, 0, 0, "White Wire UV drawtype");
                uiDefButC(block,  ROW, B_REDR, "Outline",               184,0,58,19, &G.sima->dt_uv, 0.0, SI_UVDT_OUTLINE, 0, 0, "Outline Wire UV drawtype");
                uiBlockBeginAlign(block);
                uiDefButBitI(block, TOG, SI_SMOOTH_UV, B_REDR, "Smooth",        250,0,60,19,  &G.sima->flag, 0, 0, 0, 0, "Display smooth lines in the UV view");
index 6be61478593d213ec6d5d527931115896e6ff91c..f637734fa345f28ad1f4d3070a2bf3a87598e5d6 100644 (file)
@@ -2410,9 +2410,14 @@ static int draw_mesh_object(Base *base, int dt, int flag)
                if(dt>OB_WIRE) init_gl_materials(ob, 0);        // no transp in editmode, the fancy draw over goes bad then
                draw_em_fancy(ob, G.editMesh, cageDM, finalDM, dt);
 
-               if (cageDM != finalDM)
+               /* TODO, not 100% sure this is correct,
+                * however I could not make it crash or leak ram with different
+                * linked-dup/modifier configurtions,
+                * should double check whats going on before release - Campbell */
+               if (cageDM != finalDM) {
                        cageDM->release(cageDM);
-               finalDM->release(finalDM);
+                       finalDM->release(finalDM);
+               }
        }
        else if(!G.obedit && (G.f & G_SCULPTMODE) &&(G.scene->sculptdata.flags & SCULPT_DRAW_FAST) &&
                OBACT==ob && !sculpt_modifiers_active(ob)) {
index aaef04283b09ab10f730d3680cd00c06332f334a..86246759a3b6b71eeedb7e2efdb6beaec38075cc 100644 (file)
@@ -51,6 +51,7 @@
 #include "DNA_screen_types.h"
 #include "DNA_space_types.h"
 #include "DNA_view2d_types.h"
+#include "DNA_userdef_types.h"
 
 #include "BKE_global.h"
 #include "BKE_plugin_types.h"
@@ -788,7 +789,11 @@ static void draw_image_seq(ScrArea *sa)
                return;
        else {
                recursive= 1;
-               ibuf= (ImBuf *)give_ibuf_seq(rectx, recty, (G.scene->r.cfra), sseq->chanshown);
+               if (!U.prefetchframes || (G.f & G_PLAYANIM) == 0) {
+                       ibuf= (ImBuf *)give_ibuf_seq(rectx, recty, (G.scene->r.cfra), sseq->chanshown);
+               } else {
+                       ibuf= (ImBuf *)give_ibuf_threaded(rectx, recty, (G.scene->r.cfra), sseq->chanshown);
+               }
                recursive= 0;
                
                /* HURMF! the give_ibuf_seq can call image display in this window */
@@ -1276,6 +1281,20 @@ static void seq_blockhandlers(ScrArea *sa)
 
 }
 
+void drawprefetchseqspace(ScrArea *sa, void *spacedata)
+{
+       SpaceSeq *sseq= sa->spacedata.first;
+       int rectx, recty;
+
+       rectx= (G.scene->r.size*G.scene->r.xsch)/100;
+       recty= (G.scene->r.size*G.scene->r.ysch)/100;
+
+       if(sseq->mainb) {
+               give_ibuf_prefetch_request(
+                       rectx, recty, (G.scene->r.cfra), sseq->chanshown);
+       }
+}
+
 void drawseqspace(ScrArea *sa, void *spacedata)
 {
        SpaceSeq *sseq= sa->spacedata.first;
index de4a81abb959062125796bb869d9e8bcc19dd6d2..2bcc7ed76a7c204f14dec88fdcf7809468c2ad76 100644 (file)
 #include "BSE_filesel.h"
 #include "BSE_headerbuttons.h"
 #include "BSE_seqaudio.h"
+#include "BSE_sequence.h"
 #include "BSE_trans_types.h"
 #include "BSE_time.h"
 #include "BSE_view.h"
@@ -3172,13 +3173,20 @@ void drawview3d_render(struct View3D *v3d, int winx, int winy)
 
 
 double tottime = 0.0;
+static ScrArea *oldsa;
+static double swaptime;
+static int curmode;
 
 int update_time(void)
 {
        static double ltime;
        double time;
 
-       if ((U.mixbufsize)&&(audiostream_pos() != CFRA)&&(G.scene->audio.flag & AUDIO_SYNC)) return 0;
+       if ((U.mixbufsize)
+           && (audiostream_pos() != CFRA)
+           && (G.scene->audio.flag & AUDIO_SYNC)) {
+               return 0;
+       }
 
        time = PIL_check_seconds_timer();
        
@@ -3187,60 +3195,169 @@ int update_time(void)
        return (tottime < 0.0);
 }
 
-void inner_play_anim_loop(int init, int mode)
+static void inner_play_prefetch_frame(int mode, int cfra)
 {
        ScrArea *sa;
-       static ScrArea *oldsa;
-       static double swaptime;
-       static int curmode;
-
-       /* init */
-       if(init) {
-               oldsa= curarea;
-               swaptime= 1.0/(float)G.scene->r.frs_sec;
-               tottime= 0.0;
-               curmode= mode;
+       int oldcfra = CFRA;
+       ScrArea *oldcurarea = curarea;
 
+       if (!U.prefetchframes) {
                return;
        }
 
-       set_timecursor(CFRA);
-       
-       update_for_newframe_nodraw(1);  /* adds no events in UI */
+       CFRA = cfra;
 
        sa= G.curscreen->areabase.first;
        while(sa) {
                if(sa==oldsa) {
-                       scrarea_do_windraw(sa);
+                       scrarea_do_winprefetchdraw(sa);
                }
-               else if(curmode & 1) { /* all view3d and seq spaces */
+               else if(mode & 1) { /* all view3d and seq spaces */
                        if ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_SEQ) {
-                               scrarea_do_windraw(sa);
+                               scrarea_do_winprefetchdraw(sa);
                        }
                }
-               else if(curmode & 4) { /* all seq spaces */
+               else if(mode & 4) { /* all seq spaces */
                        if (sa->spacetype == SPACE_SEQ) {
-                               scrarea_do_windraw(sa);
+                               scrarea_do_winprefetchdraw(sa);
                        }
                }               
                
                sa= sa->next;   
        }
+
+       CFRA = oldcfra;
+       curarea = oldcurarea;
+}
+
+static void inner_play_prefetch_startup(int mode)
+{
+       int i;
+
+       if (!U.prefetchframes) {
+               return;
+       }
+
+       seq_start_threads();
+
+       for (i = 0; i <= U.prefetchframes; i++) {
+               int cfra = CFRA + i;
+               inner_play_prefetch_frame(mode, cfra);
+       }
+
+       seq_wait_for_prefetch_ready();
+}
+
+static void inner_play_prefetch_shutdown(int mode)
+{
+       if (!U.prefetchframes) {
+               return;
+       }
+       seq_stop_threads();
+}
+
+void inner_play_anim_loop(int init, int mode)
+{
+       ScrArea *sa;
+       static int last_cfra = -1;
+
+       /* init */
+       if(init) {
+               oldsa= curarea;
+               swaptime= 1.0/(float)G.scene->r.frs_sec;
+               tottime= 0.0;
+               curmode= mode;
+               last_cfra = -1;
+
+               return;
+       }
+
+       if (CFRA != last_cfra) {
+               int pf;
+               set_timecursor(CFRA);
        
+               update_for_newframe_nodraw(1);  /* adds no events in UI */
+
+               sa= G.curscreen->areabase.first;
+               while(sa) {
+                       if(sa==oldsa) {
+                               scrarea_do_windraw(sa);
+                       }
+                       else if(curmode & 1) { /* all view3d and seq spaces */
+                               if ELEM(sa->spacetype, SPACE_VIEW3D, SPACE_SEQ) {
+                                       scrarea_do_windraw(sa);
+                               }
+                       }
+                       else if(curmode & 4) { /* all seq spaces */
+                               if (sa->spacetype == SPACE_SEQ) {
+                                       scrarea_do_windraw(sa);
+                               }
+                       }               
+               
+                       sa= sa->next;   
+               }
+
+               if (last_cfra == -1) {
+                       last_cfra = CFRA - 1;
+               }
+               
+               if (U.prefetchframes) {
+                       pf = last_cfra;
+
+                       if (CFRA - last_cfra >= U.prefetchframes || 
+                           CFRA - last_cfra < 0) {
+                               pf = CFRA - U.prefetchframes;
+                               fprintf(stderr, 
+                                       "SEQ-THREAD: Lost sync, "
+                                       "stopping threads, "
+                                       "back to skip mode...\n");
+                               seq_stop_threads();
+                       } else {
+                               while (pf < CFRA) {
+                                       int c;
+                                       pf++;
+                                       c = pf + U.prefetchframes;
+                                       if (c >= PEFRA) {
+                                               c -= PEFRA;
+                                               c += PSFRA;
+                                       }
+
+                                       inner_play_prefetch_frame(curmode, c);
+                               }
+                       }
+                       
+               }
+       }
+
+       last_cfra = CFRA;
+
        /* make sure that swaptime passed by */
        tottime -= swaptime;
-       while (update_time()) PIL_sleep_ms(1);
-
-       if(CFRA>=PEFRA) {
-               if (tottime > 0.0) tottime = 0.0;
-               CFRA= PSFRA;
+       while (update_time()) {
+               PIL_sleep_ms(1);
+       }
+       
+       if (CFRA >= PEFRA) {
+               if (tottime > 0.0) {
+                       tottime = 0.0;
+               }
+               CFRA = PSFRA;
                audiostream_stop();
                audiostream_start( CFRA );
+       } else {
+               if (U.mixbufsize 
+                   && (G.scene->audio.flag & AUDIO_SYNC)) {
+                       CFRA = audiostream_pos();
+               } else {
+                       CFRA++;
+               }
+               if (CFRA < last_cfra) {
+                       fprintf(stderr, 
+                               "SEQ-THREAD: CFRA running backwards: %d\n",
+                               CFRA);
+               }
        }
-       else {
-               if (U.mixbufsize && (G.scene->audio.flag & AUDIO_SYNC)) CFRA = audiostream_pos();
-               else CFRA++;
-       }
+
 }
 
 /* play_anim: 'mode' defines where to play and if repeat is on (now bitfield):
@@ -3261,22 +3378,24 @@ int play_anim(int mode)
 
        if(PSFRA>PEFRA) return 0;
        
-       update_time();
-
        /* waitcursor(1); */
        G.f |= G_PLAYANIM;              /* in sequence.c and view.c this is handled */
 
        cfraont= CFRA;
        oldsa= curarea;
 
-       audiostream_start( CFRA );
-       
        if (curarea && curarea->spacetype == SPACE_SEQ) {
                SpaceSeq *sseq = curarea->spacedata.first;
                if (sseq->mainb == 0) mode |= 4;
        }
+
+       inner_play_prefetch_startup(mode);
+
+       update_time();
        
        inner_play_anim_loop(1, mode);  /* 1==init */
+
+       audiostream_start( CFRA );
        
         /* forces all buffers to be OK for current frame (otherwise other windows get redrawn with CFRA+1) */
        curarea->win_swap= WIN_BACK_OK;
@@ -3317,6 +3436,7 @@ int play_anim(int mode)
        if(event==SPACEKEY);
        else CFRA= cfraont;
        
+       inner_play_prefetch_shutdown(mode);
        audiostream_stop();
 
        if(oldsa!=curarea) areawinset(oldsa->win);
index 75cded52010ebe52681cbe063fa5ff77338a9c98..025dfcc78864082a5e891b12677780fa09e2a456 100644 (file)
 
 #include "blendef.h"
 #include "mydevice.h"
+#include "transform.h"
 
 extern int ob_ar[];
 extern int ma_ar[];
@@ -4763,485 +4764,392 @@ void movekey_obipo(int dir)           /* only call external from view3d queue */
 
 }
 /* **************************************************** */
+/* IPO TRANSFORM TOOLS 
+ * 
+ * Only the helper functions are stored here these days. They are here as
+ * there are heaps of ugly globals which the IPO editor relies on. 
+ * However, the actual transforms go through the transform system these days.
+ */
 
-
-void remake_ipo_transverts(TransVert *transmain, float *dvec, int tot)
+/* Helper function for make_ipo_transdata, which is reponsible for associating
+ * source data with transform data
+ */
+static void bezt_to_transdata (TransData *td, TransData2D *td2d, float *loc, float *cent, short selected, short onlytime)
 {
-       EditIpo *ei;
-       TransVert *tv;
-       BezTriple *bezt;
-       int a, b;
+       /* New location from td gets dumped onto the old-location of td2d, which then
+        * gets copied to the actual data at td2d->loc2d (bezt->vec[n])
+        *
+        * Due to NLA scaling, we apply NLA scaling to some of the verts here,
+        * and then that scaling will be undone after transform is done.
+        */
        
-       ei= G.sipo->editipo;
-       for(a=0; a<G.sipo->totipo; a++, ei++) {
+       if (NLA_IPO_SCALED) {
+               td2d->loc[0] = get_action_frame_inv(OBACT, loc[0]);
+               td2d->loc[1] = loc[1];
+               td2d->loc[2] = 0.0f;
+               td2d->loc2d = loc;
                
-               if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) {
-                               
-                       if(ei->icu->bezt) {
-                               sort_time_ipocurve(ei->icu);
-                       }
-               }
+               td->flag = 0;
+               td->loc = td2d->loc;
+               VECCOPY(td->center, cent);
+               VECCOPY(td->iloc, td->loc);
        }
-
-       ei= G.sipo->editipo;
-       tv= transmain;
-       for(a=0; a<G.sipo->totipo; a++, ei++) {
+       else {
+               td2d->loc[0] = loc[0];
+               td2d->loc[1] = loc[1];
+               td2d->loc[2] = 0.0f;
+               td2d->loc2d = loc;
                
-               if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) {
-                       if( (ei->flag & IPO_EDIT) || G.sipo->showkey) {
-                               if(ei->icu->bezt) {
-                                       bezt= ei->icu->bezt;
-                                       b= ei->icu->totvert;
-                                       while(b--) {
-                                               if(ei->icu->ipo==IPO_BEZ) {
-                                                       if(bezt->f1 & 1) {
-                                                               tv->loc= bezt->vec[0];
-                                                               tv++;
-                                                       }
-                                                       if(bezt->f3 & 1) {
-                                                               tv->loc= bezt->vec[2];
-                                                               tv++;
-                                                       }
-                                               }
-                                               if(bezt->f2 & 1) {
-                                                       tv->loc= bezt->vec[1];
-                                                       tv++;
-                                               }
-                                               
-                                               bezt++;
-                                       }
-                                       testhandles_ipocurve(ei->icu);
-                               }
-                       }
-               }
+               td->flag = 0;
+               td->loc = td2d->loc;
+               VECCOPY(td->center, cent);
+               VECCOPY(td->iloc, td->loc);
        }
+
+       memset(td->axismtx, 0, sizeof(td->axismtx));
+       td->axismtx[2][2] = 1.0f;
+
+       td->ext= NULL; td->tdi= NULL; td->val= NULL;
+
+       if (selected) {
+               td->flag |= TD_SELECTED;
+               td->dist= 0.0;
+       }
+       else
+               td->dist= MAXFLOAT;
+       
+       if (onlytime)
+               td->flag |= TD_TIMEONLY;
+       
+       Mat3One(td->mtx);
+       Mat3One(td->smtx);
+}      
+/* This function is called by createTransIpoData and remake_ipo_transdata to
+ * create the TransData and TransData2D arrays for transform. The costly counting
+ * stage is only performed for createTransIpoData case, and is indicated by t->total==-1;
+ */
+void make_ipo_transdata (TransInfo *t)
+{
+       TransData *td = NULL;
+       TransData2D *td2d = NULL;
        
-       if(G.sipo->showkey) make_ipokey();
+       EditIpo *ei;
+       BezTriple *bezt;
+       int a, b;
        
-       if(dvec==0) return;
+       /* countsel and propmode are used for proportional edit, which is not yet available */
+       int count=0/*, countsel=0*/;
+       /*int propmode = t->flag & T_PROP_EDIT;*/
        
-       tv= transmain;
-       for(a=0; a<tot; a++, tv++) {
-               if (NLA_IPO_SCALED) {
-                       tv->oldloc[0] = get_action_frame_inv(OBACT, tv->loc[0]);
-                       tv->oldloc[0]-= dvec[0];
-                       tv->oldloc[0] = get_action_frame(OBACT, tv->oldloc[0]);
+       /* count data and allocate memory (if needed) */
+       if (t->total == 0) {
+               /* count data first */
+               if (totipo_vertsel) {
+                       /* we're probably in editmode, so only selected verts */
+                       count= totipo_vertsel;
+               }
+               else if (totipo_edit==0 && totipo_sel!=0) {
+                       /* we're not in editmode, so entire curves get moved */
+                       ei= G.sipo->editipo;
+                       for (a=0; a<G.sipo->totipo; a++, ei++) {
+                               if (ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu)) {
+                                       if (ei->icu->bezt && ei->icu->ipo==IPO_BEZ)
+                                               count+= 3*ei->icu->totvert;
+                                       else 
+                                               count+= ei->icu->totvert;
+                               }
+                       }
+                       if (count==0) return;
                }
                else {
-                       tv->oldloc[0]= tv->loc[0]-dvec[0];
+                       /* this case should not happen */
+                       return;
                }
-               tv->oldloc[1]= tv->loc[1]-dvec[1];
+               
+               /* memory allocation */
+               /*t->total= (propmode)? count: countsel;*/
+               t->total= count;
+               t->data= MEM_callocN(t->total*sizeof(TransData), "TransData (IPO Editor)");
+                       /* for each 2d vert a 3d vector is allocated, so that they can be treated just as if they were 3d verts */
+               t->data2d= MEM_callocN(t->total*sizeof(TransData2D), "TransData2D (IPO Editor)");
        }
-}
-
-#define CLAMP_OFF      0
-#define CLAMP_X                1
-#define CLAMP_Y                2
-
-void transform_ipo(int mode)
-{
-       EditIpo *ei;
-       BezTriple *bezt;
-       TransVert *transmain = NULL, *tv;
-       float dx, dy, dvec[2], min[3], max[3], vec[2], div, cent[2], size[2], sizefac;
-       int tot=0, a, b, firsttime=1, afbreek=0, dosort, clampAxis=CLAMP_OFF;
-       unsigned short event = 0;
-       short mval[2], val, xo, yo, xn, yn, xc, yc;
-       char str[64];
-       
-       if(G.sipo->ipo && G.sipo->ipo->id.lib) return;
-       if(G.sipo->editipo==0) return;
-       if(mode=='r') return;   /* from gesture */
        
-       INIT_MINMAX(min, max);
+       td= t->data;
+       td2d= t->data2d;
        
-       /* which vertices are involved */
-       get_status_editipo();
-       if(totipo_vertsel) {
-               tot= totipo_vertsel;
-               tv=transmain= MEM_callocN(tot*sizeof(TransVert), "transmain");
-               
+       /* add verts */
+       if (totipo_vertsel) {
+               /* we're probably in editmode, so only selected verts */
                ei= G.sipo->editipo;
-               for(a=0; a<G.sipo->totipo; a++, ei++) {
-                       
+               for (a=0; a<G.sipo->totipo; a++, ei++) {
+                       /* only consider those curves that are visible and are being edited/used for showkeys */
                        if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) {
-                               if( (ei->flag & IPO_EDIT) || G.sipo->showkey) {
-
-                               
-                                       if(ei->icu->bezt) {
+                               if ( (ei->flag & IPO_EDIT) || G.sipo->showkey) {
+                                       if (ei->icu->bezt) {
                                                bezt= ei->icu->bezt;
-                                               b= ei->icu->totvert;
-                                               while(b--) {
-                                                       if(ei->icu->ipo==IPO_BEZ) {
-                                                               if(bezt->f1 & 1) {
-                                                                       tv->loc= bezt->vec[0];
-                                                                       VECCOPY(tv->oldloc, tv->loc);
-                                                                       if(ei->disptype==IPO_DISPBITS) tv->flag= 1;
-                                                                       
-                                                                       /* we take the middle vertex */
-                                                                       DO_MINMAX2(bezt->vec[1], min, max);
-
-                                                                       tv++;
-                                                               }
-                                                               if(bezt->f3 & 1) {
-                                                                       tv->loc= bezt->vec[2];
-                                                                       VECCOPY(tv->oldloc, tv->loc);
-                                                                       if(ei->disptype==IPO_DISPBITS) tv->flag= 1;
-                                                                       
-                                                                       /* we take the middle vertex */
-                                                                       DO_MINMAX2(bezt->vec[1], min, max);
-
-                                                                       tv++;
-                                                               }
+                                               
+                                               for (b=0; b < ei->icu->totvert; b++, bezt++) {
+                                                       /* only include handles if selected, and interpolaton mode uses beztriples */
+                                                       if (ei->icu->ipo==IPO_BEZ) {
+                                                               if (bezt->f1 & 1)
+                                                                       bezt_to_transdata(td++, td2d++, bezt->vec[0], bezt->vec[1], 1, (ei->disptype==IPO_DISPBITS));
+                                                               if (bezt->f3 & 1)
+                                                                       bezt_to_transdata(td++, td2d++, bezt->vec[2], bezt->vec[1], 1, (ei->disptype==IPO_DISPBITS));
                                                        }
-                                                       if(bezt->f2 & 1) {
-                                                               tv->loc= bezt->vec[1];
-                                                               VECCOPY(tv->oldloc, tv->loc);
-                                                               if(ei->disptype==IPO_DISPBITS) tv->flag= 1;
-                                                               DO_MINMAX2(bezt->vec[1], min, max);
-                                                               tv++;
+                                                       
+                                                       /* only include main vert if selected */
+                                                       if (bezt->f2 & 1) {
+                                                               bezt_to_transdata(td++, td2d++, bezt->vec[1], bezt->vec[1], 1, (ei->disptype==IPO_DISPBITS));
                                                        }
-                                                       bezt++;
                                                }
                                        }
                                }
                        }
                }
-               
        }
-       else if(totipo_edit==0 && totipo_sel!=0) {
-               
-               ei= G.sipo->editipo;
-               for(a=0; a<G.sipo->totipo; a++, ei++) {
-                       if (ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu)) {
-                               if(ei->icu->bezt && ei->icu->ipo==IPO_BEZ) tot+= 3*ei->icu->totvert;
-                               else tot+= ei->icu->totvert;
-                       }
-               }
-               if(tot==0) return;
-               
-               tv=transmain= MEM_callocN(tot*sizeof(TransVert), "transmain");
-
+       else if (totipo_edit==0 && totipo_sel!=0) {
+               /* we're not in editmode, so entire curves get moved */
                ei= G.sipo->editipo;
-               for(a=0; a<G.sipo->totipo; a++, ei++) {
+               for (a=0; a<G.sipo->totipo; a++, ei++) {
+                       /* only include curves that are visible and selected */
                        if (ISPOIN3(ei, flag & IPO_VISIBLE, flag & IPO_SELECT, icu)) {
-                               if(ei->icu->bezt) {
-                                       
+                               if (ei->icu->bezt) {
                                        bezt= ei->icu->bezt;
                                        b= ei->icu->totvert;
-                                       while(b--) {
-                                               if(ei->icu->ipo==IPO_BEZ) {
-                                                       tv->loc= bezt->vec[0];
-                                                       VECCOPY(tv->oldloc, tv->loc);
-                                                       if(ei->disptype==IPO_DISPBITS) tv->flag= 1;
-                                                       tv++;
-                                               
-                                                       tv->loc= bezt->vec[2];
-                                                       VECCOPY(tv->oldloc, tv->loc);
-                                                       if(ei->disptype==IPO_DISPBITS) tv->flag= 1;
-                                                       tv++;
+                                       for (b=0; b < ei->icu->totvert; b++, bezt++) {
+                                               /* only include handles if interpolation mode is bezier not bpoint */
+                                               if (ei->icu->ipo==IPO_BEZ) {
+                                                       bezt_to_transdata(td++, td2d++, bezt->vec[0], bezt->vec[1], 1, (ei->disptype==IPO_DISPBITS));
+                                                       bezt_to_transdata(td++, td2d++, bezt->vec[2], bezt->vec[1], 1, (ei->disptype==IPO_DISPBITS));
                                                }
-                                               tv->loc= bezt->vec[1];
-                                               VECCOPY(tv->oldloc, tv->loc);
-                                               if(ei->disptype==IPO_DISPBITS) tv->flag= 1;
                                                
-                                               DO_MINMAX2(bezt->vec[1], min, max);
-                                               
-                                               tv++;
-                                               
-                                               bezt++;
+                                               /* always include the main handle */
+                                               bezt_to_transdata(td++, td2d++, bezt->vec[1], bezt->vec[1], 1, (ei->disptype==IPO_DISPBITS));
                                        }
                                }
                        }
                }
-
        }
+}
 
-       if(tot==0) {
-               if(totipo_edit==0) move_keys(OBACT);
-               return;
-       }
+/* ------------------------ */
 
-       cent[0]= (float)((min[0]+max[0])/2.0);
-       cent[1]= (float)((min[1]+max[1])/2.0);
+/* struct for use in re-sorting BezTriples during IPO transform */
+typedef struct BeztMap {
+       BezTriple *bezt;
+       int oldIndex;
+       int newIndex;
+       short handles;
+} BeztMap;
 
-       if(G.sipo->showkey) {
-               clampAxis = CLAMP_Y;
-       }
+#define BEZM_FLIPH             1
+#define BEZM_CLEARH1   2
+#define BEZM_CLEARH2   4
+
+/* This function converts an IpoCurve's BezTriple array to a BeztMap array
+ * NOTE: this allocates memory that will need to get freed later
+ */
+static BeztMap *bezt_to_beztmaps (BezTriple *bezts, int totvert)
+{
+       BezTriple *bezt= bezts;
+       BeztMap *bezm, *bezms;
+       int i;
        
-       ipoco_to_areaco(G.v2d, cent, mval);
-       xc= mval[0];
-       yc= mval[1];
+       /* allocate memory for this array */
+       if (totvert==0 || bezts==NULL)
+               return NULL;
+       bezm= bezms= MEM_callocN(sizeof(BeztMap)*totvert, "BeztMaps");
        
-       getmouseco_areawin(mval);
-       xo= xn= mval[0];
-       yo= yn= mval[1];
-       dvec[0]= dvec[1]= 0.0;
+       /* assign beztriples to beztmaps */
+       for (i=0; i < totvert; i++, bezm++, bezt++) {
+               bezm->bezt= bezt;
+               bezm->oldIndex= i;
+               bezm->newIndex= i;
+       }
        
-       sizefac= (float)(sqrt( (float)((yc-yn)*(yc-yn)+(xn-xc)*(xn-xc)) ));
-       if(sizefac<2.0) sizefac= 2.0;
+       return bezms;
+}
 
-       while(afbreek==0) {
-               getmouseco_areawin(mval);
-               if(mval[0]!=xo || mval[1]!=yo || firsttime) {
-                       
-                       if(mode=='g') {
-                       
-                               dx= (float)(mval[0]- xo);
-                               dy= (float)(mval[1]- yo);
-       
-                               div= (float)(G.v2d->mask.xmax-G.v2d->mask.xmin);
-                               dvec[0]+= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/div;
+/* This function copies the code of sort_time_ipocurve, but acts on BeztMap structs instead */
+static void sort_time_beztmaps (BeztMap *bezms, int totvert)
+{
+       BeztMap *bezm;
+       int i, ok= 1;
        
-                               div= (float)(G.v2d->mask.ymax-G.v2d->mask.ymin);
-                               dvec[1]+= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div;
-                               
-                               if(clampAxis) dvec[clampAxis-1]= 0.0;
-                               
-                               /* vec is reused below: remake_ipo_transverts */
-                               vec[0]= dvec[0];
-                               vec[1]= dvec[1];
-                               
-                               apply_keyb_grid(vec, 0.0, (float)1.0, (float)0.1, U.flag & USER_AUTOGRABGRID);
-                               apply_keyb_grid(vec+1, 0.0, (float)1.0, (float)0.1, 0);
-                               
-                               tv= transmain;
-                               for(a=0; a<tot; a++, tv++) {
-                                       /* adjust times for scaled ipos */
-                                       if (NLA_IPO_SCALED) {
-                                               tv->loc[0] = get_action_frame_inv(OBACT, tv->oldloc[0]);
-                                               tv->loc[0]+= vec[0];
-                                               tv->loc[0] = get_action_frame(OBACT, tv->loc[0]);
-                                       }
-                                       else {
-                                               tv->loc[0]= tv->oldloc[0]+vec[0];
-                                       }
-
-                                       if(tv->flag==0) tv->loc[1]= tv->oldloc[1]+vec[1];
-                               }
-                               
-                               if (clampAxis == CLAMP_Y)
-                                       sprintf(str, "X: %.3f  ", vec[0]);
-                               else if (clampAxis == CLAMP_X)
-                                       sprintf(str, "Y: %.3f  ", vec[1]);
-                               else
-                                       sprintf(str, "X: %.3f   Y: %.3f  ", vec[0], vec[1]);
-                               
-                               headerprint(str);
-                       }
-                       else if(mode=='s') {
-                               
-                               size[0]=size[1]=(float)( (sqrt( (float)((yc-mval[1])*(yc-mval[1])+(mval[0]-xc)*(mval[0]-xc)) ))/sizefac);
-                               
-                               if(clampAxis) size[clampAxis-1]= 1.0;
-                               
-                               apply_keyb_grid(size, 0.0, (float)0.2, (float)0.1, U.flag & USER_AUTOSIZEGRID);
-                               apply_keyb_grid(size+1, 0.0, (float)0.2, (float)0.1, U.flag & USER_AUTOSIZEGRID);
-
-                               tv= transmain;
-
-                               for(a=0; a<tot; a++, tv++) {
-                                       /* adjust times for scaled ipo's */
-                                       if (NLA_IPO_SCALED) {
-                                               tv->loc[0] = get_action_frame_inv(OBACT, tv->oldloc[0]) - get_action_frame_inv(OBACT, cent[0]);
-                                               tv->loc[0]*= size[0];
-                                               tv->loc[0]+= get_action_frame_inv(OBACT, cent[0]);
-                                               tv->loc[0] = get_action_frame(OBACT, tv->loc[0]);
-                                       }
-                                       else {
-                                               tv->loc[0]= size[0]*(tv->oldloc[0]-cent[0])+ cent[0];
-                                       }
+       /* keep repeating the process until nothing is out of place anymore */
+       while (ok) {
+               ok= 0;
+               
+               bezm= bezms;
+               i= totvert;
+               while (i--) {
+                       /* is current bezm out of order (i.e. occurs later than next)? */
+                       if (i > 0) {
+                               if ( bezm->bezt->vec[1][0] > (bezm+1)->bezt->vec[1][0]) {
+                                       bezm->newIndex++;
+                                       (bezm+1)->newIndex--;
                                        
-                                       if(tv->flag==0) tv->loc[1]= size[1]*(tv->oldloc[1]-cent[1])+ cent[1];
-                               }
-                               
-                               if (clampAxis == CLAMP_Y)
-                                       sprintf(str, "scaleX: %.3f  ", size[0]);
-                               else if (clampAxis == CLAMP_X)
-                                       sprintf(str, "scaleY: %.3f  ", size[1]);
-                               else
-                                       sprintf(str, "scaleX: %.3f   scaleY: %.3f  ", size[0], size[1]);
-                               
-                               headerprint(str);
-                               
-                       }
-                       
-                       xo= mval[0];
-                       yo= mval[1];
-                               
-                       dosort= 0;
-                       ei= G.sipo->editipo;
-                       for(a=0; a<G.sipo->totipo; a++, ei++) {
-                               if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) {
+                                       SWAP(BeztMap, *bezm, *(bezm+1));
                                        
-                                       /* watch it: if the time is wrong: do not correct handles */
-                                       if (test_time_ipocurve(ei->icu) ) dosort++;
-                                       else testhandles_ipocurve(ei->icu);
+                                       ok= 1;
                                }
                        }
                        
-                       if(dosort) {
-                               if(mode=='g') remake_ipo_transverts(transmain, vec, tot);
-                               else remake_ipo_transverts(transmain, 0, tot);
+                       /* swap order of handles or snap handles to centre-point? */
+                       if (bezm->bezt->vec[0][0]>bezm->bezt->vec[1][0] && bezm->bezt->vec[2][0]<bezm->bezt->vec[1][0]) {
+                               bezm->handles ^= BEZM_FLIPH;
+                       }
+                       else {
+                               if (bezm->bezt->vec[0][0]>bezm->bezt->vec[1][0]) bezm->handles ^= BEZM_CLEARH1;
+                               if (bezm->bezt->vec[2][0]<bezm->bezt->vec[1][0]) bezm->handles ^= BEZM_CLEARH2;
                        }
-                       if(G.sipo->showkey) update_ipokey_val();
                        
-                       calc_ipo(G.sipo->ipo, (float)CFRA);
+                       bezm++;
+               }       
+       }
+}
 
-                       /* update realtime */
-                       if(G.sipo->lock) {
-                               if(G.sipo->blocktype==ID_MA || G.sipo->blocktype==ID_TE) {
-                                       do_ipo(G.sipo->ipo);
-                                       force_draw_plus(SPACE_BUTS, 0);
-                               }
-                               else if(G.sipo->blocktype==ID_CA) {
-                                       do_ipo(G.sipo->ipo);
-                                       force_draw_plus(SPACE_VIEW3D, 0);
-                               }
-                               else if(G.sipo->blocktype==ID_KE) {
-                                       Object *ob= OBACT;
-                                       if(ob) {
-                                               ob->shapeflag &= ~OB_SHAPE_TEMPLOCK;
-                                               DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+/* This function firstly adjusts the pointers that the transdata has to each BezTriple*/
+static void beztmap_to_data (TransInfo *t, EditIpo *ei, BeztMap *bezms, int totvert)
+{
+       BezTriple *bezts = ei->icu->bezt;
+       BeztMap *bezm;
+       TransData2D *td;
+       int i, j;
+       
+       /* for each beztmap item, find if it is used anywhere */
+       bezm= bezms;
+       for (i= 0; i < totvert; i++, bezm++) {
+               /* loop through transdata, testing if we have a hit */
+               td= t->data2d;
+               for (j= 0; j < t->total; j++, td++) {
+                       if (totipo_vertsel) {
+                               /* only selected verts */
+                               if (ei->icu->ipo==IPO_BEZ) {
+                                       if (bezm->bezt->f1 & 1) {
+                                               if (td->loc2d == bezm->bezt->vec[0])
+                                                       td->loc2d= (bezts + bezm->newIndex)->vec[0];
                                        }
-                                       force_draw_plus(SPACE_VIEW3D, 0);
-                               }
-                               else if(G.sipo->blocktype==ID_PO) {
-                                       Object *ob= OBACT;
-                                       if(ob && ob->pose) {
-                                               DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+                                       if (bezm->bezt->f3 & 1) {
+                                               if (td->loc2d == bezm->bezt->vec[2])
+                                                       td->loc2d= (bezts + bezm->newIndex)->vec[2];
                                        }
-                                       force_draw_plus(SPACE_VIEW3D, 0);
                                }
-                               else if(G.sipo->blocktype==ID_OB) {
-                                       Base *base= FIRSTBASE;
-                                       
-                                       while(base) {
-                                               if(base->object->ipo==G.sipo->ipo) {
-                                                       do_ob_ipo(base->object);
-                                                       base->object->recalc |= OB_RECALC_OB;
-                                               }
-                                               base= base->next;
-                                       }
-                                       DAG_scene_flush_update(G.scene, screen_view3d_layers());
-                                       force_draw_plus(SPACE_VIEW3D, 0);
+                               if (bezm->bezt->f2 & 1) {
+                                       if (td->loc2d == bezm->bezt->vec[1])
+                                               td->loc2d= (bezts + bezm->newIndex)->vec[1];
                                }
-                               else force_draw(0);
                        }
                        else {
-                               force_draw(0);
-                       }
-                       firsttime= 0;
-               }
-               else BIF_wait_for_statechange();
-               
-               while(qtest()) {
-                       event= extern_qread(&val);
-                       if(val) {
-                               switch(event) {
-                               case ESCKEY:
-                               case LEFTMOUSE:
-                               case RIGHTMOUSE:
-                               case SPACEKEY:
-                               case RETKEY:
-                                       afbreek= 1;
-                                       break;
-                               case MIDDLEMOUSE:
-                                       if(G.sipo->showkey==0) {
-                                               if (clampAxis == CLAMP_OFF)
-                                               {
-                                                       if( abs(mval[0]-xn) > abs(mval[1]-yn))
-                                                               clampAxis = CLAMP_Y;
-                                                       else
-                                                               clampAxis = CLAMP_X;
-                                               }
-                                               else
-                                               {
-                                                       clampAxis = CLAMP_OFF;
-                                               }
-                                               firsttime= 1;
+                               /* whole curve */
+                               if (ei->icu->ipo==IPO_BEZ) {
+                                       if (td->loc2d == bezm->bezt->vec[0]) {
+                                               td->loc2d= (bezts + bezm->newIndex)->vec[0];
                                        }
-                                       break;
-                               case XKEY:
-                                       /* clampAxis is the axis that will be Zeroed out, which is why we clamp
-                                        * on Y when pressing X
-                                        */
-                                       if (clampAxis == CLAMP_Y) 
-                                               clampAxis = CLAMP_OFF; // Clamp Off if already on Y
-                                       else 
-                                               clampAxis = CLAMP_Y; // On otherwise
-                                       firsttime= 1;
-                                       break;
-                               case YKEY:
-                                       /* clampAxis is the axis that will be Zeroed out, which is why we clamp
-                                        * on X when pressing Y
-                                        */
-                                       if (clampAxis == CLAMP_X) 
-                                               clampAxis = CLAMP_OFF; // Clamp Off if already on X
-                                       else 
-                                               clampAxis = CLAMP_X; // On otherwise
-                                       firsttime= 1;
-                                       break;
-                               case LEFTCTRLKEY:
-                               case RIGHTCTRLKEY:
-                                       firsttime= 1;
-                                       break;
-                               default:
-                                       if(mode=='g') {
-                                               if(G.qual & LR_CTRLKEY) {
-                                                       if(event==LEFTARROWKEY) {dvec[0]-= 1.0; firsttime= 1;}
-                                                       else if(event==RIGHTARROWKEY) {dvec[0]+= 1.0; firsttime= 1;}
-                                                       else if(event==UPARROWKEY) {dvec[1]+= 1.0; firsttime= 1;}
-                                                       else if(event==DOWNARROWKEY) {dvec[1]-= 1.0; firsttime= 1;}
-                                               }
-                                               else arrows_move_cursor(event);
+                                       
+                                       if (td->loc2d == bezm->bezt->vec[2]) {
+                                               td->loc2d= (bezts + bezm->newIndex)->vec[2];
                                        }
-                                       else arrows_move_cursor(event);
                                }
-                       }
-                       if(afbreek) break;
-               }
-       }
-       
-       if(event==ESCKEY || event==RIGHTMOUSE) {
-               tv= transmain;
-               for(a=0; a<tot; a++, tv++) {
-                       tv->loc[0]= tv->oldloc[0];
-                       tv->loc[1]= tv->oldloc[1];
-               }
-               
-               dosort= 0;
-               ei= G.sipo->editipo;
-               for(a=0; a<G.sipo->totipo; a++, ei++) {
-                       if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) {
-                               if( (ei->flag & IPO_EDIT) || G.sipo->showkey) {
-                                       if( test_time_ipocurve(ei->icu)) {
-                                               dosort= 1;
-                                               break;
-                                       }
+                               if (td->loc2d == bezm->bezt->vec[1]) {
+                                       td->loc2d= (bezts + bezm->newIndex)->vec[1];
                                }
                        }
                }
                
-               if(dosort) remake_ipo_transverts(transmain, 0, tot);
-               
-               ei= G.sipo->editipo;
-               for(a=0; a<G.sipo->totipo; a++, ei++) {
-                       if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) {
-                               if( (ei->flag & IPO_EDIT) || G.sipo->showkey) {
-                                       testhandles_ipocurve(ei->icu);
-                               }
+       }
+}
+
+/* This function is called by recalcData during the Transform loop to recalculate 
+ * the handles of curves and sort the keyframes so that the curves draw correctly.
+ * It is only called if some keyframes have moved out of order.
+ */
+void remake_ipo_transdata (TransInfo *t)
+{
+       EditIpo *ei;
+       int a;
+       
+       /* sort and reassign verts */
+       ei= G.sipo->editipo;
+       for (a=0; a<G.sipo->totipo; a++, ei++) {
+               if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) {
+                       if (ei->icu->bezt) {
+                               BeztMap *bezm;
+                               
+                               /* adjust transform-data pointers */
+                               bezm= bezt_to_beztmaps(ei->icu->bezt, ei->icu->totvert);
+                               sort_time_beztmaps(bezm, ei->icu->totvert);
+                               beztmap_to_data(t, ei, bezm, ei->icu->totvert);
+                               
+                               /* re-sort actual beztriples (perhaps this could be done using the beztmaps to save time?) */
+                               sort_time_ipocurve(ei->icu);
+                               
+                               /* free mapping stuff */
+                               MEM_freeN(bezm);
+                               
+                               /* make sure handles are all set correctly */
+                               testhandles_ipocurve(ei->icu);
                        }
                }
-               calc_ipo(G.sipo->ipo, (float)CFRA);
        }
-       else BIF_undo_push("Transform Ipo");
+               
+       /* remake ipokeys */
+       if (G.sipo->showkey) make_ipokey();
+}
 
+/* This function acts as the entrypoint for transforms in the IPO editor (as for
+ * the Action and NLA editors). The actual transform loop is not here anymore.
+ */
+void transform_ipo (int mode)
+{
+       short tmode;
+       
+       /* data-validation */
+       if (G.sipo->ipo && G.sipo->ipo->id.lib) return;
+       if (G.sipo->editipo==0) return;
+       
+       /* convert ascii-based mode to transform system constants (mode) */
+       switch (mode) {
+               case 'g':       
+                       tmode= TFM_TRANSLATION;
+                       break;
+               case 'r':
+                       tmode= TFM_ROTATION;
+                       break;
+               case 's':
+                       tmode= TFM_RESIZE;
+                       break;
+               default:
+                       tmode= 0;
+                       return;
+       }
+       
+       /* the transform system method involved depends on the selection */
+       get_status_editipo();
+       if (totipo_vertsel) {
+               /* we're probably in editmode, so only selected verts - transform system */
+               initTransform(tmode, CTX_NONE);
+               Transform();
+       }
+       else if (totipo_edit==0 && totipo_sel!=0) {
+               /* we're not in editmode, so entire curves get moved - transform system*/
+               initTransform(tmode, CTX_NONE);
+               Transform();
+       }
+       else {
+               /* shapekey mode? special transform code */
+               if (totipo_edit==0) 
+                       move_keys(OBACT);
+               return;
+       }
+       
+       /* cleanup */
        editipo_changed(G.sipo, 1);
-
-       MEM_freeN(transmain);
 }
 
+/**************************************************/
+
 void filter_sampledata(float *data, int sfra, int efra)
 {
        float *da;
index 2f3127ba29b65a9a72e4d8228745602c88d2ace4..e8514cee2df9abcbc70dadb7f67101abb777e184 100644 (file)
@@ -1096,6 +1096,7 @@ void load_editMesh(void)
        a = 0;
        efa= em->faces.first;
        i = 0;
+       me->act_face = -1;
        while(efa) {
                mface= &((MFace *) me->mface)[i];
                
@@ -1151,8 +1152,8 @@ void load_editMesh(void)
                /* no index '0' at location 3 or 4 */
                test_index_face(mface, &me->fdata, i, efa->v4?4:3);
                
-               if (a==me->act_face)
-                       EM_set_actFace(efa);
+               if (EM_get_actFace() == efa)
+                       me->act_face = a;
 
 #ifdef WITH_VERSE
                if(efa->vface) {
index 2a86c674f662c5f6a79b0d6d82e246e2b6e9f093..5cfeab03c0aa080ae594c0325207c88cb6d9d8e9 100644 (file)
@@ -3894,7 +3894,7 @@ void vertexsmooth(void)
        eve= em->verts.first;
        while(eve) {
                if(eve->f & SELECT) {
-                       eve->tmp.fp = adr;
+                       eve->tmp.p = (void*)adr;
                        eve->f1= 0;
                        eve->f2= 0;
                        adr+= 3;
@@ -3942,11 +3942,11 @@ void vertexsmooth(void)
                        
                        if((eed->v1->f & SELECT) && eed->v1->f1<255) {
                                eed->v1->f1++;
-                               VecAddf(eed->v1->tmp.fp, eed->v1->tmp.fp, fvec);
+                               VecAddf(eed->v1->tmp.p, eed->v1->tmp.p, fvec);
                        }
                        if((eed->v2->f & SELECT) && eed->v2->f1<255) {
                                eed->v2->f1++;
-                               VecAddf(eed->v2->tmp.fp, eed->v2->tmp.fp, fvec);
+                               VecAddf(eed->v2->tmp.p, eed->v2->tmp.p, fvec);
                        }
                }
                eed= eed->next;
@@ -3956,7 +3956,7 @@ void vertexsmooth(void)
        while(eve) {
                if(eve->f & SELECT) {
                        if(eve->f1) {
-                               adr = eve->tmp.fp;
+                               adr = eve->tmp.p;
                                fac= 0.5/(float)eve->f1;
                                
                                eve->co[0]= 0.5*eve->co[0]+fac*adr[0];
@@ -3976,7 +3976,7 @@ void vertexsmooth(void)
                                        }
                                }
                        }
-                       eve->tmp.fp= 0;
+                       eve->tmp.p= NULL;
                }
                eve= eve->next;
        }
index f4c6c475f1a6af71f183d42af8a6858d240f3642..2afac79be1d6688ff244cff2467b8539701f7b28 100644 (file)
@@ -5111,9 +5111,10 @@ void mesh_set_face_flags(short mode)
        short m_tex=0, m_tiles=0, m_shared=0, m_light=0, m_invis=0, m_collision=0, m_twoside=0, m_obcolor=0; 
        short flag = 0, change = 0;
        
-       if(G.obedit==0) return;
-       
-       if(G.obedit->type != OB_MESH) return;
+       if (!EM_texFaceCheck()) {
+               error("not a mesh with uv/image layers");
+               return;
+       }
        
        add_numbut(0, TOG|SHO, "Texture", 0, 0, &m_tex, NULL);
        add_numbut(1, TOG|SHO, "Tiles", 0, 0, &m_tiles, NULL);
@@ -6558,7 +6559,7 @@ void mesh_rotate_uvs(void)
 {
        EditMesh *em = G.editMesh;
        EditFace *efa;
-       short change = 0;
+       short change = 0, ccw;
        MTFace *tf;
        float u1, v1;
        
@@ -6567,28 +6568,49 @@ void mesh_rotate_uvs(void)
                return;
        }
        
+       ccw = (G.qual == LR_SHIFTKEY);
+       
        for(efa=em->faces.first; efa; efa=efa->next) {
                if (efa->f & SELECT) {
                        tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
                        u1= tf->uv[0][0];
                        v1= tf->uv[0][1];
                        
-                       tf->uv[0][0]= tf->uv[1][0];
-                       tf->uv[0][1]= tf->uv[1][1];
-
-                       tf->uv[1][0]= tf->uv[2][0];
-                       tf->uv[1][1]= tf->uv[2][1];
-                       
-                       if(efa->v4) {
-                               tf->uv[2][0]= tf->uv[3][0];
-                               tf->uv[2][1]= tf->uv[3][1];
-                       
-                               tf->uv[3][0]= u1;
-                               tf->uv[3][1]= v1;
-                       }
-                       else {
-                               tf->uv[2][0]= u1;
-                               tf->uv[2][1]= v1;
+                       if (ccw) {
+                               if(efa->v4) {
+                                       tf->uv[0][0]= tf->uv[3][0];
+                                       tf->uv[0][1]= tf->uv[3][1];
+                                       
+                                       tf->uv[3][0]= tf->uv[2][0];
+                                       tf->uv[3][1]= tf->uv[2][1];
+                               } else {
+                                       tf->uv[0][0]= tf->uv[2][0];
+                                       tf->uv[0][1]= tf->uv[2][1];
+                               }
+                               
+                               tf->uv[2][0]= tf->uv[1][0];
+                               tf->uv[2][1]= tf->uv[1][1];
+                               
+                               tf->uv[1][0]= u1;
+                               tf->uv[1][1]= v1;
+                       } else {        
+                               tf->uv[0][0]= tf->uv[1][0];
+                               tf->uv[0][1]= tf->uv[1][1];
+       
+                               tf->uv[1][0]= tf->uv[2][0];
+                               tf->uv[1][1]= tf->uv[2][1];
+                               
+                               if(efa->v4) {
+                                       tf->uv[2][0]= tf->uv[3][0];
+                                       tf->uv[2][1]= tf->uv[3][1];
+                               
+                                       tf->uv[3][0]= u1;
+                                       tf->uv[3][1]= v1;
+                               }
+                               else {
+                                       tf->uv[2][0]= u1;
+                                       tf->uv[2][1]= v1;
+                               }
                        }
                        change = 1;
                }
@@ -6656,27 +6678,40 @@ void mesh_rotate_colors(void)
 {
        EditMesh *em = G.editMesh;
        EditFace *efa;
-       short change = 0;
+       short change = 0, ccw;
        MCol tmpcol, *mcol;
        if (!EM_vertColorCheck()) {
                error("mesh has no color layers");
                return;
        }
        
+       ccw = (G.qual == LR_SHIFTKEY);
+       
        for(efa=em->faces.first; efa; efa=efa->next) {
                if (efa->f & SELECT) {
                        mcol = CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
                        tmpcol= mcol[0];
                        
-                       mcol[0]= mcol[1];
-                       mcol[1]= mcol[2];
-
-                       if(efa->v4) {
-                               mcol[2]= mcol[3];
-                               mcol[3]= tmpcol;
+                       if (ccw) {
+                               if(efa->v4) {
+                                       mcol[0]= mcol[3];
+                                       mcol[3]= mcol[2];
+                               } else {
+                                       mcol[0]= mcol[2];
+                               }
+                               mcol[2]= mcol[1];
+                               mcol[1]= tmpcol;
+                       } else {
+                               mcol[0]= mcol[1];
+                               mcol[1]= mcol[2];
+       
+                               if(efa->v4) {
+                                       mcol[2]= mcol[3];
+                                       mcol[3]= tmpcol;
+                               }
+                               else
+                                       mcol[2]= tmpcol;
                        }
-                       else
-                               mcol[2]= tmpcol;
                        change = 1;
                }
        }
index 9ae46998cbc6f3e8cd5ed3e9034f68b8e6a2ccff..ff70ff74d70a85634436a110f89e0b96103fbc7b 100644 (file)
@@ -1119,7 +1119,9 @@ static void animated_screen(bScreen *sc, short val)
        }
        if(val & TIME_ALL_ANIM_WIN) allqueue(REDRAWANIM, 0);
        if(val & TIME_ALL_BUTS_WIN) allqueue(REDRAWBUTSALL, 0);
-       if(val & TIME_SEQ) allqueue(REDRAWSEQ, 0);
+       if(val & TIME_SEQ) {
+               allqueue(REDRAWSEQ, 0);
+       }
        
        allqueue(REDRAWTIME, 0);
 }
index 1b1c4c251d2304d4cc8e7a9dff01ecd30c31672b..3da7a72f249751f7216b3e24069dcf2a02038fe8 100644 (file)
@@ -308,16 +308,100 @@ void weld_align_tface_uv(char tool)
        object_uvs_changed(OBACT);
 }
 
+// just for averaging UV's
+typedef struct UVVertAverage {
+       float uv[2];
+       int count;
+} UVVertAverage;
+
+void stitch_vert_uv_tface(void)
+{
+       EditMesh *em = G.editMesh;
+       EditFace *efa;
+       EditVert *eve;
+       MTFace *tface;
+       int count;
+       UVVertAverage *uv_average, *uvav;
+       
+       if( is_uv_tface_editing_allowed()==0 ) return;
+       
+       // index and count verts
+       for (count=0, eve=em->verts.first; eve; count++, eve= eve->next) {
+               eve->tmp.l = count;
+       }
+       
+       uv_average = MEM_callocN(sizeof(UVVertAverage) * count, "Stitch");
+       
+       // gather uv averages per vert
+       for (efa= em->faces.first; efa; efa= efa->next) {
+               tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+               if (SIMA_FACEDRAW_CHECK(efa, tface)) {
+                       if (SIMA_UVSEL_CHECK(efa, tface, 0)) {
+                               uvav = uv_average + efa->v1->tmp.l;
+                               uvav->count++;
+                               uvav->uv[0] += tface->uv[0][0];
+                               uvav->uv[1] += tface->uv[0][1];
+                       }
+                       if (SIMA_UVSEL_CHECK(efa, tface, 1)) {
+                               uvav = uv_average + efa->v2->tmp.l;
+                               uvav->count++;
+                               uvav->uv[0] += tface->uv[1][0];
+                               uvav->uv[1] += tface->uv[1][1];
+                       }
+                       if (SIMA_UVSEL_CHECK(efa, tface, 2)) {
+                               uvav = uv_average + efa->v3->tmp.l;
+                               uvav->count++;
+                               uvav->uv[0] += tface->uv[2][0];
+                               uvav->uv[1] += tface->uv[2][1];
+                       }
+                       if (efa->v4 && SIMA_UVSEL_CHECK(efa, tface, 3)) {
+                               uvav = uv_average + efa->v4->tmp.l;
+                               uvav->count++;
+                               uvav->uv[0] += tface->uv[3][0];
+                               uvav->uv[1] += tface->uv[3][1];
+                       }
+               }
+       }
+       
+       // apply uv welding
+       for (efa= em->faces.first; efa; efa= efa->next) {
+               tface = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
+               if (SIMA_FACEDRAW_CHECK(efa, tface)) {
+                       if (SIMA_UVSEL_CHECK(efa, tface, 0)) {
+                               uvav = uv_average + efa->v1->tmp.l;
+                               tface->uv[0][0] = uvav->uv[0]/uvav->count;
+                               tface->uv[0][1] = uvav->uv[1]/uvav->count;
+                       }
+                       if (SIMA_UVSEL_CHECK(efa, tface, 1)) {
+                               uvav = uv_average + efa->v2->tmp.l;
+                               tface->uv[1][0] = uvav->uv[0]/uvav->count;
+                               tface->uv[1][1] = uvav->uv[1]/uvav->count;
+                       }
+                       if (SIMA_UVSEL_CHECK(efa, tface, 2)) {
+                               uvav = uv_average + efa->v3->tmp.l;
+                               tface->uv[2][0] = uvav->uv[0]/uvav->count;
+                               tface->uv[2][1] = uvav->uv[1]/uvav->count;
+                       }
+                       if (efa->v4 && SIMA_UVSEL_CHECK(efa, tface, 3)) {
+                               uvav = uv_average + efa->v4->tmp.l;
+                               tface->uv[3][0] = uvav->uv[0]/uvav->count;
+                               tface->uv[3][1] = uvav->uv[1]/uvav->count;
+                       }
+               }
+       }
+       MEM_freeN(uv_average);
+       object_uvs_changed(OBACT);
+}
+
 void weld_align_menu_tface_uv(void)
 {
        short mode= 0;
 
        if( is_uv_tface_editing_allowed()==0 ) return;
 
-       mode= pupmenu("Weld/Align%t|Weld%x1|Align X%x2|Align Y%x3|");
+       mode= pupmenu("Weld/Align%t|Weld%x1|Align X%x2|Align Y%x3");
 
        if(mode==-1) return;
-
        if(mode==1) weld_align_tface_uv('w');
        else if(mode==2) weld_align_tface_uv('x');
        else if(mode==3) weld_align_tface_uv('y');
@@ -1027,7 +1111,7 @@ void snap_menu_sima(void)
        short event;
        if( is_uv_tface_editing_allowed()==0 || !G.v2d) return; /* !G.v2d should never happen */
        
-       event = pupmenu("Snap %t|Selection -> Pixels%x1|Selection -> Cursor%x2|Selection -> Adjacent Unselected%x3|Cursor-> Pixel%x3|Cursor-> Selection%x4");
+       event = pupmenu("Snap %t|Selection -> Pixels%x1|Selection -> Cursor%x2|Selection -> Adjacent Unselected%x3|Cursor -> Pixel%x4|Cursor -> Selection%x5");
        switch (event) {
                case 1:
                    if (snap_uv_sel_to_pixels()) {
@@ -1201,12 +1285,12 @@ void mouseco_to_cursor_sima(void)
        scrarea_queue_winredraw(curarea);
 }
 
-void stitch_uv_tface(int mode)
+void stitch_limit_uv_tface(void)
 {
        MTFace *tf;
        int a, vtot;
        float newuv[2], limit[2];
-       UvMapVert *vlist, *iterv, *v;
+       UvMapVert *vlist, *iterv;
        EditMesh *em = G.editMesh;
        EditVert *ev;
        EditFace *efa;
@@ -1222,11 +1306,9 @@ void stitch_uv_tface(int mode)
        }
        
        limit[0]= limit[1]= 20.0;
-       if(mode==1) {
-               add_numbut(0, NUM|FLO, "Limit:", 0.1, 1000.0, &limit[0], NULL);
-               if (!do_clever_numbuts("Stitch UVs", 1, REDRAW))
-                       return;
-       }
+       add_numbut(0, NUM|FLO, "Limit:", 0.1, 1000.0, &limit[0], NULL);
+       if (!do_clever_numbuts("Stitch UVs", 1, REDRAW))
+               return;
 
        limit[0]= limit[1]= limit[0]/256.0;
        if(G.sima->image) {
@@ -1244,20 +1326,20 @@ void stitch_uv_tface(int mode)
        if(vmap == NULL)
                return;
 
-       if(mode==0) {
-               for(a=0, ev= em->verts.first; ev; a++, ev= ev->next) {
-                       v = get_uv_map_vert_EM(vmap, a);
-
-                       if(v == NULL)
-                               continue;
+       for(a=0, ev= em->verts.first; ev; a++, ev= ev->next) {
+               vlist= get_uv_map_vert_EM(vmap, a);
 
+               while(vlist) {
                        newuv[0]= 0; newuv[1]= 0;
                        vtot= 0;
 
-                       for(iterv=v; iterv; iterv=iterv->next) {
+                       for(iterv=vlist; iterv; iterv=iterv->next) {
+                               if((iterv != vlist) && iterv->separate)
+                                       break;
                                efa = EM_get_face_for_index(iterv->f);
                                tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                               if (tf->flag & TF_SEL_MASK(iterv->tfindex)) {
+                               
+                               if (tf[iterv->f].flag & TF_SEL_MASK(iterv->tfindex)) {
                                        newuv[0] += tf->uv[iterv->tfindex][0];
                                        newuv[1] += tf->uv[iterv->tfindex][1];
                                        vtot++;
@@ -1267,53 +1349,18 @@ void stitch_uv_tface(int mode)
                        if (vtot > 1) {
                                newuv[0] /= vtot; newuv[1] /= vtot;
 
-                               for(iterv=v; iterv; iterv=iterv->next) {
-                                       efa = EM_get_face_for_index(iterv->f);
-                                       tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                                       if (tf->flag & TF_SEL_MASK(iterv->tfindex)) {
-                                               tf->uv[iterv->tfindex][0]= newuv[0];
-                                               tf->uv[iterv->tfindex][1]= newuv[1];
-                                       }
-                               }
-                       }
-               }
-       } else if(mode==1) {
-               for(a=0, ev= em->verts.first; ev; a++, ev= ev->next) {
-                       vlist= get_uv_map_vert_EM(vmap, a);
-
-                       while(vlist) {
-                               newuv[0]= 0; newuv[1]= 0;
-                               vtot= 0;
-
                                for(iterv=vlist; iterv; iterv=iterv->next) {
                                        if((iterv != vlist) && iterv->separate)
                                                break;
                                        efa = EM_get_face_for_index(iterv->f);
                                        tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                                       
-                                       if (tf[iterv->f].flag & TF_SEL_MASK(iterv->tfindex)) {
-                                               newuv[0] += tf->uv[iterv->tfindex][0];
-                                               newuv[1] += tf->uv[iterv->tfindex][1];
-                                               vtot++;
-                                       }
-                               }
-
-                               if (vtot > 1) {
-                                       newuv[0] /= vtot; newuv[1] /= vtot;
-
-                                       for(iterv=vlist; iterv; iterv=iterv->next) {
-                                               if((iterv != vlist) && iterv->separate)
-                                                       break;
-                                               efa = EM_get_face_for_index(iterv->f);
-                                               tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                                               if (tf->flag & TF_SEL_MASK(iterv->tfindex)) {
-                                                       tf->uv[iterv->tfindex][0]= newuv[0];
-                                                       tf->uv[iterv->tfindex][1]= newuv[1];
-                                               }
+                                       if (tf->flag & TF_SEL_MASK(iterv->tfindex)) {
+                                               tf->uv[iterv->tfindex][0]= newuv[0];
+                                               tf->uv[iterv->tfindex][1]= newuv[1];
                                        }
                                }
-                               vlist= iterv;
                        }
+                       vlist= iterv;
                }
        }
 
index c9cde5436e8c9128cffa8c6c957753d59786a3bd..86a53ba2b3d311944706753a49c55cf386a2336a 100644 (file)
@@ -970,10 +970,10 @@ static void do_image_uvsmenu(void *arg, int event)
                else G.sima->flag |= SI_CLIP_UV;
                break;
        case 3: /* Limit Stitch UVs */
-               stitch_uv_tface(1);
+               stitch_limit_uv_tface();
                break;
        case 4: /* Stitch UVs */
-               stitch_uv_tface(0);
+               stitch_vert_uv_tface();
                break;
        case 5: /* Proportional Edit (toggle) */
                if(G.scene->proportional)
index 44812b074b3367f8fb1455cbad2521917abf5e5a..16420f1536bf326c4fa1756881b53167d728e5e4 100644 (file)
@@ -262,7 +262,10 @@ static void do_ipo_editmenu_transformmenu(void *arg, int event)
        case 0: /* grab/move */
                transform_ipo('g');
                break;
-       case 1: /* scale */
+       case 1: /* rotate */
+               transform_ipo('r');
+               break;
+       case 2: /* scale */
                transform_ipo('s');
                break;
        }
@@ -277,7 +280,8 @@ static uiBlock *ipo_editmenu_transformmenu(void *arg_unused)
        uiBlockSetButmFunc(block, do_ipo_editmenu_transformmenu, NULL);
 
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Move|G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Scale|S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Rotate|R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Scale|S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
 
        uiBlockSetDirection(block, UI_RIGHT);
        uiTextBoundsBlock(block, 60);
@@ -639,7 +643,7 @@ static uiBlock *ipo_editmenu(void *arg_unused)
        uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
 
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Duplicate|Shift D", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 1, "");
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Record Mouse Movement|R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Record Mouse Movement|Ctrl R", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 2, "");
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Clean IPO Curves|O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 8, "");
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Smooth IPO Curves|Shift O", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 9, "");
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Delete|X", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
index ffa810f6eb87d94e593abd07b744e2949f2675b7..da2581e36dfd82e4bf66aea50e7ee8e45c2f315e 100644 (file)
@@ -115,10 +115,22 @@ static uiBlock *seq_viewmenu(void *arg_unused)
        block= uiNewBlock(&curarea->uiblocks, "seq_viewmenu", UI_EMBOSSP, UI_HELV, curarea->headwin);
        uiBlockSetButmFunc(block, do_seq_viewmenu, NULL);
 
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Back Animation|Alt A", 0, yco-=20,
-                                        menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Play Back Animation in 3D View|Alt Shift A", 0, yco-=20,
-                                        menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
+       if (sseq->mainb == 0) {
+               uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
+                                "Play Back Animation "
+                                "in all Sequence Areas|Alt A", 0, yco-=20,
+                                menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+       } else {
+               uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
+                                "Play Back Animation "
+                                "in this window|Alt A", 0, yco-=20,
+                                menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
+       }
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, 
+                        "Play Back Animation in all "
+                        "3D Views and Sequence Areas|Alt Shift A", 
+                        0, yco-=20,
+                        menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
 
        uiDefBut(block, SEPR, 0, "",        0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
 
index 3f27fe1a5adf638c8aec2dfe73b6a4aeb499f9cf..add58a2a2ef01e8039076242d5d91cc3d317aced 100644 (file)
@@ -2768,7 +2768,7 @@ static uiBlock *view3d_edit_mesh_facesmenu(void *arg_unused)
        
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Convert Quads to Triangles|Ctrl T",      0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
        uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Convert Triangles to Quads|Alt J", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
-       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Flip Triangle Edges|Ctrl F",             0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
+       uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Flip Triangle Edges|Ctrl Shift F",               0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
        
        uiDefBut(block, SEPR, 0, "",                    0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
        
@@ -4715,6 +4715,7 @@ void do_view3d_buttons(short event)
                countall();
                BIF_undo_push("Selectmode Set: Vertex");
                allqueue(REDRAWVIEW3D, 1);
+               allqueue(REDRAWIMAGE, 0); /* only needed in cases where mesh and UV selection are in sync */
                break;
        case B_SEL_EDGE:
                if( (G.qual & LR_SHIFTKEY)==0 || G.scene->selectmode==0){
@@ -4727,6 +4728,7 @@ void do_view3d_buttons(short event)
                countall();
                BIF_undo_push("Selectmode Set: Edge");
                allqueue(REDRAWVIEW3D, 1);
+               allqueue(REDRAWIMAGE, 0); /* only needed in cases where mesh and UV selection are in sync */
                break;
        case B_SEL_FACE:
                if( (G.qual & LR_SHIFTKEY)==0 || G.scene->selectmode==0){
@@ -4739,6 +4741,7 @@ void do_view3d_buttons(short event)
                countall();
                BIF_undo_push("Selectmode Set: Face");
                allqueue(REDRAWVIEW3D, 1);
+               allqueue(REDRAWIMAGE, 0); /* only needed in cases where mesh and UV selection are in sync */
                break;  
        
        case B_MAN_TRANS:
index 5b7fb4e62483cf3b04d0efdb3cc6239c0e40643a..4f1d50561116cba2e04227819cf70dcae2e773b8 100644 (file)
@@ -2272,7 +2272,7 @@ static void ui_draw_but_CURVE(uiBut *but)
        }
        glEnd();
        glDisable(GL_LINE_SMOOTH);
-       glEnable(GL_BLEND);
+       glDisable(GL_BLEND);
 
        /* the points, use aspect to make them visible on edges */
        cmp= cuma->curve;
index 4bac7fdb25085fa26de20fb263ceafdab7f82160..f050906efa50c6626a234ae5237caf27e3bcb0f5 100644 (file)
@@ -95,6 +95,7 @@ static int audio_pos;
 static int audio_scrub=0;
 static int audio_playing=0;
 static int audio_initialised=0;
+static int audio_startframe=0;
 /////
 //
 /* local protos ------------------- */
@@ -506,8 +507,9 @@ void audiostream_play(Uint32 startframe, Uint32 duration, int mixdown)
                }
        }
 
-       audio_pos = ( ((int)( (((float)startframe)
-                              /(float)G.scene->r.frs_sec)
+       audio_startframe = startframe;
+       audio_pos = ( ((int)( (( (double)startframe)
+                              /(double)G.scene->r.frs_sec)
                              *(G.scene->audio.mixrate)*4 )) & (~3) );
        
        audio_scrub = duration;
@@ -537,8 +539,11 @@ int audiostream_pos(void)
 {
        int pos;
        
-       pos = (int) ( ((float)(audio_pos-U.mixbufsize)/( G.scene->audio.mixrate*4 ))*(float)G.scene->r.frs_sec );
-       if (pos<1) pos=1;
+       pos = (int) (((double)(audio_pos-U.mixbufsize)
+                     / ( G.scene->audio.mixrate*4 ))
+                    * (double)G.scene->r.frs_sec );
+
+       if (pos < audio_startframe) pos = audio_startframe;
        return ( pos );
 }
 
index aad0ebf5c5ff5ad2a6cdf521ca3dec611ee25c7d..333f3d24e6ecfa68792e64d0b901538bbc57636a 100644 (file)
@@ -70,6 +70,7 @@
 #include "RE_pipeline.h"               // talks to entire render API
 
 #include "blendef.h"
+#include <pthread.h>
 
 int seqrectx, seqrecty;
 
@@ -1179,6 +1180,325 @@ ImBuf *give_ibuf_seq(int rectx, int recty, int cfra, int chanshown)
 
 }
 
+/* threading api */
+
+static ListBase running_threads;
+static ListBase prefetch_wait;
+static ListBase prefetch_done;
+
+static pthread_mutex_t queue_lock          = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t wakeup_lock         = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t  wakeup_cond         = PTHREAD_COND_INITIALIZER;
+
+static pthread_mutex_t prefetch_ready_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t  prefetch_ready_cond = PTHREAD_COND_INITIALIZER;
+
+static pthread_mutex_t frame_done_lock     = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t  frame_done_cond     = PTHREAD_COND_INITIALIZER;
+
+static volatile int seq_thread_shutdown = FALSE;
+static volatile int seq_last_given_monoton_cfra = 0;
+static int monoton_cfra = 0;
+
+typedef struct PrefetchThread {
+       struct PrefetchThread *next, *prev;
+       struct PrefetchQueueElem *current;
+       pthread_t pthread;
+       int running;
+} PrefetchThread;
+
+typedef struct PrefetchQueueElem {
+       struct PrefetchQueueElem *next, *prev;
+       
+       int rectx;
+       int recty;
+       int cfra;
+       int chanshown;
+
+       int monoton_cfra;
+
+       struct ImBuf * ibuf;
+} PrefetchQueueElem;
+
+
+static void * seq_prefetch_thread(void * This_)
+{
+       PrefetchThread * This = This_;
+
+       while (!seq_thread_shutdown) {
+               PrefetchQueueElem * e;
+               int s_last;
+
+               pthread_mutex_lock(&queue_lock);
+               e = prefetch_wait.first;
+               if (e) {
+                       BLI_remlink(&prefetch_wait, e);
+               }
+               s_last = seq_last_given_monoton_cfra;
+
+               This->current = e;
+
+               pthread_mutex_unlock(&queue_lock);
+
+               if (!e) {
+                       pthread_mutex_lock(&prefetch_ready_lock);
+
+                       This->running = FALSE;
+
+                       pthread_cond_signal(&prefetch_ready_cond);
+                       pthread_mutex_unlock(&prefetch_ready_lock);
+
+                       pthread_mutex_lock(&wakeup_lock);
+                       if (!seq_thread_shutdown) {
+                               pthread_cond_wait(&wakeup_cond, &wakeup_lock);
+                       }
+                       pthread_mutex_unlock(&wakeup_lock);
+                       continue;
+               }
+
+               This->running = TRUE;
+               
+               if (e->cfra >= s_last) { 
+                       e->ibuf = give_ibuf_seq(e->rectx, e->recty, e->cfra, 
+                                               e->chanshown);
+               }
+
+               if (e->ibuf) {
+                       IMB_cache_limiter_ref(e->ibuf);
+               }
+
+               pthread_mutex_lock(&queue_lock);
+
+               BLI_addtail(&prefetch_done, e);
+
+               for (e = prefetch_wait.first; e; e = e->next) {
+                       if (s_last > e->monoton_cfra) {
+                               BLI_remlink(&prefetch_wait, e);
+                               MEM_freeN(e);
+                       }
+               }
+
+               for (e = prefetch_done.first; e; e = e->next) {
+                       if (s_last > e->monoton_cfra) {
+                               if (e->ibuf) {
+                                       IMB_cache_limiter_unref(e->ibuf);
+                               }
+                               BLI_remlink(&prefetch_done, e);
+                               MEM_freeN(e);
+                       }
+               }
+
+               pthread_mutex_unlock(&queue_lock);
+
+               pthread_mutex_lock(&frame_done_lock);
+               pthread_cond_signal(&frame_done_cond);
+               pthread_mutex_unlock(&frame_done_lock);
+       }
+       return 0;
+}
+
+void seq_start_threads()
+{
+       int i;
+
+       running_threads.first = running_threads.last = NULL;
+       prefetch_wait.first = prefetch_wait.last = NULL;
+       prefetch_done.first = prefetch_done.last = NULL;
+
+       seq_thread_shutdown = FALSE;
+       seq_last_given_monoton_cfra = monoton_cfra = 0;
+
+       /* since global structures are modified during the processing
+          of one frame, only one render thread is currently possible... 
+
+          (but we code, in the hope, that we can remove this restriction
+          soon...)
+       */
+
+       fprintf(stderr, "SEQ-THREAD: seq_start_threads\n");
+
+       for (i = 0; i < 1; i++) {
+               PrefetchThread *t = MEM_callocN(sizeof(PrefetchThread), 
+                                               "prefetch_thread");
+               t->running = TRUE;
+               BLI_addtail(&running_threads, t);
+
+               pthread_create(&t->pthread, NULL, seq_prefetch_thread, t);
+       }
+}
+
+void seq_stop_threads()
+{
+       PrefetchThread *tslot;
+       PrefetchQueueElem * e;
+
+       fprintf(stderr, "SEQ-THREAD: seq_stop_threads()\n");
+
+       if (seq_thread_shutdown) {
+               fprintf(stderr, "SEQ-THREAD: ... already stopped\n");
+               return;
+       }
+       
+       pthread_mutex_lock(&wakeup_lock);
+
+       seq_thread_shutdown = TRUE;
+
+        pthread_cond_broadcast(&wakeup_cond);
+        pthread_mutex_unlock(&wakeup_lock);
+
+       for(tslot = running_threads.first; tslot; tslot= tslot->next) {
+               pthread_join(tslot->pthread, NULL);
+       }
+
+
+       for (e = prefetch_wait.first; e; e = e->next) {
+               BLI_remlink(&prefetch_wait, e);
+               MEM_freeN(e);
+       }
+
+       for (e = prefetch_done.first; e; e = e->next) {
+               if (e->ibuf) {
+                       IMB_cache_limiter_unref(e->ibuf);
+               }
+               BLI_remlink(&prefetch_done, e);
+               MEM_freeN(e);
+       }
+
+       BLI_freelistN(&running_threads);
+}
+
+void give_ibuf_prefetch_request(int rectx, int recty, int cfra, int chanshown)
+{
+       PrefetchQueueElem * e;
+       if (seq_thread_shutdown) {
+               return;
+       }
+
+       e = MEM_callocN(sizeof(PrefetchQueueElem), "prefetch_queue_elem");
+       e->rectx = rectx;
+       e->recty = recty;
+       e->cfra = cfra;
+       e->chanshown = chanshown;
+       e->monoton_cfra = monoton_cfra++;
+
+       pthread_mutex_lock(&queue_lock);
+       BLI_addtail(&prefetch_wait, e);
+       pthread_mutex_unlock(&queue_lock);
+       
+       pthread_mutex_lock(&wakeup_lock);
+       pthread_cond_signal(&wakeup_cond);
+       pthread_mutex_unlock(&wakeup_lock);
+}
+
+void seq_wait_for_prefetch_ready()
+{
+       if (seq_thread_shutdown) {
+               return;
+       }
+
+       fprintf(stderr, "SEQ-THREAD: rendering prefetch frames...\n");
+
+       PrefetchThread *tslot;
+
+       pthread_mutex_lock(&prefetch_ready_lock);
+
+       for(;;) {
+               for(tslot = running_threads.first; tslot; tslot= tslot->next) {
+                       if (tslot->running) {
+                               break;
+                       }
+               }
+               if (!tslot) {
+                       break;
+               }
+               pthread_cond_wait(&prefetch_ready_cond, &prefetch_ready_lock);
+       }
+
+       pthread_mutex_unlock(&prefetch_ready_lock);
+
+       fprintf(stderr, "SEQ-THREAD: prefetch done\n");
+}
+
+ImBuf * give_ibuf_threaded(int rectx, int recty, int cfra, int chanshown)
+{
+       PrefetchQueueElem * e = 0;
+       int found_something = FALSE;
+
+       if (seq_thread_shutdown) {
+               return give_ibuf_seq(rectx, recty, cfra, chanshown);
+       }
+
+       while (!e) {
+               int success = FALSE;
+               pthread_mutex_lock(&queue_lock);
+
+               for (e = prefetch_done.first; e; e = e->next) {
+                       if (cfra == e->cfra &&
+                           chanshown == e->chanshown &&
+                           rectx == e->rectx && 
+                           recty == e->recty) {
+                               success = TRUE;
+                               found_something = TRUE;
+                               break;
+                       }
+               }
+
+               if (!e) {
+                       for (e = prefetch_wait.first; e; e = e->next) {
+                               if (cfra == e->cfra &&
+                                   chanshown == e->chanshown &&
+                                   rectx == e->rectx && 
+                                   recty == e->recty) {
+                                       found_something = TRUE;
+                                       break;
+                               }
+                       }
+               }
+
+               if (!e) {
+                       PrefetchThread *tslot;
+
+                       for(tslot = running_threads.first; 
+                           tslot; tslot= tslot->next) {
+                               if (tslot->current &&
+                                   cfra == tslot->current->cfra &&
+                                   chanshown == tslot->current->chanshown &&
+                                   rectx == tslot->current->rectx && 
+                                   recty == tslot->current->recty) {
+                                       found_something = TRUE;
+                                       break;
+                               }
+                       }
+               }
+
+               /* e->ibuf is unrefed by render thread on next round. */
+
+               if (e) {
+                       seq_last_given_monoton_cfra = e->monoton_cfra;
+               }
+
+               pthread_mutex_unlock(&queue_lock);
+
+               if (!success) {
+                       e = NULL;
+
+                       if (!found_something) {
+                               fprintf(stderr, 
+                                       "SEQ-THREAD: Requested frame "
+                                       "not in queue ???\n");
+                               break;
+                       }
+                       pthread_mutex_lock(&frame_done_lock);
+                       pthread_cond_wait(&frame_done_cond, &frame_done_lock);
+                       pthread_mutex_unlock(&frame_done_lock);
+               }
+       }
+       
+       return e ? e->ibuf : 0;
+}
+
+
+
 /* Functions to free imbuf and anim data on changes */
 
 static void free_imbuf_strip_elem(StripElem *se)
@@ -1371,11 +1691,12 @@ void do_render_seq(RenderResult *rr, int cfra)
                */
                {
                        extern int mem_in_use;
+                       extern int mmap_in_use;
 
                        int max = MEM_CacheLimiter_get_maximum();
-                       if (max != 0 && mem_in_use > max) {
+                       if (max != 0 && mem_in_use + mmap_in_use > max) {
                                fprintf(stderr, "mem_in_use = %d, max = %d\n",
-                                       mem_in_use, max);
+                                       mem_in_use + mmap_in_use, max);
                                fprintf(stderr, "Cleaning up, please wait...\n"
                                        "If this happens very often,\n"
                                        "consider "
index 8563a0f634fdd37994c0507a991ae42de6c16a05..5eceb5ee43308dcb940f6b0667133593568f98c1 100644 (file)
@@ -2876,8 +2876,10 @@ static void winqreadipospace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                        allqueue(REDRAWIPO, 0);
                        break;
                case RKEY:
-                       if (G.qual==0)
+                       if (G.qual==LR_CTRLKEY)
                                ipo_record();
+                       else 
+                               transform_ipo('r');
                        break;
                case SKEY:
                        if (G.qual==LR_SHIFTKEY) {              
@@ -3158,8 +3160,8 @@ void drawinfospace(ScrArea *sa, void *spacedata)
        uiBlock *block;
        static short cur_light=0;
        float fac, col[3];
-       short xpos, ypos, ypostab,  buth, rspace, dx, y1, y2, y3, y4, y5, y6;
-       short y2label, y3label, y4label, y5label, y6label;
+       short xpos, ypos, ypostab,  buth, rspace, dx, y1, y2, y3, y4, y5, y6, y7;
+       short y2label, y3label, y4label, y5label, y6label, y7label;
        short spref, mpref, lpref, smfileselbut;
        short edgsp, midsp;
        char naam[32];
@@ -3210,6 +3212,7 @@ void drawinfospace(ScrArea *sa, void *spacedata)
        y4 = ypos+3*(buth+rspace);
        y5 = ypos+4*(buth+rspace);
        y6 = ypos+5*(buth+rspace);
+       y7 = ypos+6*(buth+rspace);
 
 
        y2label = y2-2;         /* adjustments to offset the labels down to align better */
@@ -3217,6 +3220,7 @@ void drawinfospace(ScrArea *sa, void *spacedata)
        y4label = y4-2;
        y5label = y5-2;
        y6label = y6-2;
+       y7label = y7-2;
 
 
        /* set the color to blue and draw the main 'tab' controls */
@@ -3808,8 +3812,13 @@ void drawinfospace(ScrArea *sa, void *spacedata)
 
 
                uiDefBut(block, LABEL,0,"System:",
-                       (xpos+edgsp+(4*midsp)+(4*mpref)),y6label,mpref,buth,
+                       (xpos+edgsp+(4*midsp)+(4*mpref)),y7label,mpref,buth,
                        0, 0, 0, 0, 0, "");
+               uiDefButI(block, NUM, B_REDR, "Prefetch frames ",
+                         (xpos+edgsp+(4*mpref)+(4*midsp)), y6, mpref, buth, 
+                         &U.prefetchframes, 0.0, 50.0, 20, 2, 
+                         "Number of frames to render ahead during playback.");
+
                uiDefButI(block, NUM, B_MEMCACHELIMIT, "MEM Cache Limit ",
                          (xpos+edgsp+(4*mpref)+(4*midsp)), y5, mpref, buth, 
                          &U.memcachelimit, 0.0, 1024.0, 30, 2, 
@@ -4817,7 +4826,6 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                else if((G.qual==0))
                                        borderselect_sima(UV_SELECT_ALL);
                                break;
-                               
                        case CKEY:
                                if (G.sima->flag & SI_SYNC_UVSEL) {
                                        /* operate on the editmesh */
@@ -4877,6 +4885,7 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                        pin_tface_uv(0);
                                else
                                        pin_tface_uv(1);
+                               break;
                        case GKEY:
                                if((G.qual==0) && is_uv_tface_editing_allowed()) {
                                        initTransform(TFM_TRANSLATION, CTX_NONE);
@@ -4901,10 +4910,10 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                }
                                break;
                        case VKEY:
-                               if(G.qual==LR_SHIFTKEY)
-                                       stitch_uv_tface(0);
+                               if(G.qual == 0)
+                                       stitch_vert_uv_tface();
                                else if(G.qual==LR_SHIFTKEY)
-                                       stitch_uv_tface(1);
+                                       stitch_limit_uv_tface();
                                else if(G.qual==LR_CTRLKEY)
                                        minimize_stretch_tface_uv();
                                break;
@@ -4925,7 +4934,6 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                scrarea_queue_headredraw(curarea);
                                scrarea_queue_winredraw(curarea);
                                break;
-                               
                        case PERIODKEY:
                                if(G.qual==LR_CTRLKEY) {
                                        G.v2d->around= V3D_LOCAL;
@@ -4947,7 +4955,6 @@ static void winqreadimagespace(ScrArea *sa, void *spacedata, BWinEvent *evt)
                                        G.scene->prop_mode = (G.scene->prop_mode+1)%7;
                                        allqueue(REDRAWHEADERS, 0);
                                }
-                               
                                break;
                        case PADSLASHKEY:
                                if(G.qual==0)
@@ -6274,7 +6281,7 @@ SpaceType *spaceaction_get_type(void)
        
        if (!st) {
                st= spacetype_new("Action");
-               spacetype_set_winfuncs(st, drawactionspace, changeactionspace, winqreadactionspace);
+               spacetype_set_winfuncs(st, NULL, drawactionspace, changeactionspace, winqreadactionspace);
        }
 
        return st;
@@ -6285,7 +6292,7 @@ SpaceType *spacebuts_get_type(void)
        
        if (!st) {
                st= spacetype_new("Buts");
-               spacetype_set_winfuncs(st, drawbutspace, changebutspace, winqreadbutspace);
+               spacetype_set_winfuncs(st, NULL, drawbutspace, changebutspace, winqreadbutspace);
        }
 
        return st;
@@ -6296,7 +6303,7 @@ SpaceType *spacefile_get_type(void)
        
        if (!st) {
                st= spacetype_new("File");
-               spacetype_set_winfuncs(st, drawfilespace, NULL, winqreadfilespace);
+               spacetype_set_winfuncs(st, NULL, drawfilespace, NULL, winqreadfilespace);
        }
 
        return st;
@@ -6307,7 +6314,7 @@ SpaceType *spaceimage_get_type(void)
        
        if (!st) {
                st= spacetype_new("Image");
-               spacetype_set_winfuncs(st, drawimagespace, changeimagepace, winqreadimagespace);
+               spacetype_set_winfuncs(st, NULL, drawimagespace, changeimagepace, winqreadimagespace);
        }
 
        return st;
@@ -6318,7 +6325,7 @@ SpaceType *spaceimasel_get_type(void)
        
        if (!st) {
                st= spacetype_new("Imasel");
-               spacetype_set_winfuncs(st, drawimaselspace, changeimaselspace, winqreadimaselspace);
+               spacetype_set_winfuncs(st, NULL, drawimaselspace, changeimaselspace, winqreadimaselspace);
        }
 
        return st;
@@ -6329,7 +6336,7 @@ SpaceType *spaceinfo_get_type(void)
        
        if (!st) {
                st= spacetype_new("Info");
-               spacetype_set_winfuncs(st, drawinfospace, NULL, winqreadinfospace);
+               spacetype_set_winfuncs(st, NULL, drawinfospace, NULL, winqreadinfospace);
        }
 
        return st;
@@ -6340,7 +6347,7 @@ SpaceType *spaceipo_get_type(void)
        
        if (!st) {
                st= spacetype_new("Ipo");
-               spacetype_set_winfuncs(st, drawipospace, changeview2dspace, winqreadipospace);
+               spacetype_set_winfuncs(st, NULL, drawipospace, changeview2dspace, winqreadipospace);
        }
 
        return st;
@@ -6351,7 +6358,7 @@ SpaceType *spacenla_get_type(void)
        
        if (!st) {
                st= spacetype_new("Nla");
-               spacetype_set_winfuncs(st, drawnlaspace, changeview2dspace, winqreadnlaspace);
+               spacetype_set_winfuncs(st, NULL, drawnlaspace, changeview2dspace, winqreadnlaspace);
        }
 
        return st;
@@ -6362,7 +6369,7 @@ SpaceType *spaceoops_get_type(void)
        
        if (!st) {
                st= spacetype_new("Oops");
-               spacetype_set_winfuncs(st, drawoopsspace, changeview2dspace, winqreadoopsspace);
+               spacetype_set_winfuncs(st, NULL, drawoopsspace, changeview2dspace, winqreadoopsspace);
        }
 
        return st;
@@ -6373,7 +6380,7 @@ SpaceType *spaceseq_get_type(void)
        
        if (!st) {
                st= spacetype_new("Sequence");
-               spacetype_set_winfuncs(st, drawseqspace, changeview2dspace, winqreadseqspace);
+               spacetype_set_winfuncs(st, drawprefetchseqspace, drawseqspace, changeview2dspace, winqreadseqspace);
        }
 
        return st;
@@ -6384,7 +6391,7 @@ SpaceType *spacesound_get_type(void)
        
        if (!st) {
                st= spacetype_new("Sound");
-               spacetype_set_winfuncs(st, drawsoundspace, changeview2dspace, winqreadsoundspace);
+               spacetype_set_winfuncs(st, NULL, drawsoundspace, changeview2dspace, winqreadsoundspace);
        }
 
        return st;
@@ -6395,7 +6402,7 @@ SpaceType *spacetext_get_type(void)
        
        if (!st) {
                st= spacetype_new("Text");
-               spacetype_set_winfuncs(st, drawtextspace, NULL, winqreadtextspace);
+               spacetype_set_winfuncs(st, NULL, drawtextspace, NULL, winqreadtextspace);
        }
 
        return st;
@@ -6419,7 +6426,7 @@ SpaceType *spacescript_get_type(void)
 
        if (!st) {
                st = spacetype_new("Script");
-               spacetype_set_winfuncs(st, drawscriptspace, spacescript_change, winqreadscriptspace);
+               spacetype_set_winfuncs(st, NULL, drawscriptspace, spacescript_change, winqreadscriptspace);
        }
 
        return st;
@@ -6430,7 +6437,7 @@ SpaceType *spaceview3d_get_type(void)
        
        if (!st) {
                st= spacetype_new("View3D");
-               spacetype_set_winfuncs(st, drawview3dspace, changeview3dspace, winqreadview3dspace);
+               spacetype_set_winfuncs(st, NULL, drawview3dspace, changeview3dspace, winqreadview3dspace);
        }
 
        return st;
@@ -6441,7 +6448,7 @@ SpaceType *spacetime_get_type(void)
        
        if (!st) {
                st= spacetype_new("Time");
-               spacetype_set_winfuncs(st, drawtimespace, NULL, winqreadtimespace);
+               spacetype_set_winfuncs(st, NULL, drawtimespace, NULL, winqreadtimespace);
        }
        
        return st;
@@ -6453,7 +6460,7 @@ SpaceType *spacenode_get_type(void)
        
        if (!st) {
                st= spacetype_new("Node");
-               spacetype_set_winfuncs(st, drawnodespace, changeview2dspace, winqreadnodespace);
+               spacetype_set_winfuncs(st, NULL, drawnodespace, changeview2dspace, winqreadnodespace);
        }
        
        return st;
index ea0d680e852ec67b494bb44b36bee9c89b6d9d4b..4a0375f2366d60437883b34b11addbb3a96d07fa 100644 (file)
@@ -52,6 +52,7 @@
 struct _SpaceType {
        char                    name[32];
        
+       SpacePrefetchDrawFP winprefetchdraw;
        SpaceDrawFP             windraw;
        SpaceChangeFP   winchange;
        SpaceHandleFP   winhandle;
@@ -70,8 +71,9 @@ SpaceType *spacetype_new(char *name)
        return st;
 }
 
-void spacetype_set_winfuncs(SpaceType *st, SpaceDrawFP draw, SpaceChangeFP change, SpaceHandleFP handle) 
+void spacetype_set_winfuncs(SpaceType *st, SpacePrefetchDrawFP prefetchdraw, SpaceDrawFP draw, SpaceChangeFP change, SpaceHandleFP handle) 
 {
+       st->winprefetchdraw = prefetchdraw;
        st->windraw= draw;
        st->winchange= change;
        st->winhandle= handle;
@@ -105,6 +107,17 @@ static SpaceType *spacetype_from_area(ScrArea *area)
        }
 }
 
+void scrarea_do_winprefetchdraw(ScrArea *area)
+{
+       SpaceType *st= spacetype_from_area(area);
+       
+       areawinset(area->win);
+
+       if(area->win && st->winprefetchdraw) {
+               st->winprefetchdraw(area, area->spacedata.first);
+       }
+}
+
 void scrarea_do_windraw(ScrArea *area)
 {
        SpaceType *st= spacetype_from_area(area);
index dae288293abf803bf23477cb7b0212a3a1078f6b..b58d5d057354dc5d5aaba655bdfe771226d2a86c 100644 (file)
@@ -267,16 +267,26 @@ void convertViewVec(TransInfo *t, float *vec, short dx, short dy)
        }
        else if(t->spacetype==SPACE_IMAGE) {
                float divx, divy, aspx, aspy;
-
+               
                transform_aspect_ratio_tface_uv(&aspx, &aspy);
-
+               
                divx= G.v2d->mask.xmax-G.v2d->mask.xmin;
                divy= G.v2d->mask.ymax-G.v2d->mask.ymin;
-
+               
                vec[0]= aspx*(G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/divx;
                vec[1]= aspy*(G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/divy;
                vec[2]= 0.0f;
        }
+       else if(t->spacetype==SPACE_IPO) {
+               float divx, divy;
+               
+               divx= G.v2d->mask.xmax-G.v2d->mask.xmin;
+               divy= G.v2d->mask.ymax-G.v2d->mask.ymin;
+               
+               vec[0]= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx) / (divx);
+               vec[1]= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy) / (divy);
+               vec[2]= 0.0f;
+       }
 }
 
 void projectIntView(TransInfo *t, float *vec, int *adr)
@@ -285,13 +295,20 @@ void projectIntView(TransInfo *t, float *vec, int *adr)
                project_int(vec, adr);
        else if(t->spacetype==SPACE_IMAGE) {
                float aspx, aspy, v[2];
-
+               
                transform_aspect_ratio_tface_uv(&aspx, &aspy);
                v[0]= vec[0]/aspx;
                v[1]= vec[1]/aspy;
-
+               
                uvco_to_areaco_noclip(v, adr);
        }
+       else if(t->spacetype==SPACE_IPO) {
+               short out[2] = {0.0f, 0.0f};
+               
+               ipoco_to_areaco(G.v2d, vec, out);
+               adr[0]= out[0];
+               adr[1]= out[1];
+       }
 }
 
 void projectFloatView(TransInfo *t, float *vec, float *adr)
@@ -300,7 +317,14 @@ void projectFloatView(TransInfo *t, float *vec, float *adr)
                project_float(vec, adr);
        else if(t->spacetype==SPACE_IMAGE) {
                int a[2];
-
+               
+               projectIntView(t, vec, a);
+               adr[0]= a[0];
+               adr[1]= a[1];
+       }
+       else if(t->spacetype==SPACE_IPO) {
+               int a[2];
+               
                projectIntView(t, vec, a);
                adr[0]= a[0];
                adr[1]= a[1];
@@ -638,14 +662,19 @@ static void transformEvent(unsigned short event, short val) {
                case XKEY:
                        if ((Trans.flag & T_NO_CONSTRAINT)==0) {
                                if (cmode == 'X') {
-                                       if (Trans.con.mode & CON_USER) {
+                                       if (Trans.flag & T_2D_EDIT) {
                                                stopConstraint(&Trans);
                                        }
                                        else {
-                                               if (G.qual == 0)
-                                                       setUserConstraint(&Trans, (CON_AXIS0), "along %s X");
-                                               else if ((G.qual == LR_SHIFTKEY) && ((Trans.flag & T_2D_EDIT)==0))
-                                                       setUserConstraint(&Trans, (CON_AXIS1|CON_AXIS2), "locking %s X");
+                                               if (Trans.con.mode & CON_USER) {
+                                                       stopConstraint(&Trans);
+                                               }
+                                               else {
+                                                       if (G.qual == 0)
+                                                               setUserConstraint(&Trans, (CON_AXIS0), "along %s X");
+                                                       else if (G.qual == LR_SHIFTKEY)
+                                                               setUserConstraint(&Trans, (CON_AXIS1|CON_AXIS2), "locking %s X");
+                                               }
                                        }
                                }
                                else {
@@ -660,14 +689,19 @@ static void transformEvent(unsigned short event, short val) {
                case YKEY:
                        if ((Trans.flag & T_NO_CONSTRAINT)==0) {
                                if (cmode == 'Y') {
-                                       if (Trans.con.mode & CON_USER) {
+                                       if (Trans.flag & T_2D_EDIT) {
                                                stopConstraint(&Trans);
                                        }
                                        else {
-                                               if (G.qual == 0)
-                                                       setUserConstraint(&Trans, (CON_AXIS1), "along %s Y");
-                                               else if ((G.qual == LR_SHIFTKEY) && ((Trans.flag & T_2D_EDIT)==0))
-                                                       setUserConstraint(&Trans, (CON_AXIS0|CON_AXIS2), "locking %s Y");
+                                               if (Trans.con.mode & CON_USER) {
+                                                       stopConstraint(&Trans);
+                                               }
+                                               else {
+                                                       if (G.qual == 0)
+                                                               setUserConstraint(&Trans, (CON_AXIS1), "along %s Y");
+                                                       else if (G.qual == LR_SHIFTKEY)
+                                                               setUserConstraint(&Trans, (CON_AXIS0|CON_AXIS2), "locking %s Y");
+                                               }
                                        }
                                }
                                else {
@@ -1711,7 +1745,7 @@ int Resize(TransInfo *t, short mval[2])
                ElementResize(t, td, mat);
        }
 
-       /* evil hack - redo resize if cliiping needeed */
+       /* evil hack - redo resize if cliping needed */
        if (t->flag & T_CLIP_UV && clipUVTransform(t, size, 1)) {
                SizeToMat3(size, mat);
 
@@ -1833,6 +1867,9 @@ void initRotation(TransInfo *t)
        t->snap[1] = (float)((5.0/180)*M_PI);
        t->snap[2] = t->snap[1] * 0.2f;
        t->fac = 0;
+       
+       if (t->flag & T_2D_EDIT)
+               t->flag |= T_NO_CONSTRAINT;
 }
 
 static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3]) {
index 39c63380c1e1b7b5a2347ada777f9cd15eed317b..71e672971f52c766628f515946dab72b8ca3cc58 100644 (file)
@@ -1581,7 +1581,7 @@ static void set_crazyspace_quats(float *origcos, float *mappedcos, float *quats)
        
        /* two abused locations in vertices */
        for(eve= em->verts.first; eve; eve= eve->next, index++) {
-               eve->tmp.fp = NULL;
+               eve->tmp.p = NULL;
                eve->prev= (EditVert *)index;
        }
        
@@ -1597,9 +1597,9 @@ static void set_crazyspace_quats(float *origcos, float *mappedcos, float *quats)
                co2= (origcos)? origcos + 3*(long)(efa->v2->prev): efa->v2->co;
                co3= (origcos)? origcos + 3*(long)(efa->v3->prev): efa->v3->co;
 
-               if(efa->v2->tmp.fp==NULL && efa->v2->f1) {
+               if(efa->v2->tmp.p==NULL && efa->v2->f1) {
                        set_crazy_vertex_quat(quats, co2, co3, co1, v2, v3, v1);
-                       efa->v2->tmp.fp= quats;
+                       efa->v2->tmp.p= (void*)quats;
                        quats+= 4;
                }
                
@@ -1607,31 +1607,31 @@ static void set_crazyspace_quats(float *origcos, float *mappedcos, float *quats)
                        v4= mappedcos + 3*(long)(efa->v4->prev);
                        co4= (origcos)? origcos + 3*(long)(efa->v4->prev): efa->v4->co;
 
-                       if(efa->v1->tmp.fp==NULL && efa->v1->f1) {
+                       if(efa->v1->tmp.p==NULL && efa->v1->f1) {
                                set_crazy_vertex_quat(quats, co1, co2, co4, v1, v2, v4);
-                               efa->v1->tmp.fp= quats;
+                               efa->v1->tmp.p= (void*)quats;
                                quats+= 4;
                        }
-                       if(efa->v3->tmp.fp==NULL && efa->v3->f1) {
+                       if(efa->v3->tmp.p==NULL && efa->v3->f1) {
                                set_crazy_vertex_quat(quats, co3, co4, co2, v3, v4, v2);
-                               efa->v3->tmp.fp= quats;
+                               efa->v3->tmp.p= (void*)quats;
                                quats+= 4;
                        }
-                       if(efa->v4->tmp.fp==NULL && efa->v4->f1) {
+                       if(efa->v4->tmp.p==NULL && efa->v4->f1) {
                                set_crazy_vertex_quat(quats, co4, co1, co3, v4, v1, v3);
-                               efa->v4->tmp.fp= quats;
+                               efa->v4->tmp.p= (void*)quats;
                                quats+= 4;
                        }
                }
                else {
-                       if(efa->v1->tmp.fp==NULL && efa->v1->f1) {
+                       if(efa->v1->tmp.p==NULL && efa->v1->f1) {
                                set_crazy_vertex_quat(quats, co1, co2, co3, v1, v2, v3);
-                               efa->v1->tmp.fp= quats;
+                               efa->v1->tmp.p= (void*)quats;
                                quats+= 4;
                        }
-                       if(efa->v3->tmp.fp==NULL && efa->v3->f1) {
+                       if(efa->v3->tmp.p==NULL && efa->v3->f1) {
                                set_crazy_vertex_quat(quats, co3, co1, co2, v3, v1, v2);
-                               efa->v3->tmp.fp= quats;
+                               efa->v3->tmp.p= (void*)quats;
                                quats+= 4;
                        }
                }
@@ -1765,12 +1765,12 @@ static void createTransEditVerts(TransInfo *t)
                                }
                                
                                /* CrazySpace */
-                               if(defmats || (quats && eve->tmp.fp)) {
+                               if(defmats || (quats && eve->tmp.p)) {
                                        float mat[3][3], imat[3][3], qmat[3][3];
                                        
                                        /* use both or either quat and defmat correction */
                                        if(quats && eve->tmp.f) {
-                                               QuatToMat3(eve->tmp.fp, qmat);
+                                               QuatToMat3(eve->tmp.p, qmat);
 
                                                if(defmats)
                                                        Mat3MulSerie(mat, mtx, qmat, defmats[a],
@@ -1882,7 +1882,7 @@ static void createTransUVs(TransInfo *t)
        t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(UV Editing)");
        /* for each 2d uv coord a 3d vector is allocated, so that they can be
           treated just as if they were 3d verts */
-       t->data2d= MEM_mallocN(t->total*sizeof(TransData2D), "TransObData2D(UV Editing)");
+       t->data2d= MEM_callocN(t->total*sizeof(TransData2D), "TransObData2D(UV Editing)");
 
        if(G.sima->flag & SI_CLIP_UV)
                t->flag |= T_CLIP_UV;
@@ -1988,6 +1988,39 @@ int clipUVTransform(TransInfo *t, float *vec, int resize)
        return (clipx || clipy);
 }
 
+/* ********************* IPO EDITOR ************************* */
+
+/* for IPO Editor transform - but actual creation of transform structures is not performed here
+ * due to bad globals that would need to be imported specially for this
+ */
+static void createTransIpoData(TransInfo *t)
+{
+       /* in editipo.c due to some globals that are defined in that file... */
+       make_ipo_transdata(t);
+}
+
+/* this function is called on recalcData to apply the transforms applied
+ * to the transdata on to the actual keyframe data 
+ */
+void flushTransIpoData(TransInfo *t)
+{
+       TransData2D *td;
+       int a;
+       
+       /* flush to 2d vector from internally used 3d vector */
+       for (a=0, td= t->data2d; a<t->total; a++, td++) {
+               /* we need to unapply the nla-scaling from the time in some situations */
+               if (NLA_IPO_SCALED)
+                       td->loc2d[0]= get_action_frame(OBACT, td->loc[0]);
+               else
+                       td->loc2d[0]= td->loc[0];
+               
+               /* when the icu that point comes from is a bitflag holder, don't allow adjusting values */
+               if ((t->data[a].flag & TD_TIMEONLY)==0)
+                       td->loc2d[1]= td->loc[1];
+       }
+}
+
 /* ********************* ACTION/NLA EDITOR ****************** */
 
 
@@ -2110,7 +2143,7 @@ static void createTransActionData(TransInfo *t)
        BLI_freelistN(&act_data);
 }
 
-static void createTransNLAData(TransInfo *t)
+static void createTransNlaData(TransInfo *t)
 {
        Base *base;
        bActionStrip *strip;
@@ -3000,7 +3033,16 @@ void createTransData(TransInfo *t)
        }
        else if (t->spacetype == SPACE_NLA) {
                t->flag |= T_POINTS|T_2D_EDIT;
-               createTransNLAData(t);
+               createTransNlaData(t);
+       }
+       else if (t->spacetype == SPACE_IPO) {
+               t->flag |= T_POINTS|T_2D_EDIT;
+               createTransIpoData(t); 
+               if (t->data && (t->flag & T_PROP_EDIT)) {
+                       sort_trans_data(t);     // makes selected become first in array
+                       set_prop_dist(t, 1);
+                       sort_trans_data_dist(t);
+               }
        }
        else if (G.obedit) {
                t->ext = NULL;
index d8afce9f2c621075966aff4999d7e2851fc9a3f1..ea8555eb7c44233fb5f3688ac753f69687ec3461 100644 (file)
@@ -62,6 +62,9 @@
 #include "BIF_meshtools.h"
 #include "BIF_retopo.h"
 
+#include "BSE_editipo.h"
+#include "BSE_editipo_types.h"
+
 #ifdef WITH_VERSE
 #include "BIF_verse.h"
 #endif
@@ -229,7 +232,7 @@ void recalcData(TransInfo *t)
                /* determine what type of data we are operating on */
                data = get_action_context(&context);
                if (data == NULL) return;
-       
+               
                if (G.saction->lock) {
                        if (context == ACTCONT_ACTION) {
                                if(ob) {
@@ -260,6 +263,66 @@ void recalcData(TransInfo *t)
                        DAG_scene_flush_update(G.scene, screen_view3d_layers());
                }
        }
+       else if (t->spacetype == SPACE_IPO) {
+               EditIpo *ei;
+               int dosort = 0;
+               int a;
+               
+               /* do the flush first */
+               flushTransIpoData(t);
+               
+               /* now test if there is a need to re-sort */
+               ei= G.sipo->editipo;
+               for (a=0; a<G.sipo->totipo; a++, ei++) {
+                       if (ISPOIN(ei, flag & IPO_VISIBLE, icu)) {
+                               
+                               /* watch it: if the time is wrong: do not correct handles */
+                               if (test_time_ipocurve(ei->icu) ) dosort++;
+                               else testhandles_ipocurve(ei->icu);
+                       }
+               }
+               
+               /* do resort and other updates? */
+               if (dosort) remake_ipo_transdata(t);
+               if (G.sipo->showkey) update_ipokey_val();
+               
+               calc_ipo(G.sipo->ipo, (float)CFRA);
+               
+               /* update realtime - not working? */
+               if (G.sipo->lock) {
+                       if (G.sipo->blocktype==ID_MA || G.sipo->blocktype==ID_TE) {
+                               do_ipo(G.sipo->ipo);
+                       }
+                       else if(G.sipo->blocktype==ID_CA) {
+                               do_ipo(G.sipo->ipo);
+                       }
+                       else if(G.sipo->blocktype==ID_KE) {
+                               Object *ob= OBACT;
+                               if(ob) {
+                                       ob->shapeflag &= ~OB_SHAPE_TEMPLOCK;
+                                       DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+                               }
+                       }
+                       else if(G.sipo->blocktype==ID_PO) {
+                               Object *ob= OBACT;
+                               if(ob && ob->pose) {
+                                       DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
+                               }
+                       }
+                       else if(G.sipo->blocktype==ID_OB) {
+                               Base *base= FIRSTBASE;
+                               
+                               while(base) {
+                                       if(base->object->ipo==G.sipo->ipo) {
+                                               do_ob_ipo(base->object);
+                                               base->object->recalc |= OB_RECALC_OB;
+                                       }
+                                       base= base->next;
+                               }
+                               DAG_scene_flush_update(G.scene, screen_view3d_layers());
+                       }
+               }
+       }
        else if (G.obedit) {
                if (G.obedit->type == OB_MESH) {
                        if(t->spacetype==SPACE_IMAGE) {
index caf3d120fab1327f1fcb759382fd2eb3fe3fbe13..463f06869d6c64dfd84d4c8b6f15c498d1545544 100644 (file)
@@ -452,4 +452,27 @@ RAS_IPolyMaterial* KX_BlenderRenderTools::CreateBlenderPolyMaterial(
        return NULL;
 }
 
+void KX_BlenderRenderTools::MotionBlur(RAS_IRasterizer* rasterizer)
+{
+       int state = rasterizer->GetMotionBlurState();
+       float motionblurvalue;
+       if(state)
+       {
+               motionblurvalue = rasterizer->GetMotionBlurValue();
+               if(state==1)
+               {
+                       //bugfix:load color buffer into accum buffer for the first time(state=1)
+                       glAccum(GL_LOAD, 1.0);
+                       rasterizer->SetMotionBlurState(2);
+               }
+               else if(motionblurvalue>=0.0 && motionblurvalue<=1.0)
+               {
+                       glAccum(GL_MULT, motionblurvalue);
+                       glAccum(GL_ACCUM, 1-motionblurvalue);
+                       glAccum(GL_RETURN, 1.0);
+                       glFlush();
+               }
+       }
+}
+
 unsigned int KX_BlenderRenderTools::m_numgllights;
index dc638d1a43a44fb15c536597f7cf42f8dfb830cd..a79302a283eeda82b0e982fceabcb8ed26c2a282 100644 (file)
@@ -100,7 +100,10 @@ public:
                                                                        void* tface);
        
        bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data);
+
+       virtual void MotionBlur(RAS_IRasterizer* rasterizer);
 };
 
 #endif //__KX_BLENDERRENDERTOOLS
 
+
index 0f6bec30437f206201e4bb16914f36e269536e46..cc5c392d51a5064800d8c91c0d6bf6dd70709907 100644 (file)
@@ -570,4 +570,27 @@ void GPC_RenderTools::applyTransform(RAS_IRasterizer* rasty,double* oglmatrix,in
        }
 }
 
+void GPC_RenderTools::MotionBlur(RAS_IRasterizer* rasterizer)
+{
+       int state = rasterizer->GetMotionBlurState();
+       float motionblurvalue;
+       if(state)
+       {
+               motionblurvalue = rasterizer->GetMotionBlurValue();
+               if(state==1)
+               {
+                       //bugfix:load color buffer into accum buffer for the first time(state=1)
+                       glAccum(GL_LOAD, 1.0);
+                       rasterizer->SetMotionBlurState(2);
+               }
+               else if(motionblurvalue>=0.0 && motionblurvalue<=1.0)
+               {
+                       glAccum(GL_MULT, motionblurvalue);
+                       glAccum(GL_ACCUM, 1-motionblurvalue);
+                       glAccum(GL_RETURN, 1.0);
+                       glFlush();
+               }
+       }
+}
+
 unsigned int GPC_RenderTools::m_numgllights;
index b7f73df3c3477d1ad1eec2b3fb16aebf1999c769..e1f2a869c22d3e3ae4a2fa42b5c28a4b10a62133 100644 (file)
@@ -149,6 +149,8 @@ public:
        int applyLights(int objectlayer);
 
        bool RayHit(KX_ClientObjectInfo* client, MT_Point3& hit_point, MT_Vector3& hit_normal, void * const data);
+
+       virtual void MotionBlur(RAS_IRasterizer* rasterizer);
 protected:
        /** 
         * Copied from KX_BlenderGL.cpp in KX_blenderhook
@@ -173,3 +175,4 @@ protected:
 
 #endif  // __GPC_RENDERTOOLS_H
 
+
index e76e28bcb7b98baf342cfaefc389374231c9f483..f8826245aab55644c7643bacd686e859ce640905 100644 (file)
@@ -966,6 +966,9 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam)
        scene->CalculateVisibleMeshes(m_rasterizer,cam);
 
        scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools);
+
+       m_rendertools->MotionBlur(m_rasterizer);
+
 }
 
 
@@ -1463,3 +1466,4 @@ void KX_KetsjiEngine::GetOverrideFrameColor(float& r, float& g, float& b) const
        b = m_overrideFrameColorB;
 }
 
+
index 7a937d5e3492088f97f5c449e7bb497a79681887..1a3a0490d218702c74061362ed511ef4ab4a1326 100644 (file)
@@ -618,7 +618,31 @@ static PyObject* gPyMakeScreenshot(PyObject*,
        Py_Return;
 }
 
+static PyObject* gPyEnableMotionBlur(PyObject*,
+                                                                       PyObject* args,
+                                                                       PyObject*)
+{
+       float motionblurvalue;
+       if (PyArg_ParseTuple(args,"f",&motionblurvalue))
+       {
+               if(gp_Rasterizer)
+               {
+                       gp_Rasterizer->EnableMotionBlur(motionblurvalue);
+               }
+       }
+       Py_Return;
+}
 
+static PyObject* gPyDisableMotionBlur(PyObject*,
+                                                                       PyObject* args,
+                                                                       PyObject*)
+{
+       if(gp_Rasterizer)
+       {
+               gp_Rasterizer->DisableMotionBlur();
+       }
+       Py_Return;
+}
 
 STR_String     gPyGetWindowHeight__doc__="getWindowHeight doc";
 STR_String     gPyGetWindowWidth__doc__="getWindowWidth doc";
@@ -645,6 +669,9 @@ static struct PyMethodDef rasterizer_methods[] = {
  {"setMistColor",(PyCFunction)gPySetMistColor,METH_VARARGS,"set Mist Color (rgb)"},
   {"setMistStart",(PyCFunction)gPySetMistStart,METH_VARARGS,"set Mist Start(rgb)"},
   {"setMistEnd",(PyCFunction)gPySetMistEnd,METH_VARARGS,"set Mist End(rgb)"},
+  {"enableMotionBlur",(PyCFunction)gPyEnableMotionBlur,METH_VARARGS,"enable motion blur"},
+  {"disableMotionBlur",(PyCFunction)gPyDisableMotionBlur,METH_VARARGS,"disable motion blur"},
+
   
   {"setEyeSeparation", (PyCFunction) gPySetEyeSeparation, METH_VARARGS, "set the eye separation for stereo mode"},
   {"getEyeSeparation", (PyCFunction) gPyGetEyeSeparation, METH_VARARGS, "get the eye separation for stereo mode"},
index 8ecc9e7ad059859351edd117ff887f29ae39f090..560c6741260355b64b35d2578f8c120b2c82d25f 100644 (file)
@@ -48,7 +48,6 @@ class RAS_IPolyMaterial;
  */
 class RAS_IRasterizer
 {
-
 public:
 
        RAS_IRasterizer(RAS_ICanvas* canv){};
@@ -398,7 +397,15 @@ public:
 
        virtual bool    QueryLists(){return false;}
        virtual bool    QueryArrays(){return false;}
+       
+       virtual void    EnableMotionBlur(float motionblurvalue)=0;
+       virtual void    DisableMotionBlur()=0;
+       
+       virtual float   GetMotionBlurValue()=0;
+       virtual int     GetMotionBlurState()=0;
+       virtual void SetMotionBlurState(int newstate)=0;
 };
 
 #endif //__RAS_IRASTERIZER
 
+
index fa3c777553d5b3647c82548dbd18ed49292dad78..114783b9a47a9908e5aaaf425f0e72f29429bbc2 100644 (file)
@@ -174,6 +174,10 @@ public:
                struct RAS_LightObject* lightobject
        );
 
+       virtual
+               void
+       MotionBlur(RAS_IRasterizer* rasterizer)=0;
+
        virtual 
                class RAS_IPolyMaterial*        
        CreateBlenderPolyMaterial(
@@ -195,3 +199,4 @@ public:
 
 #endif //__RAS_IRENDERTOOLS
 
+
index 53ec7a02e6f79043196c9407b96ab5ca983265b0..85250fcd552d8033a188f926b010e23320a0a4a4 100644 (file)
@@ -82,7 +82,9 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
        m_setfocallength(false),
        m_noOfScanlines(32),
        m_useTang(false),
-       m_materialCachingInfo(0)
+       m_materialCachingInfo(0),
+       m_motionblur(0),
+       m_motionblurvalue(-1.0)
 {
        m_viewmatrix.Identity();
        
@@ -1979,3 +1981,15 @@ void RAS_OpenGLRasterizer::SetPolygonOffset(float mult, float add)
        else
                glDisable(mode);
 }
+
+void RAS_OpenGLRasterizer::EnableMotionBlur(float motionblurvalue)
+{
+       m_motionblur = 1;
+       m_motionblurvalue = motionblurvalue;
+}
+
+void RAS_OpenGLRasterizer::DisableMotionBlur()
+{
+       m_motionblur = 0;
+       m_motionblurvalue = -1.0;
+}
index d95ced658cedab9b58a1348093d47bd9afe9848c..6728905aa577bbec993c80e7f473587d3a83fa69 100644 (file)
@@ -91,6 +91,10 @@ class RAS_OpenGLRasterizer : public RAS_IRasterizer
        int                             m_noOfScanlines;
        bool                    InterlacedStereo() const;
 
+       //motion blur
+       int     m_motionblur;
+       float   m_motionblurvalue;
+
 protected:
        int                             m_drawingmode;
        TexCoGen                m_texco[RAS_MAX];
@@ -293,8 +297,22 @@ public:
                                        const RAS_TexVert& v2,
                                        const RAS_TexVert& v3,
                                        const MT_Vector3 &no);
-
+       
+       virtual void    EnableMotionBlur(float motionblurvalue);
+       virtual void    DisableMotionBlur();
+       virtual float   GetMotionBlurValue(){return m_motionblurvalue;};
+       virtual int     GetMotionBlurState(){return m_motionblur;};
+       virtual void SetMotionBlurState(int newstate)
+       {
+               if(newstate<0) 
+                       m_motionblur = 0;
+               else if(newstate>2)
+                       m_motionblur = 2;
+               else 
+                       m_motionblur = newstate;
+       };
 };
 
 #endif //__RAS_OPENGLRASTERIZER
 
+