/** * $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 #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); }