diff options
Diffstat (limited to 'source/blender/src/editika.c')
-rw-r--r-- | source/blender/src/editika.c | 422 |
1 files changed, 422 insertions, 0 deletions
diff --git a/source/blender/src/editika.c b/source/blender/src/editika.c new file mode 100644 index 00000000000..1c4cde7a247 --- /dev/null +++ b/source/blender/src/editika.c @@ -0,0 +1,422 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#include <math.h> +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif +#include "MEM_guardedalloc.h" + +#include "BMF_Api.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" +#include "BLI_editVert.h" + +#include "DNA_object_types.h" +#include "DNA_screen_types.h" +#include "DNA_scene_types.h" +#include "DNA_ika_types.h" +#include "DNA_view3d_types.h" + +#include "BKE_utildefines.h" +#include "BKE_object.h" +#include "BKE_ika.h" +#include "BKE_global.h" +#include "BKE_displist.h" + +#include "BIF_gl.h" +#include "BIF_toolbox.h" +#include "BIF_mywindow.h" +#include "BIF_screen.h" +#include "BIF_space.h" +#include "BIF_editika.h" + +#include "BSE_view.h" +#include "BSE_drawview.h" + +#include "mydevice.h" +#include "blendef.h" + +static void draw_limb(Limb *li, float small) +{ + float vec[2]; + + glRotatef(( li->alpha*180.0/M_PI), 0.0, 0.0, 1.0); + + { GLUquadricObj *qobj = gluNewQuadric(); + gluQuadricDrawStyle(qobj, GLU_SILHOUETTE); + gluPartialDisk( qobj, small, small, 32, 1, 180.0, 180.0); + gluDeleteQuadric(qobj); + }; + + vec[0]= 0.0; vec[1]= small; + glBegin(GL_LINE_STRIP); + glVertex2fv(vec); + vec[0]= li->len; vec[1]= 0.0; + glVertex2fv(vec); + vec[0]= 0.0; vec[1]= -small; + glVertex2fv(vec); + glEnd(); + + small*= 0.25; + + if(li->next) circf(li->len, 0.0, small); + else circf(li->len, 0.0, small); + + glTranslatef(li->len, 0.0, 0.0); +} + +void draw_ika(Object *ob, int sel) +{ + Ika *ika; + Limb *li; + float col[4]; + float small= 0.15; + + ika= ob->data; + li= ika->limbbase.first; + if(li==0) return; + + /* we zijn al in objectspace */ + glPushMatrix(); + + glGetFloatv(GL_CURRENT_COLOR, col); + + if((ika->flag & IK_GRABEFF)==0) { + if(sel) cpack(0xFFFF); + circf(0.0, 0.0, 0.05*li->len); + + glColor3f(col[0], col[1], col[2]); + } + + while(li) { + small= 0.10*li->len; + draw_limb(li, small); + li= li->next; + } + + if(ika->flag & IK_GRABEFF) { + if(sel) { + if(ika->def) cpack(0xFFFF00); + else cpack(0xFFFF); + } + circf(0.0, 0.0, 0.25*small); + glColor3f(col[0], col[1], col[2]); + } + + glPopMatrix(); +} + +/* type 0: verts, type 1: limbs */ +void draw_ika_nrs(Object *ob, int type) +{ + Ika *ika; + Limb *li; + int nr=0; + char str[12]; + + if(curarea->spacetype!=SPACE_VIEW3D) return; + mywinset(curarea->win); + + glDrawBuffer(GL_FRONT); + myloadmatrix(G.vd->viewmat); + mymultmatrix(ob->obmat); + + ika= ob->data; + li= ika->limbbase.first; + + /* we zijn al in objectspace */ + glPushMatrix(); + cpack(0xFFFFFF); + + if(type==0) { + sprintf(str, " %d", nr++); + glRasterPos3f(0.0, 0.0, 0.0); + BMF_DrawString(G.font, str); + + while(li) { + + glRotatef(( li->alpha*180.0/M_PI), 0.0, 0.0, 1.0); + glTranslatef(li->len, 0.0, 0.0); + sprintf(str, " %d", nr++); + glRasterPos3f(0.0, 0.0, 0.0); + BMF_DrawString(G.font, str); + + li= li->next; + } + } + else { + while(li) { + + glRotatef(( li->alpha*180.0/M_PI), 0.0, 0.0, 1.0); + glTranslatef( 0.7*li->len, 0.0, 0.0); + sprintf(str, " %d", nr++); + glRasterPos3f(0.0, 0.0, 0.0); + BMF_DrawString(G.font, str); + glTranslatef( 0.3*li->len, 0.0, 0.0); + + li= li->next; + } + + } + + glDrawBuffer(GL_BACK); + glPopMatrix(); +} + + + +int extrude_ika(Object *ob, int add) +{ + Ika *ika; + Limb *li; + float dvec[3], dvecp[3], oldeul[3], mat[3][3], imat[3][3]; + int firsttime= 1; + unsigned short event = 0; + short val, afbreek=0, mval[2], xo, yo; + + /* init */ + VECCOPY(oldeul, ob->rot); + initgrabz(ob->obmat[3][0], ob->obmat[3][1], ob->obmat[3][2]); + + Mat3CpyMat4(mat, ob->obmat); + Mat3Inv(imat, mat); + + getmouseco_areawin(mval); + xo= mval[0]; + yo= mval[1]; + + /* het laatste punt van de ika */ + ika= ob->data; + + if(add) { + /* een erbij: */ + li= MEM_callocN(sizeof(Limb), "limb"); + BLI_addtail(&ika->limbbase, li); + if(li->prev) { + li->eff[0]= li->prev->eff[0]; + li->eff[1]= li->prev->eff[1]; + } + li->eff[0]+= 0.5; + } + li= ika->limbbase.last; + if(li==0) return 0; + + while(TRUE) { + + getmouseco_areawin(mval); + if(mval[0]!=xo || mval[1]!=yo || firsttime) { + firsttime= 0; + + window_to_3d(dvec, mval[0]-xo, mval[1]-yo); + VECCOPY(dvecp, dvec); + + /* apply */ + Mat3MulVecfl(imat, dvecp); + li->eff[0]+= dvecp[0]; + li->eff[1]+= dvecp[1]; + + calc_limb(li); + + if(li->prev==0) { + VECCOPY(ob->rot, oldeul); + euler_rot(ob->rot, li->alpha, 'z'); + li->alpha= li->alphao= 0.0; + } + + xo= mval[0]; + yo= mval[1]; + + force_draw(); + } + + while(qtest()) { + event= extern_qread(&val); + if(val) { + switch(event) { + case ESCKEY: + case LEFTMOUSE: + case MIDDLEMOUSE: + case SPACEKEY: + case RETKEY: + afbreek= 1; + break; + } + } + if(afbreek) break; + } + + if(afbreek) break; + } + + if(event==ESCKEY) { + if(ika->limbbase.first!=ika->limbbase.last) { + li= ika->limbbase.last; + BLI_remlink(&ika->limbbase, li); + MEM_freeN(li); + } + } + else if(add) init_defstate_ika(ob); + + allqueue(REDRAWVIEW3D, 0); + + if(event==LEFTMOUSE) return 0; + return 1; +} + +void delete_skeleton(void) +{ + Object *ob; + Ika *ika; + + ob= OBACT; + if(ob==0 || ob->type!=OB_IKA || (ob->flag & SELECT)==0) return; + + ika= ob->data; + + if(!ika->def) return; + if(!okee("Delete Skeleton")) return; + + if(ika->def) MEM_freeN(ika->def); + ika->def= 0; + ika->totdef= 0; + + allqueue(REDRAWVIEW3D, 0); +} + +static void copy_deform(int tot, Deform *defbase, Deform *def) +{ + /* defbase is the old one, *def is new. When they match, + the deform data is copied */ + + while(tot--) { + if(defbase->ob==def->ob && defbase->par1==def->par1) { + def->fac= defbase->fac; + def->dist= defbase->dist; + return; + } + defbase++; + } +} + +void make_skeleton(void) +{ + Object *ob; + Base *base; + Ika *ika; + Deform *def, *defbase; + Limb *li; + int a, totdef=0; + + ob= OBACT; + if(ob==0 || ob->type!=OB_IKA || (ob->flag & SELECT)==0) return; + + if(!okee("Make Skeleton")) return; + + ika= ob->data; + + /* per selected ob, per limb, de obmat en imat berekenen */ + + base= FIRSTBASE; + while(base) { + if TESTBASE(base) { + if(base->object->type==OB_IKA) totdef+= count_limbs(base->object); + else totdef++; + } + base= base->next; + } + + if(totdef==0) { + error("Nothing selected"); + return; + } + + def=defbase= MEM_callocN(totdef*sizeof(Deform), "deform"); + + base= FIRSTBASE; + while(base) { + if TESTBASE(base) { + + if(base->object->type==OB_IKA) { + + li= ( (Ika *)(base->object->data) )->limbbase.first; + a= 0; + while(li) { + what_does_parent1(base->object, PARLIMB, a, 0, 0); + def->ob= base->object; + def->partype= PARLIMB; + def->par1= a; + + Mat4Invert(def->imat, workob.obmat); + def->vec[0]= li->len; + def->fac= 1.0; + + copy_deform(ika->totdef, ika->def, def); + + def++; + a++; + li= li->next; + } + } + else { + what_does_parent1(base->object, PAROBJECT, 0, 0, 0); + def->ob= base->object; + def->partype= PAROBJECT; + + def->vec[0]= 0.0; + def->fac= 1.0; + def->dist= 0.0; + + copy_deform(ika->totdef, ika->def, def); + + Mat4Invert(def->imat, workob.obmat); + def++; + } + } + base= base->next; + } + + if(ika->def) MEM_freeN(ika->def); + ika->def= defbase; + ika->totdef= totdef; + + /* Recalculate the deformation on any object + * that was parented to the old skeleton. + */ + for (base= FIRSTBASE; base; base= base->next) + if (base->object->parent==ob) + makeDispList(base->object); + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWBUTSEDIT, 0); +} |