diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7f513b8028f..0227c51f39d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -240,7 +240,11 @@ IF(WIN32)
SET(OPENEXR ${LIBDIR}/openexr)
SET(OPENEXR_INC ${OPENEXR}/include ${OPENEXR}/include/IlmImf ${OPENEXR}/include/Iex ${OPENEXR}/include/Imath)
SET(OPENEXR_LIB Iex Half IlmImf Imath IlmThread)
+ IF (MSVC80)
+ SET(OPENEXR_LIBPATH ${OPENEXR}/lib_vs2005)
+ ELSE (MSVC80)
SET(OPENEXR_LIBPATH ${OPENEXR}/lib_msvc)
+ ENDIF(MSVC80)
SET(QUICKTIME ${LIBDIR}/QTDevWin)
SET(QUICKTIME_INC ${QUICKTIME}/CIncludes)
diff --git a/extern/bFTGL/src/FTVectoriser.cpp b/extern/bFTGL/src/FTVectoriser.cpp
index bb133d025b4..82dcb0c0f51 100644
--- a/extern/bFTGL/src/FTVectoriser.cpp
+++ b/extern/bFTGL/src/FTVectoriser.cpp
@@ -5,8 +5,12 @@
#define CALLBACK
#endif
-#ifdef __APPLE_CC__
- typedef GLvoid (*GLUTesselatorFunction)(...);
+#if defined(__APPLE_CC__)
+ #if __APPLE_CC__ >= 5465
+ typedef GLvoid (*GLUTesselatorFunction)();
+ #else
+ typedef GLvoid (*GLUTesselatorFunction)(...);
+ #endif
#elif defined( __mips ) || defined( __linux__ ) || defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __sun ) || defined (__CYGWIN__)
typedef GLvoid (*GLUTesselatorFunction)();
#elif defined ( WIN32)
diff --git a/projectfiles_vc7/blender/nodes/nodes.vcproj b/projectfiles_vc7/blender/nodes/nodes.vcproj
index d5fe5328df3..04403630664 100644
--- a/projectfiles_vc7/blender/nodes/nodes.vcproj
+++ b/projectfiles_vc7/blender/nodes/nodes.vcproj
@@ -239,6 +239,9 @@
+
+
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index d5eb43fa12e..40f4ae7298e 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -411,12 +411,31 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest)
Mat4 *result_array= (rest)? bbone_rest_array: bbone_array;
bPoseChannel *next, *prev;
Bone *bone= pchan->bone;
- float h1[3], h2[3], length, hlength1, hlength2, roll1=0.0f, roll2;
- float mat3[3][3], imat[4][4];
+ float h1[3], h2[3], scale[3], length, hlength1, hlength2, roll1=0.0f, roll2;
+ float mat3[3][3], imat[4][4], posemat[4][4], scalemat[4][4], iscalemat[4][4];
float data[MAX_BBONE_SUBDIV+1][4], *fp;
- int a;
-
+ int a, doscale= 0;
+
length= bone->length;
+
+ if(!rest) {
+ /* check if we need to take non-uniform bone scaling into account */
+ scale[0]= VecLength(pchan->pose_mat[0]);
+ scale[1]= VecLength(pchan->pose_mat[1]);
+ scale[2]= VecLength(pchan->pose_mat[2]);
+
+ if(fabs(scale[0] - scale[1]) > 1e-6f || fabs(scale[1] - scale[2]) > 1e-6f) {
+ Mat4One(scalemat);
+ scalemat[0][0]= scale[0];
+ scalemat[1][1]= scale[1];
+ scalemat[2][2]= scale[2];
+ Mat4Invert(iscalemat, scalemat);
+
+ length *= scale[1];
+ doscale = 1;
+ }
+ }
+
hlength1= bone->ease1*length*0.390464f; // 0.5*sqrt(2)*kappa, the handle length for near-perfect circles
hlength2= bone->ease2*length*0.390464f;
@@ -432,8 +451,14 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest)
first point = (0,0,0)
last point = (0, length, 0) */
- if(rest)
+ if(rest) {
Mat4Invert(imat, pchan->bone->arm_mat);
+ }
+ else if(doscale) {
+ Mat4CpyMat4(posemat, pchan->pose_mat);
+ Mat4Ortho(posemat);
+ Mat4Invert(imat, posemat);
+ }
else
Mat4Invert(imat, pchan->pose_mat);
@@ -527,8 +552,15 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest)
for(a=0, fp= data[0]; asegments; a++, fp+=4) {
VecSubf(h1, fp+4, fp);
vec_roll_to_mat3(h1, fp[3], mat3); // fp[3] is roll
+
Mat4CpyMat3(result_array[a].mat, mat3);
VECCOPY(result_array[a].mat[3], fp);
+
+ if(doscale) {
+ /* correct for scaling when this matrix is used in scaled space */
+ Mat4MulSerie(result_array[a].mat, iscalemat, result_array[a].mat,
+ scalemat, NULL, NULL, NULL, NULL, NULL);
+ }
}
return result_array;
@@ -849,7 +881,7 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
for(i = 0; i < numVerts; i++) {
MDeformVert *dvert;
DualQuat sumdq, *dq = NULL;
- float *co = vertexCos[i];
+ float *co = vertexCos[i], dco[3];
float sumvec[3], summat[3][3];
float *vec = NULL, (*smat)[3] = NULL;
float contrib = 0.0f;
@@ -938,7 +970,17 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm,
if(contrib > 0.0001f) {
if(use_quaternion) {
DQuatNormalize(dq, contrib, armature_weight);
- DQuatMulVecfl(dq, co, (defMats)? summat: NULL);
+
+ if(armature_weight != 1.0f) {
+ VECCOPY(dco, co);
+ DQuatMulVecfl(dq, dco, (defMats)? summat: NULL);
+ VecSubf(dco, dco, co);
+ VecMulf(dco, armature_weight);
+ VecAddf(co, co, dco);
+ }
+ else
+ DQuatMulVecfl(dq, co, (defMats)? summat: NULL);
+
smat = summat;
}
else {
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index d70cd683237..49d3021090e 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -757,9 +757,9 @@ int material_in_material(Material *parmat, Material *mat)
/* ****************** */
char colname_array[125][20]= {
-"Black","DarkRed","HalveRed","Red","Red",
+"Black","DarkRed","HalfRed","Red","Red",
"DarkGreen","DarkOlive","Brown","Chocolate","OrangeRed",
-"HalveGreen","GreenOlive","DryOlive","Goldenrod","DarkOrange",
+"HalfGreen","GreenOlive","DryOlive","Goldenrod","DarkOrange",
"LightGreen","Chartreuse","YellowGreen","Yellow","Gold",
"Green","LawnGreen","GreenYellow","LightOlive","Yellow",
"DarkBlue","DarkPurple","HotPink","VioletPink","RedPink",
@@ -767,7 +767,7 @@ char colname_array[125][20]= {
"SeaGreen","PaleGreen","GreenKhaki","LightBrown","LightSalmon",
"SpringGreen","PaleGreen","MediumOlive","YellowBrown","LightGold",
"LightGreen","LightGreen","LightGreen","GreenYellow","PaleYellow",
-"HalveBlue","DarkSky","HalveMagenta","VioletRed","DeepPink",
+"HalfBlue","DarkSky","HalfMagenta","VioletRed","DeepPink",
"SteelBlue","SkyBlue","Orchid","LightHotPink","HotPink",
"SeaGreen","SlateGray","MediumGrey","Burlywood","LightPink",
"SpringGreen","Aquamarine","PaleGreen","Khaki","PaleOrange",
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 22692f503e1..531cd78b3b2 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -5310,7 +5310,28 @@ static void meshdeformModifier_do(
}
/* do deformation */
+ fac= 1.0f;
+
for(b=0; bflag & MOD_MDEF_INVERT_VGROUP) {
+ if(!dw) fac= 1.0f;
+ else if(dw->weight == 0.0f) continue;
+ else fac=1.0f-dw->weight;
+ }
+ else {
+ if(!dw) continue;
+ else fac= dw->weight;
+ }
+ }
+
totweight= 0.0f;
co[0]= co[1]= co[2]= 0.0f;
@@ -5323,20 +5344,6 @@ static void meshdeformModifier_do(
}
if(totweight > 0.0f) {
- if(dvert) {
- for(dw=NULL, a=0; aweight;
- }
- else
- fac= 1.0f;
-
VecMulf(co, fac/totweight);
Mat3MulVecfl(icmat, co);
VECADD(vertexCos[b], vertexCos[b], co);
@@ -5354,15 +5361,15 @@ static void meshdeformModifier_deformVerts(
{
DerivedMesh *dm;
- if(derivedData) dm = CDDM_copy(derivedData);
- else dm = CDDM_from_mesh(ob->data, ob);
-
- CDDM_apply_vert_coords(dm, vertexCos);
- CDDM_calc_normals(dm);
+ if(!derivedData && ob->type==OB_MESH)
+ dm= CDDM_from_mesh(ob->data, ob);
+ else
+ dm= derivedData;
meshdeformModifier_do(md, ob, dm, vertexCos, numVerts);
- dm->release(dm);
+ if(dm != derivedData)
+ dm->release(dm);
}
static void meshdeformModifier_deformVertsEM(
@@ -5371,15 +5378,15 @@ static void meshdeformModifier_deformVertsEM(
{
DerivedMesh *dm;
- if(derivedData) dm = CDDM_copy(derivedData);
- else dm = CDDM_from_editmesh(editData, ob->data);
-
- CDDM_apply_vert_coords(dm, vertexCos);
- CDDM_calc_normals(dm);
+ if(!derivedData && ob->type == OB_MESH)
+ dm = CDDM_from_editmesh(editData, ob->data);
+ else
+ dm = derivedData;
meshdeformModifier_do(md, ob, dm, vertexCos, numVerts);
- dm->release(dm);
+ if(dm != derivedData)
+ dm->release(dm);
}
diff --git a/source/blender/include/BIF_transform.h b/source/blender/include/BIF_transform.h
index eeb465135de..26900b06c52 100644
--- a/source/blender/include/BIF_transform.h
+++ b/source/blender/include/BIF_transform.h
@@ -58,6 +58,7 @@
#define TFM_TIME_TRANSLATE 19
#define TFM_TIME_SLIDE 20
#define TFM_TIME_SCALE 21
+#define TFM_TIME_EXTEND 22
/* TRANSFORM CONTEXTS */
#define CTX_NONE 0
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 151e652eef0..ea7e67ddac4 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -374,6 +374,8 @@ typedef struct BooleanModifierData {
int operation, pad;
} BooleanModifierData;
+#define MOD_MDEF_INVERT_VGROUP (1<<0)
+
typedef struct MeshDeformModifierData {
ModifierData modifier;
@@ -382,7 +384,7 @@ typedef struct MeshDeformModifierData {
float *bindweights, *bindcos; /* computed binding weights */
short gridsize, needbind;
- int pad;
+ short flag, pad;
int totvert, totcagevert;
} MeshDeformModifierData;
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index 3da0196cc46..3f08c7d5ff9 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -1497,8 +1497,13 @@ static void modifiers_bindMeshDeform(void *ob_v, void *md_v)
mmd->needbind= 1;
mmd->modifier.mode |= eModifierMode_Realtime;
- dm= mesh_create_derived_view(ob, 0);
- dm->release(dm);
+ if(ob->type == OB_MESH) {
+ dm= mesh_create_derived_view(ob, 0);
+ dm->release(dm);
+ }
+ else if(ob->type == OB_LATTICE) {
+ lattice_calc_modifiers(ob);
+ }
mmd->needbind= 0;
mmd->modifier.mode= mode;
@@ -2141,8 +2146,9 @@ static void draw_modifier(uiBlock *block, Object *ob, ModifierData *md, int *xco
uiBlockBeginAlign(block);
uiDefIDPoinBut(block, test_meshobpoin_but, ID_OB, B_CHANGEDEP, "Ob: ", lx, (cy-=19), buttonWidth,19, &mmd->object, "Mesh object to be use as cage");
- but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-=19), buttonWidth,19, &mmd->defgrp_name, 0.0, 31.0, 0, 0, "Vertex Group name to control overall meshdeform influence");
+ but=uiDefBut(block, TEX, B_MODIFIER_RECALC, "VGroup: ", lx, (cy-19), buttonWidth-40,19, &mmd->defgrp_name, 0.0, 31.0, 0, 0, "Vertex Group name to control overall meshdeform influence");
uiButSetCompleteFunc(but, autocomplete_vgroup, (void *)ob);
+ uiDefButBitS(block, TOG, MOD_MDEF_INVERT_VGROUP, B_MODIFIER_RECALC, "Inv", lx+buttonWidth-40, (cy-=19), 40,19, &mmd->flag, 0.0, 31.0, 0, 0, "Invert vertex group influence");
uiBlockBeginAlign(block);
if(mmd->bindweights) {
diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c
index 3957b107814..48a39875cc2 100644
--- a/source/blender/src/editaction.c
+++ b/source/blender/src/editaction.c
@@ -739,6 +739,12 @@ void transform_action_keys (int mode, int dummy)
Transform();
}
break;
+ case 'e':
+ {
+ initTransform(TFM_TIME_EXTEND, CTX_NONE);
+ Transform();
+ }
+ break;
}
}
@@ -2645,7 +2651,12 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
duplicate_action_keys();
}
break;
-
+
+ case EKEY:
+ if (mval[0] >= ACTWIDTH)
+ transform_action_keys('e', 0);
+ break;
+
case GKEY:
if (G.qual & LR_CTRLKEY) {
transform_markers('g', 0);
diff --git a/source/blender/src/editnla.c b/source/blender/src/editnla.c
index 13423424f90..ec3b1c834e5 100644
--- a/source/blender/src/editnla.c
+++ b/source/blender/src/editnla.c
@@ -995,6 +995,12 @@ void transform_nlachannel_keys(int mode, int dummy)
Transform();
}
break;
+ case 'e':
+ {
+ initTransform(TFM_TIME_EXTEND, CTX_NONE);
+ Transform();
+ }
+ break;
}
}
@@ -1791,6 +1797,13 @@ void winqreadnlaspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
+ case EKEY:
+ if (mval[0] >= NLAWIDTH) {
+ transform_nlachannel_keys ('e', 0);
+ update_for_newframe_muted();
+ }
+ break;
+
case GKEY:
if (mval[0]>=NLAWIDTH) {
if (G.qual & LR_CTRLKEY) {
diff --git a/source/blender/src/editseq.c b/source/blender/src/editseq.c
index fafb5081ef0..eed3145284c 100644
--- a/source/blender/src/editseq.c
+++ b/source/blender/src/editseq.c
@@ -2956,13 +2956,13 @@ void transform_seq(int mode, int context)
}
/* check seq's next to the active also - nice for quick snapping */
- if (snap_dist && seq_tx_check_left(last_seq)) {
+ if (snap_dist && last_seq && seq_tx_check_left(last_seq)) {
seq = find_next_prev_sequence(last_seq, 1, 0); /* left */
if(seq && !seq_tx_check_right(seq))
TESTSNAP(seq_tx_get_final_right(seq));
}
- if (snap_dist && seq_tx_check_right(last_seq)) {
+ if (snap_dist && last_seq && seq_tx_check_right(last_seq)) {
seq = find_next_prev_sequence(last_seq, 2, 0); /* right */
if(seq && !seq_tx_check_left(seq))
TESTSNAP(seq_tx_get_final_left(seq));
diff --git a/source/blender/src/header_action.c b/source/blender/src/header_action.c
index c6d1b88c95c..4a803926a94 100644
--- a/source/blender/src/header_action.c
+++ b/source/blender/src/header_action.c
@@ -114,7 +114,6 @@ enum {
enum {
ACTMENU_KEY_DUPLICATE = 0,
ACTMENU_KEY_DELETE,
- ACTMENU_KEY_BAKE,
ACTMENU_KEY_CLEAN
};
@@ -128,7 +127,8 @@ enum {
enum {
ACTMENU_KEY_TRANSFORM_MOVE = 0,
ACTMENU_KEY_TRANSFORM_SCALE,
- ACTMENU_KEY_TRANSFORM_SLIDE
+ ACTMENU_KEY_TRANSFORM_SLIDE,
+ ACTMENU_KEY_TRANSFORM_EXTEND
};
enum {
@@ -594,6 +594,9 @@ static void do_action_keymenu_transformmenu(void *arg, int event)
case ACTMENU_KEY_TRANSFORM_SLIDE:
transform_action_keys('t', 0);
break;
+ case ACTMENU_KEY_TRANSFORM_EXTEND:
+ transform_action_keys('e', 0);
+ break;
}
scrarea_queue_winredraw(curarea);
@@ -611,6 +614,9 @@ static uiBlock *action_keymenu_transformmenu(void *arg_unused)
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
"Grab/Move|G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0,
ACTMENU_KEY_TRANSFORM_MOVE, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Grab/Extend from Frame|E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_KEY_TRANSFORM_EXTEND, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
"Scale|S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0,
ACTMENU_KEY_TRANSFORM_SCALE, "");
diff --git a/source/blender/src/header_nla.c b/source/blender/src/header_nla.c
index 3a3d3dfdb49..96ea6c3d792 100644
--- a/source/blender/src/header_nla.c
+++ b/source/blender/src/header_nla.c
@@ -269,12 +269,16 @@ static void do_nla_strip_transformmenu(void *arg, int event)
{
switch(event) {
case 0: /* grab/move */
- transform_nlachannel_keys ('g', 0);
- update_for_newframe_muted();
+ transform_nlachannel_keys('g', 0);
+ update_for_newframe_muted();
break;
case 1: /* scale */
- transform_nlachannel_keys ('s', 0);
- update_for_newframe_muted();
+ transform_nlachannel_keys('s', 0);
+ update_for_newframe_muted();
+ break;
+ case 2: /* extend */
+ transform_nlachannel_keys('e', 0);
+ update_for_newframe_muted();
break;
}
allqueue(REDRAWVIEW3D, 0);
@@ -289,8 +293,10 @@ static uiBlock *nla_strip_transformmenu(void *arg_unused)
uiBlockSetButmFunc(block, do_nla_strip_transformmenu, NULL);
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Move|G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Grab/Extend from Frame|E", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Scale|S", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
-
+
+
uiBlockSetDirection(block, UI_RIGHT);
uiTextBoundsBlock(block, 60);
return block;
diff --git a/source/blender/src/transform.c b/source/blender/src/transform.c
index 321a56c5ebd..2a7f744f219 100644
--- a/source/blender/src/transform.c
+++ b/source/blender/src/transform.c
@@ -938,6 +938,7 @@ void initTransform(int mode, int context) {
/* EVIL! posemode code can switch translation to rotate when 1 bone is selected. will be removed (ton) */
/* EVIL2: we gave as argument also texture space context bit... was cleared */
+ /* EVIL3: extend mode for animation editors also switches modes... but is best way to avoid duplicate code */
mode = Trans.mode;
calculatePropRatio(&Trans);
@@ -1004,6 +1005,10 @@ void initTransform(int mode, int context) {
case TFM_TIME_SCALE:
initTimeScale(&Trans);
break;
+ case TFM_TIME_EXTEND:
+ /* now that transdata has been made, do like for TFM_TIME_TRANSLATE */
+ initTimeTranslate(&Trans);
+ break;
}
}
diff --git a/source/blender/src/transform_conversions.c b/source/blender/src/transform_conversions.c
index c53c3d851a8..b599270b5f0 100644
--- a/source/blender/src/transform_conversions.c
+++ b/source/blender/src/transform_conversions.c
@@ -114,6 +114,7 @@
#include "BIF_toolbox.h"
#include "BSE_view.h"
+#include "BSE_drawipo.h"
#include "BSE_edit.h"
#include "BSE_editipo.h"
#include "BSE_editipo_types.h"
@@ -2050,7 +2051,48 @@ void flushTransIpoData(TransInfo *t)
/* ********************* ACTION/NLA EDITOR ****************** */
+/* This function tests if a point is on the "mouse" side of the cursor/frame-marking */
+static short FrameOnMouseSide(char side, float frame, float cframe)
+{
+ /* both sides, so it doesn't matter */
+ if (side == 'B') return 1;
+
+ /* only on the named side */
+ if (side == 'R')
+ return (frame >= cframe) ? 1 : 0;
+ else
+ return (frame <= cframe) ? 1 : 0;
+}
+/* fully select selected beztriples, but only include if it's on the right side of cfra */
+static int count_ipo_keys(Ipo *ipo, char side, float cfra)
+{
+ IpoCurve *icu;
+ BezTriple *bezt;
+ int i, count = 0;
+
+ if (ipo == NULL)
+ return count;
+
+ /* only include points that occur on the right side of cfra */
+ for (icu= ipo->curve.first; icu; icu= icu->next) {
+ for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
+ if (bezt->f2) {
+ /* fully select the other two keys */
+ bezt->f1 |= 1;
+ bezt->f3 |= 1;
+
+ /* increment by 3, as there are 3 points (3 * x-coordinates) that need transform */
+ if (FrameOnMouseSide(side, bezt->vec[1][0], cfra))
+ count += 3;
+ }
+ }
+ }
+
+ return count;
+}
+
+/* This function assigns the information to transdata */
static void TimeToTransData(TransData *td, float *time, Object *ob)
{
/* memory is calloc'ed, so that should zero everything nicely for us */
@@ -2066,9 +2108,12 @@ static void TimeToTransData(TransData *td, float *time, Object *ob)
/* This function advances the address to which td points to, so it must return
* the new address so that the next time new transform data is added, it doesn't
- * overwrite the existing ones... i.e. td = IpoToTransData(td, ipo, ob);
+ * overwrite the existing ones... i.e. td = IpoToTransData(td, ipo, ob, side, cfra);
+ *
+ * The 'side' argument is needed for the extend mode. 'B' = both sides, 'R'/'L' mean only data
+ * on the named side are used.
*/
-static TransData *IpoToTransData(TransData *td, Ipo *ipo, Object *ob)
+static TransData *IpoToTransData(TransData *td, Ipo *ipo, Object *ob, char side, float cfra)
{
IpoCurve *icu;
BezTriple *bezt;
@@ -2078,18 +2123,21 @@ static TransData *IpoToTransData(TransData *td, Ipo *ipo, Object *ob)
return td;
for (icu= ipo->curve.first; icu; icu= icu->next) {
- /* only add selected keyframes (for now, proportional edit is not enabled) */
for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
+ /* only add selected keyframes (for now, proportional edit is not enabled) */
if (BEZSELECTED(bezt)) {
- /* each control point needs to be added separetely */
- TimeToTransData(td, bezt->vec[0], ob);
- td++;
-
- TimeToTransData(td, bezt->vec[1], ob);
- td++;
-
- TimeToTransData(td, bezt->vec[2], ob);
- td++;
+ /* only add if on the right 'side' of the current frame */
+ if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) {
+ /* each control point needs to be added separetely */
+ TimeToTransData(td, bezt->vec[0], ob);
+ td++;
+
+ TimeToTransData(td, bezt->vec[1], ob);
+ td++;
+
+ TimeToTransData(td, bezt->vec[2], ob);
+ td++;
+ }
}
}
}
@@ -2109,6 +2157,8 @@ static void createTransActionData(TransInfo *t)
int filter;
int count=0;
+ float cfra;
+ char side;
/* determine what type of data we are operating on */
data = get_action_context(&datatype);
@@ -2121,10 +2171,31 @@ static void createTransActionData(TransInfo *t)
/* is the action scaled? if so, the it should belong to the active object */
if (NLA_ACTION_SCALED)
ob= OBACT;
+
+ /* which side of the current frame should be allowed */
+ if (t->mode == TFM_TIME_EXTEND) {
+ /* only side on which mouse is gets transformed */
+ float xmouse, ymouse;
+
+ areamouseco_to_ipoco(G.v2d, t->imval, &xmouse, &ymouse);
+ side = (xmouse > CFRA) ? 'R' : 'L';
+ }
+ else {
+ /* normal transform - both sides of current frame are considered */
+ side = 'B';
+ }
+
+ /* convert current-frame to action-time (slightly less accurate, espcially under
+ * higher scaling ratios, but is faster than converting all points)
+ */
+ if (ob)
+ cfra = get_action_frame(ob, CFRA);
+ else
+ cfra = CFRA;
/* loop 1: fully select ipo-keys and count how many BezTriples are selected */
for (ale= act_data.first; ale; ale= ale->next)
- count += fullselect_ipo_keys(ale->key_data);
+ count += count_ipo_keys(ale->key_data, side, cfra);
/* stop if trying to build list if nothing selected */
if (count == 0) {
@@ -2144,7 +2215,7 @@ static void createTransActionData(TransInfo *t)
for (ale= act_data.first; ale; ale= ale->next) {
Ipo *ipo= (Ipo *)ale->key_data;
- td= IpoToTransData(td, ipo, ob);
+ td= IpoToTransData(td, ipo, ob, side, cfra);
}
/* check if we're supposed to be setting minx/maxx for TimeSlide */
@@ -2179,17 +2250,32 @@ static void createTransNlaData(TransInfo *t)
TransData *td = NULL;
int count=0, i;
+ float cfra;
+ char side;
+
+ /* which side of the current frame should be allowed */
+ if (t->mode == TFM_TIME_EXTEND) {
+ /* only side on which mouse is gets transformed */
+ float xmouse, ymouse;
+
+ areamouseco_to_ipoco(G.v2d, t->imval, &xmouse, &ymouse);
+ side = (xmouse > CFRA) ? 'R' : 'L';
+ }
+ else {
+ /* normal transform - both sides of current frame are considered */
+ side = 'B';
+ }
/* Ensure that partial selections result in beztriple selections */
for (base=G.scene->base.first; base; base=base->next) {
/* Check object ipos */
- i= fullselect_ipo_keys(base->object->ipo);
+ i= count_ipo_keys(base->object->ipo, side, CFRA);
if (i) base->flag |= BA_HAS_RECALC_OB;
count += i;
/* Check object constraint ipos */
for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next)
- count += fullselect_ipo_keys(conchan->ipo);
+ count += count_ipo_keys(conchan->ipo, side, CFRA);
/* skip actions and nlastrips if object is collapsed */
if (base->object->nlaflag & OB_NLA_COLLAPSED)
@@ -2204,9 +2290,11 @@ static void createTransNlaData(TransInfo *t)
break;
}
if (strip==NULL) {
+ cfra = get_action_frame(base->object, CFRA);
+
for (achan=base->object->action->chanbase.first; achan; achan=achan->next) {
if (EDITABLE_ACHAN(achan)) {
- i= fullselect_ipo_keys(achan->ipo);
+ i= count_ipo_keys(achan->ipo, side, cfra);
if (i) base->flag |= BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA;
count += i;
@@ -2214,7 +2302,7 @@ static void createTransNlaData(TransInfo *t)
if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
if (EDITABLE_CONCHAN(conchan))
- count += fullselect_ipo_keys(conchan->ipo);
+ count += count_ipo_keys(conchan->ipo, side, cfra);
}
}
}
@@ -2226,7 +2314,9 @@ static void createTransNlaData(TransInfo *t)
for (strip=base->object->nlastrips.first; strip; strip=strip->next) {
if (strip->flag & ACTSTRIP_SELECT) {
base->flag |= BA_HAS_RECALC_OB|BA_HAS_RECALC_DATA;
- count += 2;
+
+ if (FrameOnMouseSide(side, strip->start, CFRA)) count++;
+ if (FrameOnMouseSide(side, strip->end, CFRA)) count++;
}
}
}
@@ -2244,12 +2334,12 @@ static void createTransNlaData(TransInfo *t)
for (base=G.scene->base.first; base; base=base->next) {
/* Manipulate object ipos */
/* - no scaling of keyframe times is allowed here */
- td= IpoToTransData(td, base->object->ipo, NULL);
+ td= IpoToTransData(td, base->object->ipo, NULL, side, CFRA);
/* Manipulate object constraint ipos */
/* - no scaling of keyframe times is allowed here */
for (conchan=base->object->constraintChannels.first; conchan; conchan=conchan->next)
- td= IpoToTransData(td, conchan->ipo, NULL);
+ td= IpoToTransData(td, conchan->ipo, NULL, side, CFRA);
/* skip actions and nlastrips if object collapsed */
if (base->object->nlaflag & OB_NLA_COLLAPSED)
@@ -2266,15 +2356,17 @@ static void createTransNlaData(TransInfo *t)
/* can include if no strip found */
if (strip==NULL) {
+ cfra = get_action_frame(base->object, CFRA);
+
for (achan=base->object->action->chanbase.first; achan; achan=achan->next) {
if (EDITABLE_ACHAN(achan)) {
- td= IpoToTransData(td, achan->ipo, base->object);
+ td= IpoToTransData(td, achan->ipo, base->object, side, cfra);
/* Manipulate action constraint ipos */
if (EXPANDED_ACHAN(achan) && FILTER_CON_ACHAN(achan)) {
for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
if (EDITABLE_CONCHAN(conchan))
- td= IpoToTransData(td, conchan->ipo, base->object);
+ td= IpoToTransData(td, conchan->ipo, base->object, side, cfra);
}
}
}
@@ -2286,13 +2378,16 @@ static void createTransNlaData(TransInfo *t)
for (strip=base->object->nlastrips.first; strip; strip=strip->next) {
if (strip->flag & ACTSTRIP_SELECT) {
/* first TransData is the start, second is the end */
- td->val = &strip->start;
- td->ival = strip->start;
- td++;
-
- td->val = &strip->end;
- td->ival = strip->end;
- td++;
+ if (FrameOnMouseSide(side, strip->start, CFRA)) {
+ td->val = &strip->start;
+ td->ival = strip->start;
+ td++;
+ }
+ if (FrameOnMouseSide(side, strip->end, CFRA)) {
+ td->val = &strip->end;
+ td->ival = strip->end;
+ td++;
+ }
}
}
}
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp
index c8ed2dd6960..26b00f02e7d 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_GLExtensionManager.cpp
@@ -108,7 +108,7 @@ static OSStatus bglInitEntryPoints (void)
// Frameworks directory/folder
err = FindFolder (kSystemDomain, kFrameworksFolderType, false,
- &fileRefParam.ioVRefNum, &fileRefParam.ioDirID);
+ &fileRefParam.ioVRefNum, (SInt32*)&fileRefParam.ioDirID);
if (noErr != err) {
DebugStr ((unsigned char *)"\pCould not find frameworks folder");
return err;