Transform project. Daily update:

- Pose Mode restored
- Dependencies work again as usual (mainly copied old code)
  so grabbing a Hook deforms, etc
- Made main transform loop idling nicely (save CPU)
- removed proportional mode for Objects (Martin OK'ed)
- code style: renamed "tv" into "td" variable names (trans-data now)

TODO:
- Ipo Key-mode editing
- texture space grab/scale
- correct inverse for scaling children offset
- actually, loadsa testing needed. :)
This commit is contained in:
2005-02-22 16:50:04 +00:00
parent 3cd546e484
commit 118e4bcf7b
5 changed files with 507 additions and 261 deletions

View File

@@ -33,7 +33,7 @@
#ifndef BIF_TRANSFORM_H
#define BIF_TRANSFORM_H
//#define NEWTRANSFORM 1
// #define NEWTRANSFORM 1
/* ******************** Macros & Prototypes *********************** */

View File

@@ -254,6 +254,7 @@ void helpline(float *vec)
VECCOPY(vecrot, vec);
if(G.obedit) Mat4MulVecfl(G.obedit->obmat, vecrot);
else if(G.obpose) Mat4MulVecfl(G.obpose->obmat, vecrot);
getmouseco_areawin(mval);
project_float(vecrot, cent); // no overflow in extreme cases

View File

@@ -83,19 +83,26 @@
#include "BIF_space.h"
#include "BIF_toolbox.h"
#include "BKE_global.h"
#include "BKE_object.h"
#include "BKE_utildefines.h"
#include "BKE_lattice.h"
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_curve.h"
#include "BKE_displist.h"
#include "BKE_effect.h"
#include "BKE_global.h"
#include "BKE_lattice.h"
#include "BKE_mball.h"
#include "BKE_object.h"
#include "BKE_utildefines.h"
#include "BSE_view.h"
#include "BSE_edit.h"
#include "BDR_editobject.h" // reset_slowparents()
#include "BLI_arithb.h"
#include "BLI_editVert.h"
#include "BLI_ghash.h"
#include "PIL_time.h"
#include "blendef.h"
@@ -140,69 +147,81 @@ static int allocTransData(void)
/* ********************* pose mode ************* */
/* callback */
static int test_bone_select(Object *ob, Bone *bone, void *ptr)
/* callback, make sure it's identical structured as next one */
static void count_bone_select(ListBase *lb, int *counter)
{
if (bone->flag & BONE_SELECTED) return 1;
return 0;
Bone *bone;
for(bone= lb->first; bone; bone= bone->next) {
if (bone->flag & BONE_SELECTED) {
/* We don't let IK children get "grabbed" */
/* ALERT! abusive global Trans here */
if ( (Trans.mode!=TFM_TRANSLATION) || (bone->flag & BONE_IK_TOPARENT)==0 ) {
(*counter)++;
return; // no transform on children if one parent bone is selected
}
}
count_bone_select( &bone->childbase, counter);
}
}
/* callback */
static int add_pose_transdata(Object *ob, Bone *bone, void *ptr)
static void add_pose_transdata(ListBase *lb, Object *ob, TransData **tdp)
{
TransData **tvp= ptr;
TransData *tv= *tvp;
Bone *bone;
TransData *td= *tdp;
float parmat[4][4], tempmat[4][4];
float tempobmat[4][4], smtx[3][3];
float tempobmat[4][4];
float vec[3];
if (bone->flag & BONE_SELECTED){
for(bone= lb->first; bone; bone= bone->next) {
if (bone->flag & BONE_SELECTED) {
/* We don't let IK children get "grabbed" */
/* ALERT! abusive global Trans here */
if ( (Trans.mode!=TFM_TRANSLATION) || (bone->flag & BONE_IK_TOPARENT)==0 ) {
/* We don't let IK children get "grabbed" */
/* if (!((mode=='g' || mode=='G') && (bone->flag & BONE_IK_TOPARENT))){ */
// commented out, no idea what it means (ton)
get_bone_root_pos (bone, vec, 1);
get_bone_root_pos (bone, vec, 1);
//VecAddf (centroid, centroid, vec);
VECCOPY(td->center, vec);
//VecAddf (centroid, centroid, vec);
td->ob = ob;
td->bone= bone; // FIXME: Dangerous
tv->ob = ob;
tv->bone= bone; // FIXME: Dangerous
td->loc = bone->loc;
td->rot= NULL;
td->quat= bone->quat;
td->size= bone->size;
td->dist= 0.0f;
td->flag= TD_SELECTED|TD_USEQUAT;
tv->loc = bone->loc;
tv->rot= NULL;
tv->quat= bone->quat;
tv->size= bone->size;
tv->dist= 0.0f;
memcpy (td->iquat, bone->quat, sizeof (bone->quat));
memcpy (td->isize, bone->size, sizeof (bone->size));
memcpy (td->iloc, bone->loc, sizeof (bone->loc));
memcpy (tv->iquat, bone->quat, sizeof (bone->quat));
memcpy (tv->isize, bone->size, sizeof (bone->size));
memcpy (tv->iloc, bone->loc, sizeof (bone->loc));
/* Get the matrix of this bone minus the usertransform */
Mat4CpyMat4 (tempobmat, bone->obmat);
Mat4One (bone->obmat);
get_objectspace_bone_matrix(bone, tempmat, 1, 1);
Mat4CpyMat4 (bone->obmat, tempobmat);
printf("init loc %f %f %f\n", tv->iloc[0], tv->iloc[1], tv->iloc[2]);
Mat4MulMat4 (parmat, tempmat, ob->obmat); /* Original */
/* Get the matrix of this bone minus the usertransform */
Mat4CpyMat4 (tempobmat, bone->obmat);
Mat4One (bone->obmat);
get_objectspace_bone_matrix(bone, tempmat, 1, 1);
Mat4CpyMat4 (bone->obmat, tempobmat);
Mat3CpyMat4 (td->mtx, parmat);
Mat3Inv (td->smtx, td->mtx);
Mat4MulMat4 (parmat, tempmat, ob->obmat); /* Original */
Mat3CpyMat4 (smtx, parmat);
Mat3Inv (tv->smtx, smtx);
Mat3CpyMat4 (tv->mtx, bone->obmat);
(*tvp)++;
(*tdp)++;
return; // see above function
}
}
add_pose_transdata(&bone->childbase, ob, tdp);
}
return 0;
}
static void createTransPoseVerts(void)
static void createTransPose(void)
{
bArmature *arm;
TransData *tv;
TransData *td;
float mtx[3][3], smtx[3][3];
Trans.total= 0; // to be able to return
@@ -232,26 +251,31 @@ static void createTransPoseVerts(void)
where_is_armature (G.obpose);
/* count total */
Trans.total= bone_looper(G.obpose, arm->bonebase.first, NULL, test_bone_select);
count_bone_select(&arm->bonebase, &Trans.total);
if(Trans.total==0 && Trans.mode==TFM_TRANSLATION) {
Trans.mode= TFM_ROTATION;
count_bone_select(&arm->bonebase, &Trans.total);
}
if(Trans.total==0) return;
/* init trans data */
Mat3CpyMat4(mtx, G.obpose->obmat);
Mat3Inv(smtx, mtx);
tv = Trans.data = MEM_mallocN(Trans.total*sizeof(TransData), "TransPoseBone");
td = Trans.data = MEM_mallocN(Trans.total*sizeof(TransData), "TransPoseBone");
Mat3CpyMat4(mtx, G.obpose->obmat);
Mat3Inv(smtx, mtx);
bone_looper(G.obpose, arm->bonebase.first, &tv, add_pose_transdata);
add_pose_transdata(&arm->bonebase, G.obpose, &td);
}
static void createTransArmatureVerts(void)
{
EditBone *ebo;
TransData *tv;
TransData *td;
float mtx[3][3], smtx[3][3];
Trans.total = 0;
@@ -269,38 +293,38 @@ static void createTransArmatureVerts(void)
Mat3CpyMat4(mtx, G.obedit->obmat);
Mat3Inv(smtx, mtx);
tv = Trans.data = MEM_mallocN(Trans.total*sizeof(TransData), "TransEditBone");
td = Trans.data = MEM_mallocN(Trans.total*sizeof(TransData), "TransEditBone");
for (ebo=G.edbo.first;ebo;ebo=ebo->next){
if (ebo->flag & BONE_TIPSEL){
VECCOPY (tv->iloc, ebo->tail);
tv->loc= ebo->tail;
tv->flag= TD_SELECTED;
VECCOPY (td->iloc, ebo->tail);
td->loc= ebo->tail;
td->flag= TD_SELECTED;
Mat3CpyMat3(tv->smtx, smtx);
Mat3CpyMat3(tv->mtx, mtx);
Mat3CpyMat3(td->smtx, smtx);
Mat3CpyMat3(td->mtx, mtx);
tv->size = NULL;
tv->rot = NULL;
td->size = NULL;
td->rot = NULL;
tv->dist = 0.0f;
td->dist = 0.0f;
tv++;
td++;
}
if (ebo->flag & BONE_ROOTSEL){
VECCOPY (tv->iloc, ebo->head);
tv->loc= ebo->head;
tv->flag= TD_SELECTED;
VECCOPY (td->iloc, ebo->head);
td->loc= ebo->head;
td->flag= TD_SELECTED;
Mat3CpyMat3(tv->smtx, smtx);
Mat3CpyMat3(tv->mtx, mtx);
Mat3CpyMat3(td->smtx, smtx);
Mat3CpyMat3(td->mtx, mtx);
tv->size = NULL;
tv->rot = NULL;
td->size = NULL;
td->rot = NULL;
tv->dist = 0.0f;
td->dist = 0.0f;
tv++;
td++;
}
}
@@ -309,7 +333,7 @@ static void createTransArmatureVerts(void)
static void createTransMBallVerts(void)
{
MetaElem *ml;
TransData *tv;
TransData *td;
float mtx[3][3], smtx[3][3];
int count;
@@ -319,28 +343,28 @@ static void createTransMBallVerts(void)
Mat3CpyMat4(mtx, G.obedit->obmat);
Mat3Inv(smtx, mtx);
tv = Trans.data;
td = Trans.data;
ml= editelems.first;
while(ml) {
if(ml->flag & SELECT) {
tv->loc= &ml->x;
VECCOPY(tv->iloc, tv->loc);
VECCOPY(tv->center, tv->loc);
tv->flag= TD_SELECTED;
td->loc= &ml->x;
VECCOPY(td->iloc, td->loc);
VECCOPY(td->center, td->loc);
td->flag= TD_SELECTED;
Mat3CpyMat3(tv->smtx, smtx);
Mat3CpyMat3(tv->mtx, mtx);
Mat3CpyMat3(td->smtx, smtx);
Mat3CpyMat3(td->mtx, mtx);
tv->size = &ml->expx;
tv->isize[0] = ml->expx;
tv->isize[1] = ml->expy;
tv->isize[2] = ml->expz;
td->size = &ml->expx;
td->isize[0] = ml->expx;
td->isize[1] = ml->expy;
td->isize[2] = ml->expz;
tv->rot = NULL;
td->rot = NULL;
tv->dist = 0.0f;
td->dist = 0.0f;
tv++;
td++;
}
ml= ml->next;
}
@@ -348,7 +372,7 @@ static void createTransMBallVerts(void)
static void createTransCurveVerts(void)
{
TransData *tv = NULL;
TransData *td = NULL;
Nurb *nu;
BezTriple *bezt;
BPoint *bp;
@@ -364,7 +388,7 @@ static void createTransCurveVerts(void)
Mat3CpyMat4(mtx, G.obedit->obmat);
Mat3Inv(smtx, mtx);
tv = Trans.data;
td = Trans.data;
nu= editNurb.first;
while(nu) {
if((nu->type & 7)==CU_BEZIER) {
@@ -373,51 +397,51 @@ static void createTransCurveVerts(void)
while(a--) {
if(bezt->hide==0) {
if(mode==1 || (bezt->f1 & 1)) {
VECCOPY(tv->iloc, bezt->vec[0]);
tv->loc= bezt->vec[0];
VECCOPY(tv->center, tv->loc);
tv->flag= TD_SELECTED;
tv->rot = NULL;
tv->size = NULL;
VECCOPY(td->iloc, bezt->vec[0]);
td->loc= bezt->vec[0];
VECCOPY(td->center, td->loc);
td->flag= TD_SELECTED;
td->rot = NULL;
td->size = NULL;
Mat3CpyMat3(tv->smtx, smtx);
Mat3CpyMat3(tv->mtx, mtx);
Mat3CpyMat3(td->smtx, smtx);
Mat3CpyMat3(td->mtx, mtx);
tv->dist = 0.0f;
td->dist = 0.0f;
tv++;
td++;
count++;
}
if(mode==1 || (bezt->f2 & 1)) {
VECCOPY(tv->iloc, bezt->vec[1]);
tv->loc= bezt->vec[1];
VECCOPY(tv->center, tv->loc);
tv->flag= TD_SELECTED;
tv->rot = NULL;
tv->size = NULL;
VECCOPY(td->iloc, bezt->vec[1]);
td->loc= bezt->vec[1];
VECCOPY(td->center, td->loc);
td->flag= TD_SELECTED;
td->rot = NULL;
td->size = NULL;
Mat3CpyMat3(tv->smtx, smtx);
Mat3CpyMat3(tv->mtx, mtx);
Mat3CpyMat3(td->smtx, smtx);
Mat3CpyMat3(td->mtx, mtx);
tv->dist = 0.0f;
td->dist = 0.0f;
tv++;
td++;
count++;
}
if(mode==1 || (bezt->f3 & 1)) {
VECCOPY(tv->iloc, bezt->vec[2]);
tv->loc= bezt->vec[2];
VECCOPY(tv->center, tv->loc);
tv->flag= TD_SELECTED;
tv->rot = NULL;
tv->size = NULL;
VECCOPY(td->iloc, bezt->vec[2]);
td->loc= bezt->vec[2];
VECCOPY(td->center, td->loc);
td->flag= TD_SELECTED;
td->rot = NULL;
td->size = NULL;
Mat3CpyMat3(tv->smtx, smtx);
Mat3CpyMat3(tv->mtx, mtx);
Mat3CpyMat3(td->smtx, smtx);
Mat3CpyMat3(td->mtx, mtx);
tv->dist = 0.0f;
td->dist = 0.0f;
tv++;
td++;
count++;
}
}
@@ -430,19 +454,19 @@ static void createTransCurveVerts(void)
while(a--) {
if(bp->hide==0) {
if(mode==1 || (bp->f1 & 1)) {
VECCOPY(tv->iloc, bp->vec);
tv->loc= bp->vec;
VECCOPY(tv->center, tv->loc);
tv->flag= TD_SELECTED;
tv->rot = NULL;
tv->size = NULL;
VECCOPY(td->iloc, bp->vec);
td->loc= bp->vec;
VECCOPY(td->center, td->loc);
td->flag= TD_SELECTED;
td->rot = NULL;
td->size = NULL;
Mat3CpyMat3(tv->smtx, smtx);
Mat3CpyMat3(tv->mtx, mtx);
Mat3CpyMat3(td->smtx, smtx);
Mat3CpyMat3(td->mtx, mtx);
tv->dist = 0.0f;
td->dist = 0.0f;
tv++;
td++;
count++;
}
}
@@ -455,7 +479,7 @@ static void createTransCurveVerts(void)
static void createTransLatticeVerts(void)
{
TransData *tv = NULL;
TransData *td = NULL;
int count = 0;
BPoint *bp;
float mtx[3][3], smtx[3][3];
@@ -474,26 +498,26 @@ static void createTransLatticeVerts(void)
Mat3CpyMat4(mtx, G.obedit->obmat);
Mat3Inv(smtx, mtx);
tv = Trans.data;
td = Trans.data;
bp= editLatt->def;
a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
while(a--) {
if(mode==1 || (bp->f1 & 1)) {
if(bp->hide==0) {
VECCOPY(tv->iloc, bp->vec);
tv->loc= bp->vec;
VECCOPY(tv->center, tv->loc);
tv->flag= TD_SELECTED;
VECCOPY(td->iloc, bp->vec);
td->loc= bp->vec;
VECCOPY(td->center, td->loc);
td->flag= TD_SELECTED;
Mat3CpyMat3(tv->smtx, smtx);
Mat3CpyMat3(tv->mtx, mtx);
Mat3CpyMat3(td->smtx, smtx);
Mat3CpyMat3(td->mtx, mtx);
tv->size = NULL;
tv->rot = NULL;
td->size = NULL;
td->rot = NULL;
tv->dist = 0.0f;
td->dist = 0.0f;
tv++;
td++;
count++;
}
}
@@ -628,6 +652,8 @@ static void createTransEditVerts(void)
}
}
/* *************************** Object Transform data ******************* */
static void ObjectToTransData(TransData *tob, Object *ob)
{
float totmat[3][3], obinv[3][3], obmtx[3][3];
@@ -670,36 +696,192 @@ static void ObjectToTransData(TransData *tob, Object *ob)
Mat3MulMat3(tob->smtx, obmtx, obinv);
}
/* only used in function below, stuff to be removed */
static Object *is_a_parent_selected_int(Object *startob, Object *ob, GHash *done_hash)
{
if (ob!=startob && TESTBASE(ob))
return ob;
if (BLI_ghash_haskey(done_hash, ob))
return NULL;
else
BLI_ghash_insert(done_hash, ob, NULL);
if (ob->parent) {
Object *par= is_a_parent_selected_int(startob, ob->parent, done_hash);
if (par)
return par;
}
return NULL;
}
/* only used in function below, stuff to be removed */
static Object *is_a_parent_selected(Object *ob)
{
GHash *gh= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
Object *res= is_a_parent_selected_int(ob, ob, gh);
BLI_ghash_free(gh, NULL, NULL);
return res;
}
/* sets flags in Bases to define whether they take part in transform */
/* it deselects Bases, so we have to call the clear function always after */
static void set_trans_object_base_flags(TransInfo *t)
{
/*
if Base selected and has parent selected:
base->flag= BA_WASSEL+BA_PARSEL
if base not selected and parent selected:
base->flag= BA_PARSEL
*/
GHash *object_to_base_hash= NULL;
Base *base;
/* moved to start of function, it is needed for hooks now too */
if (!object_to_base_hash) {
Base *b;
object_to_base_hash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
for (b= FIRSTBASE; b; b= b->next)
BLI_ghash_insert(object_to_base_hash, b->object, b);
}
/* makes sure base flags and object flags are identical */
copy_baseflags();
for (base= FIRSTBASE; base; base= base->next) {
base->flag &= ~(BA_PARSEL+BA_WASSEL);
if( (base->lay & G.vd->lay) && base->object->id.lib==0) {
Object *ob= base->object;
Object *parsel= is_a_parent_selected(ob);
/* parentkey here? */
if(parsel) {
if(base->flag & SELECT) {
base->flag &= ~SELECT;
base->flag |= (BA_PARSEL+BA_WASSEL);
}
else base->flag |= BA_PARSEL;
}
if(t->mode==TFM_TRANSLATION) {
if(ob->track && TESTBASE(ob->track) && (base->flag & SELECT)==0)
base->flag |= BA_PARSEL;
}
/* updates? */
if(ob->hooks.first) {
Base *b;
ObHook *hook= ob->hooks.first;
while(hook) {
if(hook->parent) {
Object *parsel= is_a_parent_selected(hook->parent);
b= BLI_ghash_lookup(object_to_base_hash, hook->parent);
if(parsel || ((base->flag | b->flag) & (SELECT | BA_PARSEL)) ) {
base->flag |= BA_DISP_UPDATE;
}
}
hook= hook->next;
}
}
if(ob->parent && ob->parent->type==OB_LATTICE)
if(ob->parent->hooks.first) base->flag |= BA_DISP_UPDATE;
if(base->flag & (SELECT | BA_PARSEL)) {
base->flag |= BA_WHERE_UPDATE;
if(ob->parent) {
if(ob->parent->type==OB_LATTICE) base->flag |= BA_DISP_UPDATE;
else if(ob->partype==PARSKEL) {
if ELEM3(ob->parent->type, OB_IKA, OB_CURVE, OB_ARMATURE)
base->flag |= BA_DISP_UPDATE;
}
}
if(ob->track) {
;
}
if( give_parteff(ob) ) base->flag |= BA_DISP_UPDATE;
if(ob->type==OB_MBALL) {
Base *b;
b= BLI_ghash_lookup(object_to_base_hash, find_basis_mball(ob));
b->flag |= BA_DISP_UPDATE;
}
}
}
}
if (object_to_base_hash)
BLI_ghash_free(object_to_base_hash, NULL, NULL);
}
static void clear_trans_object_base_flags(void)
{
Base *base;
base= FIRSTBASE;
while(base) {
if(base->flag & BA_WASSEL) base->flag |= SELECT;
base->flag &= ~(BA_PARSEL+BA_WASSEL);
base->flag &= ~(BA_DISP_UPDATE+BA_WHERE_UPDATE+BA_DO_IPO);
/* pose here? */
if (base->object->pose) {
Object *ob= base->object;
bPoseChannel *chan;
for (chan = ob->pose->chanbase.first; chan; chan=chan->next) {
chan->flag &= ~PCHAN_TRANS_UPDATE;
}
}
base= base->next;
}
copy_baseflags();
}
static void createTransObject(void)
{
TransData *tob = NULL;
Object *ob;
Base *base;
int totsel = 0, i;
int totsel= 0;
/* hackish... but we have to do it somewhere */
reset_slowparents();
set_trans_object_base_flags(&Trans);
/* count */
base= FIRSTBASE;
while(base) {
for(base= FIRSTBASE; base; base= base->next) {
if TESTBASELIB(base) {
Trans.total++;
totsel++;
}
else if (G.f & G_PROPORTIONAL) {
ob= base->object;
if (G.vd->lay & ob->lay) {
Trans.total++;
}
}
base= base->next;
}
if(!Trans.total)
if(!Trans.total) {
/* clear here, main transform function escapes too */
clear_trans_object_base_flags();
return;
}
tob = Trans.data = MEM_mallocN(Trans.total*sizeof(TransData), "TransOb");
base= FIRSTBASE;
while(base) {
for(base= FIRSTBASE; base; base= base->next) {
if TESTBASELIB(base) {
ob= base->object;
@@ -711,46 +893,6 @@ static void createTransObject(void)
tob++;
}
base= base->next;
}
/* PROPORTIONAL*/
if (G.f & G_PROPORTIONAL) {
base= FIRSTBASE;
while(base) {
if (!TESTBASELIB(base)) {
TransData *td;
int i;
float dist;
ob= base->object;
if (G.vd->lay & ob->lay) {
tob->flag = 0;
tob->ob = ob;
ObjectToTransData(tob, ob);
tob->dist = -1;
td = Trans.data;
for (i = 0; i < totsel; i++, td++) {
dist = VecLenf(tob->center, td->center);
if (tob->dist == -1) {
tob->dist = dist;
}
else if (dist < tob->dist) {
tob->dist = dist;
}
}
tob++;
}
}
base= base->next;
}
}
/*
@@ -758,37 +900,16 @@ static void createTransObject(void)
SINCE TRANSFORMATION IS ALREADY APPLIED ON PARENT
THERE MUST BE A BETTER WAY TO DO THIS
Yes there is! For now I copy the baseflag method from old transform (ton)
*/
tob = Trans.data;
for (i = 0; i < Trans.total; i++, tob++) {
ob = tob->ob->parent;
while (ob) {
TransData *td;
int j, found = 0;
td = Trans.data;
for (j = 0; j < Trans.total; j++, td++) {
if (ob == td->ob) {
found = 1;
tob->flag |= TD_NOACTION;
break;
}
}
if (found) {
break;
}
ob = ob->parent;
}
}
}
static void createTransData(void)
{
if (G.obpose) {
createTransPoseVerts();
createTransPose();
}
else if (G.obedit) {
if (G.obedit->type == OB_MESH) {
@@ -828,6 +949,7 @@ void Transform(int mode)
unsigned short event;
/*joeedh -> hopefully may be what makes the old transform() constant*/
/* ton: I doubt, but it doesnt harm for now. shouldnt be needed though */
areawinset(curarea->win);
Mat3One(mati);
@@ -855,6 +977,9 @@ void Transform(int mode)
if (Trans.total == 0)
return;
/* EVIL! posemode code can switch translation to rotate when 1 bone is selected. will be removed (ton) */
mode= Trans.mode;
calculatePropRatio(&Trans);
calculateCenter(&Trans);
@@ -884,7 +1009,9 @@ void Transform(int mode)
Trans.redraw = 1;
while (ret_val == 0) {
getmouseco_areawin(mval);
if (mval[0] != pmval[0] || mval[1] != pmval[1]) {
Trans.redraw = 1;
}
@@ -897,6 +1024,10 @@ void Transform(int mode)
}
Trans.redraw = 0;
}
/* essential for idling subloop */
if( qtest()==0) PIL_sleep_ms(2);
while( qtest() ) {
event= extern_qread(&val);
@@ -992,7 +1123,27 @@ void Transform(int mode)
BIF_undo_push("Transform");
}
/* free data, reset vars */
postTrans(&Trans);
/* mess from old transform, just for now (ton) */
{
char cmode='g';
if(mode==TFM_RESIZE) cmode= 's';
else if(mode==TFM_ROTATION) cmode= 'r';
/* aftertrans does displists, ipos and action channels */
special_aftertrans_update(cmode, 0, ret_val == TRANS_CANCEL, 0 /*keyflags*/);
if(G.obedit==NULL && G.obpose==NULL)
clear_trans_object_base_flags();
}
/* send events out for redraws */
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSOBJECT, 0);
scrarea_queue_headredraw(curarea);
}
/* ************************** WRAP *************************** */
@@ -1379,6 +1530,7 @@ int Rotation(TransInfo *t, short mval[2])
sprintf(str, "Rot: %.2f %s", 180.0*final/M_PI, t->proptext);
}
//printf("Axis %f %f %f\n", axis[0], axis[1], axis[2]);
VecRotToMat3(axis, final * td->factor, mat);
for(i = 0 ; i < t->total; i++, td++) {
@@ -1415,11 +1567,23 @@ int Rotation(TransInfo *t, short mval[2])
VecAddf(td->loc, td->iloc, vec);
Mat3MulMat3(totmat, mat, td->mtx);
Mat3MulMat3(fmat, td->smtx, totmat);
Mat3ToEul(fmat, eul);
VECCOPY(td->rot, eul);
if(td->flag & TD_USEQUAT) {
float quat[4];
Mat3MulSerie(fmat, td->mtx, mat, td->smtx, 0, 0, 0, 0, 0);
Mat3ToQuat(fmat, quat); // Actual transform
//printf("Quat %f %f %f %f\n", quat[0], quat[1], quat[2], quat[3]);
QuatMul(td->quat, quat, td->iquat);
}
else {
Mat3MulMat3(totmat, mat, td->mtx);
Mat3MulMat3(fmat, td->smtx, totmat);
Mat3ToEul(fmat, eul);
VECCOPY(td->rot, eul);
}
}
}

View File

@@ -104,7 +104,7 @@ typedef struct TransInfo {
#define NOZERO 8
#define NOFRACTION 16
/* transinfo->mode */
#define TFM_REPEAT 0
#define TFM_TRANSLATION 1
#define TFM_ROTATION 2
@@ -124,9 +124,10 @@ typedef struct TransInfo {
#define PROP_LIN 3
#define PROP_CONST 4
/* TRANSDATA FLAGS */
/* transdata->flag */
#define TD_SELECTED 1
#define TD_NOACTION 2
#define TD_USEQUAT 4
void Transform(int mode);

View File

@@ -88,12 +88,13 @@
#include "BKE_curve.h"
#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_ipo.h"
#include "BKE_lattice.h"
#include "BKE_object.h"
#include "BKE_utildefines.h"
#include "BSE_view.h"
#include "BSE_edit.h"
#include "BSE_view.h"
#include "BLI_arithb.h"
#include "BLI_editVert.h"
@@ -115,6 +116,7 @@ extern TransInfo Trans;
/* ************************** GENERICS **************************** */
/* called for objects updating while transform acts, once per redraw */
void recalcData(TransInfo *t)
{
Base *base;
@@ -137,7 +139,6 @@ void recalcData(TransInfo *t)
if (t->mode == TFM_TRANSLATION) {
chan->flag |= POSE_LOC;
memcpy (chan->loc, td->loc, sizeof (chan->loc));
printf("loc %f %f %f\n", chan->loc[0], chan->loc[1], chan->loc[2]);
}
if (t->mode == TFM_RESIZE) {
chan->flag |= POSE_SIZE;
@@ -171,23 +172,96 @@ void recalcData(TransInfo *t)
makeBevelList(G.obedit); // might be needed for deform
calc_curvepath(G.obedit);
// deform, bevel, taper
base= FIRSTBASE;
while(base) {
if(base->lay & G.vd->lay) {
if(base->object->parent==G.obedit && base->object->partype==PARSKEL)
makeDispList(base->object);
else if(base->object->type==OB_CURVE) {
Curve *cu= base->object->data;
if(G.obedit==cu->bevobj || G.obedit==cu->taperobj)
makeDispList(base->object);
}
}
base= base->next;
}
}
else if(G.obedit->type==OB_ARMATURE){
EditBone *ebo;
/* Ensure all bones are correctly adjusted */
for (ebo=G.edbo.first; ebo; ebo=ebo->next){
if ((ebo->flag & BONE_IK_TOPARENT) && ebo->parent){
/* If this bone has a parent tip that has been moved */
if (ebo->parent->flag & BONE_TIPSEL){
VECCOPY (ebo->head, ebo->parent->tail);
}
/* If this bone has a parent tip that has NOT been moved */
else{
VECCOPY (ebo->parent->tail, ebo->head);
}
}
}
}
else if(G.obedit->type==OB_LATTICE) {
if(editLatt->flag & LT_OUTSIDE) outside_lattice(editLatt);
base= FIRSTBASE;
while(base) {
if(base->lay & G.vd->lay) {
if(base->object->parent==G.obedit) {
makeDispList(base->object);
}
}
base= base->next;
}
}
else if (G.obedit->type == OB_MBALL) {
makeDispList(G.obedit);
}
}
else {
TransData *tob;
int i;
tob = t->data;
for (i = 0; i < t->total; i++, tob++) {
if (tob->ob->type == OB_MBALL) {
makeDispList(tob->ob);
}
base= FIRSTBASE;
while(base) {
if(base->flag & BA_DO_IPO) {
IpoCurve *icu;
base->object->ctime= -1234567.0;
icu= base->object->ipo->curve.first;
while(icu) {
calchandles_ipocurve(icu);
icu= icu->next;
}
}
if(base->object->partype & PARSLOW) {
base->object->partype -= PARSLOW;
where_is_object(base->object);
base->object->partype |= PARSLOW;
}
else if(base->flag & BA_WHERE_UPDATE) {
where_is_object(base->object);
}
base= base->next;
}
base= FIRSTBASE;
while(base) {
if(base->flag & BA_DISP_UPDATE) makeDispList(base->object);
base= base->next;
}
}
/* ugly stuff for posemode */
/* ugly stuff for posemode, copied from old system */
base= FIRSTBASE;
while(base) {
extern int pose_flags_reset_done(Object *ob); // linker solves
@@ -273,19 +347,15 @@ void drawLine(float *center, float *dir, char axis)
myloadmatrix(G.vd->viewmat);
}
/* Here I would suggest only TransInfo related issues, like free data & reset vars. Not redraws */
void postTrans (TransInfo *t)
{
G.moving = 0; // Set moving flag off (display as usual)
//special_aftertrans_update();
MEM_freeN(t->data);
t->data = NULL;
scrarea_do_windraw(curarea);
screen_swapbuffers();
}
void apply_grid3(float *val, int max_index, float fac1, float fac2, float fac3)
@@ -371,6 +441,11 @@ void restoreTransObjects(TransInfo *t)
if (tob->size) {
VECCOPY(tob->size, tob->isize);
}
if(tob->flag & TD_USEQUAT) {
if (tob->quat) {
QUATCOPY(tob->quat, tob->iquat);
}
}
}
recalcData(t);
}
@@ -409,18 +484,18 @@ void calculateCenterCursor(TransInfo *t)
cursor = give_cursor();
VECCOPY(t->center, cursor);
if(G.obedit) {
if(G.obedit || G.obpose) {
Object *ob= G.obedit?G.obedit:G.obpose;
float mat[3][3], imat[3][3];
VecSubf(t->center, t->center, G.obedit->obmat[3]);
Mat3CpyMat4(mat, G.obedit->obmat);
float vec[3];
VecSubf(t->center, t->center, ob->obmat[3]);
Mat3CpyMat4(mat, ob->obmat);
Mat3Inv(imat, mat);
Mat3MulVecfl(imat, t->center);
}
if (G.obedit) {
float vec[3];
VECCOPY(vec, t->center);
Mat4MulVecfl(G.obedit->obmat, vec);
Mat4MulVecfl(ob->obmat, vec);
project_short_noclip(vec, t->center2d);
}
else {
@@ -440,10 +515,12 @@ void calculateCenterMedian(TransInfo *t)
VecMulf(partial, 1.0f / t->total);
VECCOPY(t->center, partial);
if (G.obedit) {
if (G.obedit || G.obpose) {
Object *ob= G.obedit?G.obedit:G.obpose;
float vec[3];
VECCOPY(vec, t->center);
Mat4MulVecfl(G.obedit->obmat, vec);
Mat4MulVecfl(ob->obmat, vec);
project_short_noclip(vec, t->center2d);
}
else {
@@ -470,10 +547,12 @@ void calculateCenterBound(TransInfo *t)
VecAddf(t->center, min, max);
VecMulf(t->center, 0.5);
if (G.obedit) {
if (G.obedit || G.obpose) {
Object *ob= G.obedit?G.obedit:G.obpose;
float vec[3];
VECCOPY(vec, t->center);
Mat4MulVecfl(G.obedit->obmat, vec);
Mat4MulVecfl(ob->obmat, vec);
project_short_noclip(vec, t->center2d);
}
else {
@@ -481,7 +560,8 @@ void calculateCenterBound(TransInfo *t)
}
}
void calculateCenter(TransInfo *t) {
void calculateCenter(TransInfo *t)
{
switch(G.vd->around) {
case V3D_CENTRE:
calculateCenterBound(t);