00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #define MODULE_SKELETON 1
00011
00012 #include "design.h"
00013
00014 #define NODE_AXIS 0
00015 #define RED_AXIS 1
00016 #define GREEN_AXIS 2
00017 #define YELLOW_AXIS 3
00018 #define TIME_DELAY 30
00019
00020 static skel *PickSkeleton(int H, int V, int view);
00021 static void DefaultOrientAxes(skel *sp);
00022 static void SelectBySk(skel *sp,int op, int children);
00023 static void SkTwist(void);
00024 static void SkPivot(void);
00025 static void SkRotateRubberBones(void);
00026 static void DrawSkeletonAxes(skel *sp,int view,int sh1,int sv1, HDC hDC);
00027 static void DrawTrSkeletonAxes(skel *sp,int view,int sh1,int sv1, HDC hDC);
00028 static void DuplicateSkeletonChildren(skel *, skel *, skel *, long );
00029 static BOOL CALLBACK SkToolBarDlgProc(HWND, UINT, WPARAM, LPARAM);
00030 static double GetBoneRelativeDistance(point v, point s, point sp, vector d, double len, double *l, vector r);
00031
00032 static BOOL SkMovedFlag=FALSE;
00033 static BOOL SkSelectFlag=FALSE;
00034 static BOOL SkRubberBonesRotate=FALSE;
00035 static int ep1[12]={0,1,2,3,4,5,6,7,0,1,2,3};
00036 static int ep2[12]={1,2,3,0,5,6,7,4,4,5,6,7};
00037 static int SelectedSkeletonAxis=0;
00038 static point LastSkeletonPoint;
00039 static skel *LastSkeletonVertex=NULL,*SkAssNode=NULL,
00040 *SkSelectedNode1=NULL,*SkSelectedNode2=NULL;
00041
00042 static skel *PickSkeleton(int H, int V, int view){
00043 skel *sp,*sf;
00044 double d,dmin,dth;
00045 int sho,svo;
00046 sp=MainSp;
00047 sf=NULL;
00048 dmin=(double)TVsizeX*(double)TVsizeX;
00049 dth=dmin/32/32;
00050 while(sp != NULL){
00051 GetWindowCoords(view,sp->xyz[0],sp->xyz[1],sp->xyz[2],&sho,&svo);
00052 if( (sho > H-4) && (sho < H+4) && (svo > V-4) && (svo < V+4)){
00053 d=(double)(sp->xyz[0]-NpointerX)*(double)(sp->xyz[0]-NpointerX)
00054 +(double)(sp->xyz[1]-NpointerY)*(double)(sp->xyz[1]-NpointerY)
00055 +(double)(sp->xyz[2]-NpointerZ)*(double)(sp->xyz[2]-NpointerZ);
00056 if(d < dmin){
00057 dmin=d;
00058 sf=sp;
00059 }
00060 }
00061 sp=sp->last;
00062 }
00063 return sf;
00064 }
00065
00066 void ZeroSkeletonBoundingBox(skel *sp){
00067 int i,j;
00068 for(i=0;i<8;i++)for(j=0;j<3;j++)sp->bx[i][j] = sp->xyz[j];
00069 if(sp->at != NULL){
00070 for(j=0;j<3;j++)sp->bx[2][j]=sp->at->xyz[j];
00071 for(j=0;j<3;j++)sp->bx[3][j]=sp->at->xyz[j];
00072 for(j=0;j<3;j++)sp->bx[6][j]=sp->at->xyz[j];
00073 for(j=0;j<3;j++)sp->bx[7][j]=sp->at->xyz[j];
00074 }
00075 }
00076
00077 static void DefaultOrientAxes(skel *sp){
00078 vector x={1.0,0.0,0.0},y={0.0,1.0,0.0},z={0.0,0.0,1.0};
00079 if(sp->at == NULL)return;
00080 VECSUB((double)sp->at->xyz,(double)sp->xyz,sp->v); O_normalize(sp->v);
00081 if (fabs(sp->v[2]) < 0.9)CROSS(sp->v,z,sp->u)
00082 else if(fabs(sp->v[1]) < 0.9)CROSS(y,sp->v,sp->u)
00083 else CROSS(x,sp->v,sp->u)
00084 O_normalize(sp->u);
00085 CROSS(sp->u,sp->v,sp->w);
00086 O_normalize(sp->w);
00087 }
00088
00089 void GetSkeletonBoundBox(skel *sp, int ass){
00090 long l;
00091 int i,j,flag=0;
00092 vector p,box[8];
00093 vertex *vp;
00094 double a,b,c,amin,amax,bmin,bmax,cmin,cmax;
00095 amin=bmin=cmin= FARAWAY;
00096 amax=bmax=cmax= -FARAWAY;
00097 ZeroSkeletonBoundingBox(sp);
00098 if((vp=MainVp) != NULL)for(l=0;l<Nvert;l++){
00099 if(ass && vp->status == SELECTED)vp->sp=sp;
00100 if(vp->sp == sp){
00101 flag=1;
00102 VECSUB((double)vp->xyz,(double)sp->xyz,p)
00103 a=DOT(p,sp->u); amin=min(a,amin); amax=max(a,amax);
00104 b=DOT(p,sp->v); bmin=min(b,bmin); bmax=max(b,bmax);
00105 c=DOT(p,sp->w); cmin=min(c,cmin); cmax=max(c,cmax);
00106 }
00107 vp++;
00108 }
00109 if(flag){
00110 box[0][0]=amin; box[0][1]=bmin; box[0][2]=cmax;
00111 box[1][0]=amax; box[1][1]=bmin; box[1][2]=cmax;
00112 box[2][0]=amax; box[2][1]=bmax; box[2][2]=cmax;
00113 box[3][0]=amin; box[3][1]=bmax; box[3][2]=cmax;
00114 box[4][0]=amin; box[4][1]=bmin; box[4][2]=cmin;
00115 box[5][0]=amax; box[5][1]=bmin; box[5][2]=cmin;
00116 box[6][0]=amax; box[6][1]=bmax; box[6][2]=cmin;
00117 box[7][0]=amin; box[7][1]=bmax; box[7][2]=cmin;
00118 for(i=0;i<8;i++)for(j=0;j<3;j++){
00119 sp->bx[i][j] = sp->xyz[j] + (long)(box[i][0]*sp->u[j] +
00120 box[i][1]*sp->v[j] +
00121 box[i][2]*sp->w[j]);
00122 }
00123 }
00124 }
00125
00126 void SelectByHierarchy(skel *sp, int op){
00127 vertex *vp;
00128 skel *sp1,*sp2;
00129 int drawval=0;
00130 long i;
00131 if(sp != NULL){
00132 if((sp1=MainSp) != NULL)while(sp1 != NULL){
00133 sp1->id=0; sp1=sp1->last;
00134 }
00135 if((sp1=MainSp) != NULL)while(sp1 != NULL){
00136 sp2=sp1;
00137 while(sp2 != NULL){
00138 if(sp2 == sp)sp1->id=1;
00139 sp2=sp2->at;
00140 }
00141 sp1=sp1->last;
00142 }
00143 if(op == DLG_SKEL_SELECT){
00144 if((vp=MainVp) != NULL)for(i=0;i<Nvert;i++,vp++){
00145 if((sp1=vp->sp) != NULL && sp1->id == 1 && vp->status != SELECTED){
00146 if(drawval == 0)drawval=1;
00147 if(vp->status == HIDDEN)drawval=2;
00148 vp->status=SELECTED;
00149 NvertSelect++; NvertDeselect--;
00150 }
00151 }
00152 }
00153 else if(op == DLG_SKEL_DESELECT){
00154 if((vp=MainVp) != NULL)for(i=0;i<Nvert;i++,vp++){
00155 if((sp1=vp->sp) != NULL && sp1->id == 1 && vp->status != DESELECTED){
00156 if(vp->status == HIDDEN){
00157 vp->status=DESELECTED;
00158 drawval=2;
00159 }
00160 else{
00161 if(drawval == 0)drawval=1;
00162 vp->status=DESELECTED;
00163 NvertSelect--; NvertDeselect++;
00164 }
00165 }
00166 }
00167 }
00168 else if(op == DLG_SKEL_HIDE){
00169 if((vp=MainVp) != NULL)for(i=0;i<Nvert;i++,vp++){
00170 if((sp1=vp->sp) != NULL && sp1->id == 1 && vp->status != HIDDEN){
00171 drawval=2;
00172 if(vp->status == SELECTED){NvertSelect--; NvertDeselect++;}
00173 vp->status=HIDDEN;
00174 }
00175 }
00176 }
00177 else if(op == 1){
00178 if((vp=MainVp) != NULL)for(i=0;i<Nvert;i++,vp++){
00179 if(vp->status == DESELECTED && (sp1=vp->sp) != NULL &&
00180 ((!SkSelectFlag && sp1 == sp) || (SkSelectFlag && sp1->id == 1)) ){
00181 if(drawval == 0)drawval=1;
00182 vp->status=SELECTED;
00183 NvertSelect++; NvertDeselect--;
00184 }
00185 }
00186 }
00187 else if(op == 2){
00188 if((vp=MainVp) != NULL)for(i=0;i<Nvert;i++,vp++){
00189 if(vp->status == SELECTED && (sp1=vp->sp) != NULL &&
00190 ((!SkSelectFlag && sp1 == sp) || (SkSelectFlag && sp1->id == 1)) ){
00191 if(drawval == 0)drawval=1;
00192 vp->status=DESELECTED;
00193 NvertSelect--; NvertDeselect++;
00194 }
00195 }
00196 }
00197 else if(op == 3){
00198 if((vp=MainVp) != NULL)for(i=0;i<Nvert;i++,vp++){
00199 if((sp1=vp->sp) != NULL &&
00200 ((!SkSelectFlag && sp1 == sp) || (SkSelectFlag && sp1->id == 1)) ){
00201 drawval=2;
00202 if(vp->status == SELECTED){NvertSelect--; NvertDeselect++;}
00203 vp->status=HIDDEN;
00204 }
00205 }
00206 }
00207 else if(op == 4){
00208 if((vp=MainVp) != NULL)for(i=0;i<Nvert;i++,vp++){
00209 if(vp->status == HIDDEN && (sp1=vp->sp) != NULL &&
00210 ((!SkSelectFlag && sp1 == sp) || (SkSelectFlag && sp1->id == 1)) ){
00211 drawval=2;
00212 vp->status=DESELECTED;
00213 }
00214 }
00215 }
00216 if(drawval == 2)DrawModel();
00217 else if(drawval == 1)DrawVerticesOnly(NULL);
00218 UpdateCounters();
00219 }
00220 }
00221
00222 static void SelectBySk(skel *sp,int op, int children){
00223 vertex *vp;
00224 skel *sp1,*sp2;
00225 int drawval=0;
00226 long i;
00227 if(sp != NULL){
00228 if((sp1=MainSp) != NULL)while(sp1 != NULL){
00229 sp1->id=0; sp1=sp1->last;
00230 }
00231 if(children == 1){
00232 if((sp1=MainSp) != NULL)while(sp1 != NULL){
00233 sp2=sp1;
00234 while(sp2 != NULL){
00235 if(sp2 == sp)sp1->id=1;
00236 sp2=sp2->at;
00237 }
00238 sp1=sp1->last;
00239 }
00240 }
00241 else{
00242 if((sp1=MainSp) != NULL)while(sp1 != NULL){
00243 if(sp1 == sp)sp1->id=1;
00244 sp1=sp1->last;
00245 }
00246 }
00247 if(op == SELECTED){
00248 if((vp=MainVp) != NULL)for(i=0;i<Nvert;i++,vp++){
00249 if((sp1=vp->sp) != NULL && sp1->id == 1 && vp->status == DESELECTED){
00250 if(drawval == 0)drawval=1;
00251 vp->status=SELECTED;
00252 NvertSelect++; NvertDeselect--;
00253 }
00254 }
00255 }
00256 else if(op == DESELECTED){
00257 if((vp=MainVp) != NULL)for(i=0;i<Nvert;i++,vp++){
00258 if((sp1=vp->sp) != NULL && sp1->id == 1 && vp->status == SELECTED){
00259 if(drawval == 0)drawval=1;
00260 vp->status=DESELECTED;
00261 NvertSelect--; NvertDeselect++;
00262 }
00263 }
00264 }
00265 if(drawval == 1){
00266 DrawVerticesOnly(NULL);
00267 UpdateCounters();
00268 }
00269 }
00270 }
00271
00272 int skintriview(point p){
00273 if( ((p[0] > TVpointX) && (p[0] < TVpointX+TVsizeX))
00274 && ((p[1] > TVpointY) && (p[1] < TVpointY+TVsizeY))
00275 && ((p[2] > TVpointZ) && (p[2] < TVpointZ+TVsizeZ))
00276 )return 1;
00277 return 0;
00278 }
00279
00280 void SkDelete(skel *sp){
00281 vertex *vp;
00282 long i;
00283 EraseSkeleton(sp);
00284 if((vp=MainVp) != NULL)for(i=0;i<Nvert;i++){
00285 if(vp->sp == sp)vp->sp=NULL;
00286 vp++;
00287 }
00288 ClearNurbsSkeleton(sp);
00289 }
00290
00291 void ResetSkeletonWeights(void){
00292 double w=1.0,r=1.0,z=0.1;
00293 skel *sp;
00294 if(Read3Reals("Reset All Bones",&w,&r,&z,2) == OK){
00295 sp=MainSp; while(sp != NULL){
00296 sp->weight=w;
00297 sp->wrange=r;
00298 sp->wzone=z;
00299 sp=sp->last;
00300 }
00301 }
00302 }
00303
00304 void AutoVerticesToSkeleton(void){
00305 int i;
00306 vertex *vp;
00307 skel *sp,*nearest_sp;
00308 double d,l,dmin;
00309 vector r;
00310 i=MessageBox(ghwnd_main,"Confirm ?","Auto Assign",MB_YESNO);
00311 if(i != IDYES)return;
00312 sp=MainSp; while(sp != NULL){
00313 VECCOPY(sp->xyz,sp->xyz_last);
00314 sp=sp->last;
00315 }
00316 sp=MainSp; while(sp != NULL){
00317 if(sp->at != NULL){
00318 VECSUB((double)sp->at->xyz_last,(double)sp->xyz_last,sp->d_last)
00319 sp->len_last=sqrt(DOT(sp->d_last,sp->d_last));
00320 VECSCALE(1.0/sp->len_last,sp->d_last,sp->d_last);
00321 VECSUB((double)sp->at->xyz,(double)sp->xyz,sp->d)
00322 sp->len=sqrt(DOT(sp->d,sp->d));
00323 VECSCALE(1.0/sp->len,sp->d,sp->d);
00324 }
00325 sp=sp->last;
00326 }
00327 vp=MainVp; if(MainVp != NULL && Nvert > 0)for(i=0;i<Nvert;i++){
00328 if(vp->status == SELECTED){
00329 dmin=(double)MAXUNIT; nearest_sp=NULL;
00330 sp=MainSp; while(sp != NULL){
00331 if(sp->at != NULL && sp->weight > 0.0){
00332 d=GetBoneRelativeDistance(vp->xyz,sp->xyz_last,sp->at->xyz_last,sp->d_last,sp->len_last,&l,r);
00333 d=d/fabs(sp->weight);
00334 if(d < dmin){
00335 if(l < sp->wrange+sp->wzone){
00336 dmin=d;
00337 nearest_sp=sp;
00338 }
00339 }
00340 }
00341 sp=sp->last;
00342 }
00343 if(nearest_sp != NULL){
00344 vp->sp=nearest_sp;
00345 }
00346 }
00347 vp++;
00348 }
00349 sp=MainSp; while(sp != NULL){
00350 GetSkeletonBoundBox(sp,0);
00351 sp=sp->last;
00352 }
00353 }
00354
00355 static void SkTwist(void){
00356 int x,xo,MickeyX;
00357 POINT pt;
00358 long xp,yp,evTime;
00359 double I,ltr[4][4];
00360 skel *sp;
00361 if(SkSelectedNode1 == NULL)return;
00362 GetCursorPos(&pt); xo=pt.x;
00363 sp=SkSelectedNode1;
00364 ClipCursor(NULL);
00365 evTime=GetTickCount()+TIME_DELAY;
00366 do {
00367 if(evTime > GetTickCount())continue;
00368 GetCursorPos(&pt); x=pt.x;
00369 MickeyX = x-xo; xo=x;
00370 if(MickeyX != 0){
00371 if(MickeyX > 0)I=(double)max( 1,min( 45,MickeyX));
00372 else I=(double)min(-1,max(-45,MickeyX));
00373 DrawSkeleton();
00374 rotate_round_vector(I,sp->v,ltr);
00375 mv4by1(ltr,sp->u,sp->u);
00376 mv4by1(ltr,sp->w,sp->w);
00377 DrawSkeleton();
00378 }
00379 evTime=GetTickCount()+TIME_DELAY;
00380 }
00381 while (GetAsyncKeyState(VK_LBUTTON) & 0x8000);
00382 return;
00383 }
00384
00385 static double GetBoneRelativeDistance(point v, point s, point sp, vector d, double len, double *l, vector r){
00386 vector dp,q;
00387 double ll;
00388 VECSUB((double)v,(double)s,dp)
00389 ll=DOT(dp,d);
00390 if(ll < 0.0){
00391 *l=0.0;
00392 VECSUB((double)v,(double)s,r)
00393 }
00394 else if(ll > len){
00395 *l=1.0;
00396 VECSUB((double)v,(double)sp,r)
00397 }
00398 else{
00399 *l=ll/len;
00400 VECSUM((double)s,ll*d,q)
00401 VECSUB((double)v,q,r)
00402 }
00403 return sqrt(DOT(r,r));
00404 }
00405
00406 static void GetNewVertexPositionForBone(skel *sp, vector p){
00407 double l;
00408 vector pb;
00409 l=sp->len * sp->l;
00410 VECSUM((double)sp->xyz,l*sp->d,pb)
00411 VECSUM(pb,sp->r,p)
00412 }
00413
00414 static void GetNewVertexPositionForRotatedBone(skel *sp, point v, vector p){
00415 m4by1(sp->tr,(double)v[0],(double)v[1],(double)v[2],&p[0],&p[1],&p[2]);
00416 }
00417
00418
00419 static void RubberBonesDeformConstant(void){
00420 int i;
00421 vertex *vp;
00422 skel *sp,*spsel;
00423 double l,f,x,ff,wsum;
00424 vector r,p,nv;
00425
00426 sp=MainSp; while(sp != NULL){
00427 if(sp->at != NULL){
00428 VECSUB((double)sp->at->xyz_last,(double)sp->xyz_last,sp->d_last)
00429 sp->len_last=sqrt(DOT(sp->d_last,sp->d_last));
00430 VECSCALE(1.0/sp->len_last,sp->d_last,sp->d_last);
00431 VECSUB((double)sp->at->xyz,(double)sp->xyz,sp->d)
00432 sp->len=sqrt(DOT(sp->d,sp->d));
00433 VECSCALE(1.0/sp->len,sp->d,sp->d);
00434 }
00435 sp=sp->last;
00436 }
00437
00438 vp=MainVp; if(MainVp != NULL && Nvert > 0)for(i=0;i<Nvert;i++){
00439 if(vp->status == SELECTED){
00440 wsum=0.0;
00441 sp=MainSp; while(sp != NULL){
00442 sp->r_scale=0.0;
00443 if(sp->at != NULL){
00444 sp->r_dist=GetBoneRelativeDistance(vp->xyz,sp->xyz_last,sp->at->xyz_last,
00445 sp->d_last,sp->len_last,&l,r);
00446 sp->l=l;
00447 VECCOPY(r,sp->r)
00448 if(sp->r_dist < sp->wrange*ruler){
00449 f=(sp->wrange-sp->wzone)*ruler;
00450 sp->r_scale=sp->weight;
00451 if(l < 1.e-3 || l > 1-1.e-3){
00452 ff=sqrt(1.0 - sp->r_dist/(sp->wrange*ruler));
00453 sp->r_scale *= ff;
00454 }
00455 else if((x=sp->r_dist - f) > 0){
00456 sp->r_scale *= (1.0-x/f);
00457 }
00458 wsum += sp->r_scale;
00459 }
00460 }
00461 sp=sp->last;
00462 }
00463 if(wsum > 0.0){
00464 nv[0]=nv[1]=nv[2]=0.0;
00465 sp=MainSp; while(sp != NULL){
00466 if(sp->at != NULL){
00467 if(SkRubberBonesRotate)GetNewVertexPositionForRotatedBone(sp,vp->xyz,p);
00468 else GetNewVertexPositionForBone(sp,p);
00469 VECSUM(nv,(sp->r_scale/wsum)*p,nv)
00470 }
00471 sp=sp->last;
00472 }
00473
00474 VECCOPY((long)nv,vp->xyz)
00475 }
00476 }
00477 vp++;
00478 }
00479 }
00480
00481 static void RubberBonesDeformVariable(void){
00482 int i;
00483 vertex *vp;
00484 skel *sp;
00485 double l,dmin,dthresh=32,wsum;
00486 vector r,p,nv;
00487
00488 sp=MainSp; while(sp != NULL){
00489 if(sp->at != NULL){
00490 VECSUB((double)sp->at->xyz_last,(double)sp->xyz_last,sp->d_last)
00491 sp->len_last=sqrt(DOT(sp->d_last,sp->d_last));
00492 VECSCALE(1.0/sp->len_last,sp->d_last,sp->d_last);
00493 VECSUB((double)sp->at->xyz,(double)sp->xyz,sp->d)
00494 sp->len=sqrt(DOT(sp->d,sp->d));
00495 VECSCALE(1.0/sp->len,sp->d,sp->d);
00496 }
00497 sp=sp->last;
00498 }
00499
00500 vp=MainVp; if(MainVp != NULL && Nvert > 0)for(i=0;i<Nvert;i++){
00501 if(vp->status == SELECTED){
00502 dmin=(double)MAXUNIT;
00503 sp=MainSp; while(sp != NULL){
00504 if(sp->at != NULL){
00505 sp->r_scale=max(dthresh,(sp->r_dist=GetBoneRelativeDistance(vp->xyz,sp->xyz_last,sp->at->xyz_last,
00506 sp->d_last,sp->len_last,&l,r)));
00507 sp->l=l;
00508 VECCOPY(r,sp->r)
00509 if(sp->r_scale < dmin)dmin=sp->r_scale;
00510 }
00511 sp=sp->last;
00512 }
00513 wsum=0.0;
00514 sp=MainSp; while(sp != NULL){
00515 if(sp->at != NULL){
00516 sp->r_scale = (dmin/(sp->r_scale))*(dmin/(sp->r_scale))*sp->weight;
00517 if(sp->r_dist > (sp->wrange-sp->wzone)*ruler){
00518 if(sp->r_dist > sp->wrange*ruler)sp->r_scale=0.0;
00519 else{
00520 double s = (sp->r_dist - (sp->wrange-sp->wzone)*ruler)/(sp->wzone*ruler);
00521 sp->r_scale *= (1.0-s);
00522 }
00523 }
00524 wsum += sp->r_scale;
00525 }
00526 sp=sp->last;
00527 }
00528 if(wsum > 1.e-4){
00529 sp=MainSp; while(sp != NULL){
00530 if(sp->at != NULL){
00531 sp->r_scale /= wsum;
00532 }
00533 sp=sp->last;
00534 }
00535
00536
00537 nv[0]=nv[1]=nv[2]=0.0;
00538 sp=MainSp; while(sp != NULL){
00539 if(sp->at != NULL){
00540 if(SkRubberBonesRotate)GetNewVertexPositionForRotatedBone(sp,vp->xyz,p);
00541 else GetNewVertexPositionForBone(sp,p);
00542 VECSUM(nv,(sp->r_scale)*p,nv)
00543 }
00544 sp=sp->last;
00545 }
00546
00547 VECCOPY((long)nv,vp->xyz)
00548 }
00549 }
00550 vp++;
00551 }
00552 }
00553
00554 static void RubberBonesDeform(void){
00555 if(rubberbone_model == 0)RubberBonesDeformVariable();
00556 else RubberBonesDeformConstant();
00557 }
00558
00559 static void SkRotateRubberBones(void){
00560 int x,xo,MickeyX;
00561 POINT pt;
00562 long xp,yp,evTime;
00563 double I,ltr[4][4],sst[4][4],xr,yr,zr;
00564 skel *sp,*ls,*ssp;
00565 point p2;
00566 vector v;
00567 if((ls=LastSkeletonVertex) == NULL)return;
00568 GetCursorPos(&pt); xo=pt.x;
00569 ClipCursor(NULL);
00570 evTime=GetTickCount()+TIME_DELAY;
00571 do {
00572 if(evTime > GetTickCount())continue;
00573 GetCursorPos(&pt); x=pt.x;
00574 MickeyX = x-xo; xo=x;
00575 if(MickeyX != 0){
00576 DrawSkeleton();
00577 if(MickeyX > 0)I=(double)max( 1,min( 45,MickeyX));
00578 else I=(double)min(-1,max(-45,MickeyX));
00579 if (ActiveView == 0){v[0] = 0.0; v[1] = 0.0; v[2] = 1.0;}
00580 else if(ActiveView == 1){v[0] = 0.0; v[1] = 1.0; v[2] = 0.0;}
00581 else if(ActiveView == 2){v[0] = -1.0; v[1] = 0.0; v[2] = 0.0;}
00582 if(ls->at == NULL){
00583 VECSCALE(1000.0*(double)UNIT2,v,v)
00584 VECSUM((double)ls->xyz,v,v)
00585 mv4by1(ls->t,v,v);
00586 VECCOPY((long)v,p2)
00587 arbitrary_rotate(I,ls->tp,p2,ltr);
00588 }
00589 else{
00590 VECSCALE(1000.0*(double)UNIT2,v,v)
00591 VECSUM((double)ls->at->xyz,v,v)
00592 mv4by1(ls->at->t,v,v);
00593 VECCOPY((long)v,p2)
00594 arbitrary_rotate(I,ls->at->tp,p2,ltr);
00595 }
00596 ssp=MainSp; while(ssp != NULL){
00597 sp=ssp; while(sp != NULL){
00598 if(sp == LastSkeletonVertex){
00599 m4by4(ltr,ssp->t,sst);
00600 c4to4(sst,ssp->t);
00601 break;
00602 }
00603 sp=sp->at;
00604 }
00605 ssp=ssp->last;
00606 }
00607 sp=MainSp; while(sp != NULL){
00608 m4by4(sp->t,sp->tr,sst); c4to4(sst,sp->tr);
00609 m4by1(sp->t,(double)(sp->xyz[0]),(double)(sp->xyz[1])
00610 ,(double)(sp->xyz[2]),&xr,&yr,&zr);
00611 sp->xyz[0]=(long)xr; sp->xyz[1]=(long)yr; sp->xyz[2]=(long)zr;
00612 null_transform(sp->t);
00613 sp=sp->last;
00614 }
00615 DrawSkeleton();
00616 }
00617 evTime=GetTickCount()+TIME_DELAY;
00618 }
00619 while (GetAsyncKeyState(VK_LBUTTON) & 0x8000);
00620 return;
00621 }
00622
00623 static void SkPivot(void){
00624 int x,xo,MickeyX;
00625 POINT pt;
00626 long xp,yp,evTime;
00627 double I,ltr[4][4],sst[4][4];
00628 skel *sp,*ls,*ssp;
00629 point p2;
00630 vector v;
00631 if((ls=LastSkeletonVertex) == NULL)return;
00632 GetCursorPos(&pt); xo=pt.x;
00633 sp=SkSelectedNode1;
00634 ClipCursor(NULL);
00635 evTime=GetTickCount()+TIME_DELAY;
00636 do {
00637 if(evTime > GetTickCount())continue;
00638 GetCursorPos(&pt); x=pt.x;
00639 MickeyX = x-xo; xo=x;
00640 if(MickeyX != 0){
00641 if(MickeyX > 0)I=(double)max( 1,min( 45,MickeyX));
00642 else I=(double)min(-1,max(-45,MickeyX));
00643 if(1){
00644 if(ls->at == NULL){
00645 if (SelectedSkeletonAxis == RED_AXIS )VECCOPY(ls->u,v)
00646 else if(SelectedSkeletonAxis == GREEN_AXIS)VECCOPY(ls->v,v)
00647 else VECCOPY(ls->w,v)
00648 VECSCALE(1000.0*(double)UNIT2,v,v)
00649 VECSUM((double)ls->xyz,v,v)
00650 mv4by1(ls->t,v,v);
00651 VECCOPY((long)v,p2)
00652 arbitrary_rotate(I,ls->tp,p2,ltr);
00653 }
00654 else{
00655 if(SelectedSkeletonAxis == NODE_AXIS){
00656 arbitrary_rotate(I,ls->tp,ls->at->tp,ltr);
00657 }
00658 else{
00659 if (SelectedSkeletonAxis == RED_AXIS )VECCOPY(ls->at->u,v)
00660 else if(SelectedSkeletonAxis == GREEN_AXIS )VECCOPY(ls->at->v,v)
00661 else if(SelectedSkeletonAxis == YELLOW_AXIS)VECCOPY(ls->at->w,v)
00662 VECSCALE(1000.0*(double)UNIT2,v,v)
00663 VECSUM((double)ls->at->xyz,v,v)
00664 mv4by1(ls->at->t,v,v);
00665 VECCOPY((long)v,p2)
00666 arbitrary_rotate(I,ls->at->tp,p2,ltr);
00667 }
00668 }
00669 }
00670 else{
00671 null_transform(ltr);
00672 }
00673 ssp=MainSp; while(ssp != NULL){
00674 sp=ssp; while(sp != NULL){
00675 if(sp == LastSkeletonVertex){
00676 m4by4(ltr,ssp->t,sst);
00677 c4to4(sst,ssp->t);
00678 break;
00679 }
00680 sp=sp->at;
00681 }
00682 ssp=ssp->last;
00683 }
00684 DrawModel();
00685 if(ghwndOpenGLview == NULL)Draw3dView(0,0);
00686 UpdateWindow(ghwnd_view);
00687 }
00688 evTime=GetTickCount()+TIME_DELAY;
00689 }
00690 while (GetAsyncKeyState(VK_LBUTTON) & 0x8000);
00691 return;
00692 }
00693
00694 static void DrawTrSkeletonAxes(skel *sp,int view,int sh1,int sv1, HDC hDC){
00695 HPEN holdPen=NULL;
00696 int i,j,draw,draw_red,draw_green,draw_yellow;
00697 vector vpu,vpv,vpw;
00698 point pu,pv,pw;
00699 double s,x,y,z;
00700 long ix,iy,iz;
00701 int sh2,sv2,sh[8],sv[8];
00702 draw_red=NO; draw_green=NO; draw_yellow=NO;
00703 if(sp == SkSelectedNode1){
00704 if(SelectedSkeletonAxis == RED_AXIS )draw_red=YES;
00705 if(SelectedSkeletonAxis == GREEN_AXIS )draw_green=YES;
00706 if(SelectedSkeletonAxis == YELLOW_AXIS)draw_yellow=YES;
00707 s=(double)TVsizeX/10;
00708 draw=YES;
00709 holdPen=SelectObject(hDC,ghSelectedPen);
00710 }
00711 else if(sp == SkSelectedNode2){
00712 if(SelectedSkeletonAxis == NODE_AXIS){
00713 holdPen=SelectObject(hDC,ghSelectedPen);
00714 draw_green=YES;
00715 }
00716 s=(double)TVsizeX/15;
00717 draw=YES;
00718 }
00719 else{
00720 s=(double)TVsizeX/15;
00721 draw=NO;
00722 }
00723 if(draw){
00724 for(i=0;i<3;i++){
00725 vpu[i]=(s * sp->u[i]) + (double)sp->xyz[i];
00726 vpv[i]=(s * sp->v[i]) + (double)sp->xyz[i];
00727 vpw[i]=(s * sp->w[i]) + (double)sp->xyz[i];
00728 }
00729 m4by1(sp->t,vpu[0],vpu[1],vpu[2],&x,&y,&z);
00730 pu[0]=(long)x; pu[1]=(long)y; pu[2]=(long)z;
00731 m4by1(sp->t,vpv[0],vpv[1],vpv[2],&x,&y,&z);
00732 pv[0]=(long)x; pv[1]=(long)y; pv[2]=(long)z;
00733 m4by1(sp->t,vpw[0],vpw[1],vpw[2],&x,&y,&z);
00734 pw[0]=(long)x; pw[1]=(long)y; pw[2]=(long)z;
00735 GetWindowCoords(view,pu[0],pu[1],pu[2],&sh2,&sv2);
00736 if(draw_red == YES){
00737 MoveToEx(hDC,sh2,sv2,NULL); LineTo(hDC,sh1,sv1);
00738 Ellipse(hDC,sh2-2,sv2-2,sh2+3,sv2+3);
00739 }
00740 GetWindowCoords(view,pv[0],pv[1],pv[2],&sh2,&sv2);
00741 if(draw_green == YES){
00742 MoveToEx(hDC,sh2,sv2,NULL); LineTo(hDC,sh1,sv1);
00743 Ellipse(hDC,sh2-2,sv2-2,sh2+3,sv2+3);
00744 }
00745 GetWindowCoords(view,pw[0],pw[1],pw[2],&sh2,&sv2);
00746 if(draw_yellow == YES){
00747 MoveToEx(hDC,sh2,sv2,NULL); LineTo(hDC,sh1,sv1);
00748 Ellipse(hDC,sh2-2,sv2-2,sh2+3,sv2+3);
00749 }
00750 }
00751 if(holdPen != NULL)SelectObject(hDC,holdPen);
00752 for(i=0;i<8;i++){
00753 m4by1(sp->t,(double)(sp->bx[i][0]),
00754 (double)(sp->bx[i][1]),
00755 (double)(sp->bx[i][2]),&x,&y,&z);
00756 GetWindowCoords(view,(long)x,(long)y,(long)z,&sh[i],&sv[i]);
00757 }
00758 if(sh[0] == sh1 &&
00759 sv[0] == sv1 &&
00760 sh[1] == sh1 &&
00761 sv[1] == sv1 &&
00762 sh[4] == sh1 &&
00763 sv[4] == sv1)return;
00764 for(i=0;i<12;i++){
00765 MoveToEx(hDC,sh[ep1[i]],sv[ep1[i]],NULL);
00766 LineTo(hDC,sh[ep2[i]],sv[ep2[i]]);
00767 }
00768 return;
00769 }
00770
00771 void DrawTrSkeletonInOne(HDC hDC, int view){
00772 HBRUSH holdBrush;
00773 HPEN holdPen,holdPen1;
00774 int sh1,sv1,sh2,sv2,i;
00775 double x,y,z;
00776 skel *sp;
00777 if(Nskel == 0 || MainSp == NULL)return;
00778 holdPen=SelectObject(hDC,ghEdgePen);
00779 holdBrush=SelectObject(hDC,GetStockObject(HOLLOW_BRUSH));
00780 SelectPalette(hDC,ghpaletteScreen,FALSE);
00781 RealizePalette(hDC);
00782 sp=MainSp;
00783 while(sp != NULL){
00784 m4by1(sp->t,(double)(sp->xyz[0]),(double)(sp->xyz[1])
00785 ,(double)(sp->xyz[2]),&x,&y,&z);
00786 sp->tp[0]=(long)x; sp->tp[1]=(long)y; sp->tp[2]=(long)z;
00787 sp=sp->last;
00788 }
00789 sp=MainSp;
00790 while(sp != NULL){
00791 if(skintriview(sp->tp) || (sp->at != NULL && skintriview(sp->at->tp))){
00792 GetWindowCoords(view,sp->tp[0],sp->tp[1],sp->tp[2],&sh1,&sv1);
00793 if(sp->at != NULL){
00794 GetWindowCoords(view,sp->at->tp[0],
00795 sp->at->tp[1],sp->at->tp[2],&sh2,&sv2);
00796 MoveToEx(hDC,sh1,sv1,NULL); LineTo(hDC,sh2,sv2);
00797 }
00798 if(sp == LastSkeletonVertex)holdPen1=SelectObject(hDC,ghInvertPen);
00799 if(sp == FirstSp)Rectangle(hDC,sh1-4,sv1-4,sh1+5,sv1+5);
00800 else Ellipse(hDC,sh1-3,sv1-3,sh1+4,sv1+4);
00801 if(sp == LastSkeletonVertex)SelectObject(hDC,holdPen1);
00802 DrawTrSkeletonAxes(sp,view,sh1,sv1,hDC);
00803 }
00804 sp=sp->last;
00805 }
00806 SelectObject(hDC,holdPen);
00807 SelectObject(hDC,holdBrush);
00808 }
00809
00810 static void DrawSkeletonAxes(skel *sp,int view,int sh1,int sv1, HDC hDC){
00811 HPEN holdPen;
00812 point pu,pv,pw;
00813 double s;
00814 int i,sh2,sv2;
00815 if(sp == SkSelectedNode1)s=(double)TVsizeX/5;
00816 else s=(double)TVsizeX/20;
00817 for(i=0;i<3;i++){
00818 pu[i]=(long)(s * sp->u[i]) + sp->xyz[i];
00819 pv[i]=(long)(s * sp->v[i]) + sp->xyz[i];
00820 pw[i]=(long)(s * sp->w[i]) + sp->xyz[i];
00821 }
00822 holdPen=SelectObject(hDC,ghSelectorPen);
00823 GetWindowCoords(view,pu[0],pu[1],pu[2],&sh2,&sv2);
00824 MoveToEx(hDC,sh1,sv1,NULL); LineTo(hDC,sh2,sv2);
00825 SelectObject(hDC,ghDeselectorPen);
00826 GetWindowCoords(view,pw[0],pw[1],pw[2],&sh2,&sv2);
00827 MoveToEx(hDC,sh1,sv1,NULL); LineTo(hDC,sh2,sv2);
00828 SelectObject(hDC,holdPen);
00829 }
00830
00831 static void DrawSkeletonRubberBone(skel *sp1, int view, HDC hDC){
00832 HPEN holdPen;
00833 int sh1,sv1,sh2,sv2,dx,dy;
00834 skel *sp;
00835 sp=sp1;
00836 holdPen=SelectObject(hDC,ghDeselectorPen);
00837 GetWindowCoords(view,sp->xyz[0],sp->xyz[1],sp->xyz[2],&sh1,&sv1);
00838 if(view == TRITOP) GetWindowCoords(view,sp->xyz[0]+(long)(sp->wrange*ruler),sp->xyz[1],sp->xyz[2],&sh2,&sv2);
00839 else if(view == TRIFRONT)GetWindowCoords(view,sp->xyz[0]+(long)(sp->wrange*ruler),sp->xyz[1],sp->xyz[2],&sh2,&sv2);
00840 else if(view == TRIRIGHT)GetWindowCoords(view,sp->xyz[0],sp->xyz[1]+(long)(sp->wrange*ruler),sp->xyz[2],&sh2,&sv2);
00841 dy=dx=sh2-sh1;
00842 Ellipse(hDC,sh1-dx,sv1-dy,sh1+dx,sv1+dy);
00843 if((sp=sp1->at) != NULL && fabs(sp->wrange-sp1->wrange) > 0.1){
00844 GetWindowCoords(view,sp->xyz[0],sp->xyz[1],sp->xyz[2],&sh1,&sv1);
00845 if(view == TRITOP) GetWindowCoords(view,sp->xyz[0]+(long)(sp1->wrange*ruler),sp->xyz[1],sp->xyz[2],&sh2,&sv2);
00846 else if(view == TRIFRONT)GetWindowCoords(view,sp->xyz[0]+(long)(sp1->wrange*ruler),sp->xyz[1],sp->xyz[2],&sh2,&sv2);
00847 else if(view == TRIRIGHT)GetWindowCoords(view,sp->xyz[0],sp->xyz[1]+(long)(sp->wrange*ruler),sp->xyz[2],&sh2,&sv2);
00848 dy=dx=sh2-sh1;
00849 Ellipse(hDC,sh1-dx,sv1-dy,sh1+dx,sv1+dy);
00850 }
00851
00852 SelectObject(hDC,holdPen);
00853 }
00854
00855 void DrawSkeletonInOne(HDC hDC, int view){
00856 HBRUSH holdBrush;
00857 HPEN holdPen;
00858 int oldROP;
00859 int sh1,sv1,sh2,sv2,i;
00860 skel *sp;
00861 holdPen=SelectObject(hDC,ghInvertPen);
00862 holdBrush=SelectObject(hDC,GetStockObject(HOLLOW_BRUSH));
00863 oldROP=SetROP2(hDC,R2_XORPEN);
00864 SelectPalette(hDC,ghpaletteScreen,FALSE);
00865 RealizePalette(hDC);
00866 DrawOne3dCursor(hDC,view);
00867 sp=MainSp;
00868 while(sp != NULL){
00869 if(skintriview(sp->xyz) || (sp->at != NULL && skintriview(sp->at->xyz))){
00870 GetWindowCoords(view,sp->xyz[0],sp->xyz[1],sp->xyz[2],&sh1,&sv1);
00871 if(sp->at != NULL){
00872 GetWindowCoords(view,sp->at->xyz[0],
00873 sp->at->xyz[1],sp->at->xyz[2],&sh2,&sv2);
00874 MoveToEx(hDC,sh1,sv1,NULL); LineTo(hDC,sh2,sv2);
00875 }
00876 if(sp == FirstSp)Rectangle(hDC,sh1-4,sv1-4,sh1+5,sv1+5);
00877 else Ellipse(hDC,sh1-3,sv1-3,sh1+4,sv1+4);
00878 DrawSkeletonAxes(sp,view,sh1,sv1,hDC);
00879 DrawSkeletonRubberBone(sp,view,hDC);
00880 }
00881 sp=sp->last;
00882 }
00883 DrawOne3dCursor(hDC,view);
00884 SelectObject(hDC,holdPen);
00885 SelectObject(hDC,holdBrush);
00886 SetROP2(hDC,oldROP);
00887 }
00888
00889 void TidyUpOldSkeltonType(void){
00890 skel *sp;
00891 if((sp=FirstSp) != NULL)while(sp != NULL){
00892 DefaultOrientAxes(sp);
00893 GetSkeletonBoundBox(sp,0);
00894 sp=sp->next;
00895 }
00896 }
00897
00898 void TabSkeletonAxis(void){
00899 SelectedSkeletonAxis++;
00900 if(SelectedSkeletonAxis > 3)SelectedSkeletonAxis=0;
00901 DrawModel();
00902 }
00903
00904 void SkToolOn(void){
00905 LastSkeletonVertex=NULL;
00906 SkSelectedNode1=NULL; SkSelectedNode2=NULL;
00907 if(tool == SKANIMATE){
00908 short i;
00909 skel *sp;
00910 if((sp=MainSp) != NULL)while(sp != NULL){
00911 null_transform(sp->t);
00912 for(i=0;i<3;i++)sp->tp[i]=sp->xyz[i];
00913 sp=sp->last;
00914 }
00915 Save_Undo(1);
00916 }
00917 else if(tool == SKRUBBERBONES)Save_Undo(1);
00918 }
00919
00920 void SkToolOff(void){
00921 LastSkeletonVertex=NULL;
00922 SkSelectedNode1=NULL; SkSelectedNode2=NULL;
00923 if(tool == SKANIMATE){
00924 int i;
00925 double x,y,z;
00926 vector p;
00927 skel *sp;
00928 vertex *vp;
00929 if((sp=MainSp) != NULL)while(sp != NULL){
00930 for(i=0;i<3;i++)sp->xyz[i]=sp->tp[i];
00931 sp=sp->last;
00932 }
00933 if((vp=MainVp) != NULL && Nvert > 0)for(i=0;i<Nvert;i++){
00934 if(vp->sp != NULL){
00935 m4by1(vp->sp->t,(double)vp->xyz[0],(double)vp->xyz[1]
00936 ,(double)vp->xyz[2],&x,&y,&z);
00937 vp->xyz[0]=(long)x; vp->xyz[1]=(long)y; vp->xyz[2]=(long)z;
00938 }
00939 vp++;
00940 }
00941 if((sp=MainSp) != NULL)while(sp != NULL){
00942 for(i=0;i<8;i++){
00943 m4by1(sp->t,(double)sp->bx[i][0],(double)sp->bx[i][1]
00944 ,(double)sp->bx[i][2],&x,&y,&z);
00945 sp->bx[i][0]=(long)x; sp->bx[i][1]=(long)y; sp->bx[i][2]=(long)z;
00946 }
00947 VECSCALE((double)UNIT2*1000.0,sp->u,p) VECSUM(p,(double)sp->xyz,p)
00948 m4by1(sp->t,p[0],p[1],p[2],&(sp->u[0]),&(sp->u[1]),&(sp->u[2]));
00949 VECSUB(sp->u,(double)sp->xyz,sp->u) O_normalize(sp->u);
00950 VECSCALE((double)UNIT2*1000.0,sp->v,p) VECSUM(p,(double)sp->xyz,p)
00951 m4by1(sp->t,p[0],p[1],p[2],&(sp->v[0]),&(sp->v[1]),&(sp->v[2]));
00952 VECSUB(sp->v,(double)sp->xyz,sp->v) O_normalize(sp->v);
00953 VECSCALE((double)UNIT2*1000.0,sp->w,p) VECSUM(p,(double)sp->xyz,p)
00954 m4by1(sp->t,p[0],p[1],p[2],&(sp->w[0]),&(sp->w[1]),&(sp->w[2]));
00955 VECSUB(sp->w,(double)sp->xyz,sp->w) O_normalize(sp->w);
00956 sp=sp->last;
00957 }
00958 }
00959 }
00960
00961 void SkToolDown(int x, int y){
00962 SkMovedFlag=FALSE;
00963 if(tool == SKADD){
00964 SkAssNode=NULL;
00965 if(LastSkeletonVertex != NULL){
00966 LastSkeletonPoint[0]=NpointerX;
00967 LastSkeletonPoint[1]=NpointerY;
00968 LastSkeletonPoint[2]=NpointerZ;
00969 DrawRubber3dLine(LastSkeletonPoint,LastSkeletonVertex->xyz);
00970 }
00971 else{
00972 LastSkeletonVertex=PickSkeleton(x,y,ActiveView);
00973 if(LastSkeletonVertex != NULL){
00974 LastSkeletonPoint[0]=NpointerX;
00975 LastSkeletonPoint[1]=NpointerY;
00976 LastSkeletonPoint[2]=NpointerZ;
00977 DrawRubber3dLine(LastSkeletonPoint,LastSkeletonVertex->xyz);
00978 }
00979 }
00980 }
00981 else if(tool == SKGRAB){
00982 LastSkeletonVertex=NULL;
00983 if(!(GetAsyncKeyState(VK_CONTROL) & 0x8000))
00984 LastSkeletonVertex=PickSkeleton(x,y,ActiveView);
00985 }
00986 else if(tool == SKRENAME){
00987 LastSkeletonVertex=NULL;
00988 if(!(GetAsyncKeyState(VK_CONTROL) & 0x8000))
00989 LastSkeletonVertex=PickSkeleton(x,y,ActiveView);
00990 }
00991 else if(tool == SKRUBBERBONES){
00992 skel *sp;
00993 int i;
00994 LastSkeletonVertex=NULL;
00995 if(GetKeyState(VK_MENU) & 0x8000)SkRubberBonesRotate=TRUE;
00996 LastSkeletonVertex=PickSkeleton(x,y,ActiveView);
00997 sp=MainSp;
00998 while(sp != NULL){
00999 VECCOPY(sp->xyz,sp->xyz_last);
01000 null_transform(sp->t);
01001 null_transform(sp->tr);
01002 for(i=0;i<3;i++)sp->tp[i]=sp->xyz[i];
01003 sp=sp->last;
01004 }
01005 }
01006 else if(tool == SKTWIST){
01007 LastSkeletonVertex=NULL;
01008 if(!(GetAsyncKeyState(VK_CONTROL) & 0x8000))
01009 LastSkeletonVertex=PickSkeleton(x,y,ActiveView);
01010 if(LastSkeletonVertex != NULL){
01011 DrawSkeleton(); SkSelectedNode1=LastSkeletonVertex; DrawSkeleton();
01012 }
01013 }
01014 else if(tool == SKDUPLICATE || tool == SKSELECT){
01015 LastSkeletonVertex=NULL;
01016 if(!(GetAsyncKeyState(VK_CONTROL) & 0x8000))SkToolAction(x,y);
01017 }
01018 else if(tool == SKDELETE || tool == SKSUBDIV || tool == SKASSIGN){
01019 LastSkeletonVertex=NULL;
01020 if(!(GetAsyncKeyState(VK_CONTROL) & 0x8000))SkToolAction(x,y);
01021 }
01022 else if(tool == SKANIMATE){
01023 long x1,y1,z1;
01024 skel *sp,*sf;
01025 double d,dmin,dth;
01026 int sho,svo;
01027 sp=MainSp; sf=NULL;
01028 dmin=(double)TVsizeX*(double)TVsizeX;
01029 dth=dmin/32/32;
01030 while(sp != NULL){
01031 GetWindowCoords(ActiveView,sp->tp[0],sp->tp[1],sp->tp[2],&sho,&svo);
01032 if( (sho > x-4) && (sho < x+4) && (svo > y-4) && (svo < y+4)){
01033 d=(double)(sp->tp[0]-NpointerX)*(double)(sp->tp[0]-NpointerX)
01034 +(double)(sp->tp[1]-NpointerY)*(double)(sp->tp[1]-NpointerY)
01035 +(double)(sp->tp[2]-NpointerZ)*(double)(sp->tp[2]-NpointerZ);
01036 if(d < dmin){
01037 dmin=d;
01038 sf=sp;
01039 }
01040 }
01041 sp=sp->last;
01042 }
01043 if(sf != NULL){
01044 LastSkeletonVertex=sf;
01045 if(sf->at != NULL){
01046 SkSelectedNode1=sf->at;
01047 SkSelectedNode2=sf;
01048 }
01049 else{
01050 SkSelectedNode1=sf;
01051 SkSelectedNode2=NULL;
01052 }
01053 DrawModel();
01054 }
01055 }
01056 }
01057
01058 void SkToolUp(int x, int y){
01059 if(tool == SKADD){
01060 if(LastSkeletonVertex != NULL){
01061 LastSkeletonPoint[0]=NpointerX;
01062 LastSkeletonPoint[1]=NpointerY;
01063 LastSkeletonPoint[2]=NpointerZ;
01064 DrawRubber3dLine(LastSkeletonPoint,LastSkeletonVertex->xyz);
01065 if(SkMovedFlag && !(GetAsyncKeyState(VK_CONTROL) & 0x8000)){
01066
01067 SkToolAction(x,y);
01068 }
01069 }
01070 if(SkAssNode != NULL){
01071 DrawSkeleton();
01072 Read1String3Real("Bone Properties","Name","Weight","Range(Ruler)","Zone(Ruler)",SkAssNode->name,
01073 &(SkAssNode->weight),&(SkAssNode->wrange),&(SkAssNode->wzone),ghwnd_main);
01074 DrawSkeleton();
01075 SkAssNode=NULL;
01076 }
01077 }
01078 else if(tool == SKRENAME){
01079 if(LastSkeletonVertex != NULL){
01080 DrawSkeleton();
01081 Read1String3Real("Bone Properties","Name","Weight","Range (Ruler)","Zone(Ruler)",LastSkeletonVertex->name,
01082 &(LastSkeletonVertex->weight),&(LastSkeletonVertex->wrange),&(LastSkeletonVertex->wzone),ghwnd_main);
01083 DrawSkeleton();
01084 }
01085 LastSkeletonVertex=NULL;
01086 }
01087 else if(tool == SKGRAB){
01088 LastSkeletonVertex=NULL;
01089 }
01090 else if(tool == SKRUBBERBONES){
01091 LastSkeletonVertex=NULL;
01092 if(SkRubberBonesRotate)RubberBonesDeform();
01093 else RubberBonesDeform();
01094 SkRubberBonesRotate=FALSE;
01095 DrawModel();
01096 if(ghwndOpenGLview == NULL)Draw3dView(0,0);
01097 else PostMessage(ghwndOpenGLview,(WM_USER+2),0,0);
01098 }
01099 else if(tool == SKTWIST){
01100 LastSkeletonVertex=NULL;
01101 if(SkSelectedNode1 != NULL){
01102 DrawSkeleton(); SkSelectedNode1=NULL; DrawSkeleton();
01103 }
01104 SkSelectedNode1=NULL;
01105 }
01106 else if(tool == SKDUPLICATE && LastSkeletonVertex != NULL){
01107 LastSkeletonVertex=NULL;
01108 }
01109 else if(tool == SKSELECT && LastSkeletonVertex != NULL){
01110 int op1,op2;
01111 if(GetAsyncKeyState(VK_SHIFT) & 0x8000)op1=DESELECTED;
01112 else op1=SELECTED;
01113 if(GetAsyncKeyState(VK_CONTROL) & 0x8000)op2=1;
01114 else op2=0;
01115 SelectBySk(LastSkeletonVertex,op1,op2);
01116 LastSkeletonVertex=NULL;
01117 }
01118 }
01119
01120 void SkToolMove(int x, int y){
01121 SkMovedFlag=TRUE;
01122 if(tool != SKTWIST && tool != SKANIMATE)Move3dCursor(0,x,y);
01123 if(tool == SKADD){
01124 if(LastSkeletonVertex != NULL){
01125 DrawRubber3dLine(LastSkeletonPoint,LastSkeletonVertex->xyz);
01126 LastSkeletonPoint[0]=NpointerX;
01127 LastSkeletonPoint[1]=NpointerY;
01128 LastSkeletonPoint[2]=NpointerZ;
01129 DrawRubber3dLine(LastSkeletonPoint,LastSkeletonVertex->xyz);
01130 }
01131 }
01132 else if(tool == SKGRAB){
01133 if(LastSkeletonVertex != NULL){
01134 skel *sp,*ssp,*fp;
01135 long x1,y1,z1,dx,dy,dz;
01136 DrawSkeleton();
01137 GetWorldCoords(ActiveView,&x1,&y1,&z1,x,y);
01138 sp=LastSkeletonVertex;
01139 if (ActiveView == TRITOP )z1=sp->xyz[2];
01140 else if(ActiveView == TRIFRONT)y1=sp->xyz[1];
01141 else if(ActiveView == TRIRIGHT)x1=sp->xyz[0];
01142 dx=x1-sp->xyz[0]; dy=y1-sp->xyz[1]; dz=z1-sp->xyz[2];
01143 if(GetAsyncKeyState(VK_SHIFT) & 0x8000){
01144 ssp=MainSp; while(ssp != NULL){
01145 fp=ssp; while(fp != NULL){
01146 if(fp == sp){
01147 ssp->xyz[0] += dx; ssp->xyz[1] += dy; ssp->xyz[2] += dz;
01148 break;
01149 }
01150 fp=fp->at;
01151 }
01152 ssp=ssp->last;
01153 }
01154 DefaultOrientAxes(sp);
01155 GetSkeletonBoundBox(sp,0);
01156 }
01157 else{
01158 sp->xyz[0]=x1; sp->xyz[1]=y1; sp->xyz[2]=z1;
01159 ssp=MainSp; while(ssp != NULL){
01160 fp=ssp; while(fp != NULL){
01161 if(fp == sp){
01162 DefaultOrientAxes(ssp);
01163 GetSkeletonBoundBox(sp,0);
01164 break;
01165 }
01166 fp=fp->at;
01167 }
01168 ssp=ssp->last;
01169 }
01170 }
01171 DrawSkeleton();
01172 }
01173 }
01174 else if(tool == SKRUBBERBONES){
01175 if(SkRubberBonesRotate){
01176 SkRotateRubberBones();
01177 }
01178 else if(LastSkeletonVertex != NULL){
01179 skel *sp,*ssp,*fp;
01180 long x1,y1,z1,dx,dy,dz;
01181 DrawSkeleton();
01182 GetWorldCoords(ActiveView,&x1,&y1,&z1,x,y);
01183 sp=LastSkeletonVertex;
01184 if (ActiveView == TRITOP )z1=sp->xyz[2];
01185 else if(ActiveView == TRIFRONT)y1=sp->xyz[1];
01186 else if(ActiveView == TRIRIGHT)x1=sp->xyz[0];
01187 dx=x1-sp->xyz[0]; dy=y1-sp->xyz[1]; dz=z1-sp->xyz[2];
01188 if(GetAsyncKeyState(VK_SHIFT) & 0x8000){
01189 ssp=MainSp; while(ssp != NULL){
01190 fp=ssp; while(fp != NULL){
01191 if(fp == sp){
01192 ssp->xyz[0] += dx; ssp->xyz[1] += dy; ssp->xyz[2] += dz;
01193 break;
01194 }
01195 fp=fp->at;
01196 }
01197 ssp=ssp->last;
01198 }
01199 DefaultOrientAxes(sp);
01200 GetSkeletonBoundBox(sp,0);
01201 }
01202 else if(GetAsyncKeyState(VK_CONTROL) & 0x8000){
01203 sp->xyz[0]=x1; sp->xyz[1]=y1; sp->xyz[2]=z1;
01204 if((ssp=sp->at) !=NULL){ ssp->xyz[0] += dx; ssp->xyz[1] += dy; ssp->xyz[2] += dz;}
01205 ssp=MainSp; while(ssp != NULL){
01206 fp=ssp; while(fp != NULL){
01207 if(fp == sp){
01208 DefaultOrientAxes(ssp);
01209 GetSkeletonBoundBox(sp,0);
01210 break;
01211 }
01212 fp=fp->at;
01213 }
01214 ssp=ssp->last;
01215 }
01216 }
01217 else{
01218 sp->xyz[0]=x1; sp->xyz[1]=y1; sp->xyz[2]=z1;
01219 ssp=MainSp; while(ssp != NULL){
01220 fp=ssp; while(fp != NULL){
01221 if(fp == sp){
01222 DefaultOrientAxes(ssp);
01223 GetSkeletonBoundBox(sp,0);
01224 break;
01225 }
01226 fp=fp->at;
01227 }
01228 ssp=ssp->last;
01229 }
01230 }
01231 DrawSkeleton();
01232 }
01233 }
01234 else if(tool == SKTWIST){
01235 if(LastSkeletonVertex != NULL)SkTwist();
01236 else Move3dCursor(0,x,y);
01237 }
01238 else if(tool == SKANIMATE){
01239 if(LastSkeletonVertex != NULL)SkPivot();
01240 else Move3dCursor(0,x,y);
01241 }
01242 }
01243
01244 void SkToolAction(int x, int y){
01245 if(tool == SKADD){
01246 if(LastSkeletonVertex != NULL){
01247
01248 DrawSkeleton();
01249 if(IsWindow(ghwndSkEdit)){
01250 MessageBeep(MB_OK);
01251 LastSkeletonVertex=NULL;
01252 SkAssNode=MainSp;
01253 }
01254 else{
01255 CreateSkeleton(LastSkeletonVertex);
01256 LastSkeletonVertex=NULL;
01257 DefaultOrientAxes(MainSp);
01258 GetSkeletonBoundBox(MainSp,0);
01259 SkAssNode=MainSp;
01260 }
01261 DrawSkeleton();
01262 while(GetAsyncKeyState(VK_LBUTTON) & 0x8000 ||
01263 GetAsyncKeyState(VK_RBUTTON) & 0x8000){;}
01264 }
01265 else{
01266
01267 }
01268
01269
01270
01271
01272
01273
01274 }
01275 else if(tool == SKGRAB){
01276
01277
01278
01279 }
01280 else if(tool == SKTWIST){
01281
01282
01283
01284
01285
01286
01287 }
01288 else if(tool == SKDELETE){
01289 if(IsWindow(ghwndSkEdit))MessageBeep(MB_OK);
01290 else{
01291 LastSkeletonVertex=PickSkeleton(x,y,ActiveView);
01292 if(LastSkeletonVertex != NULL && LastSkeletonVertex != FirstSp){
01293 DrawSkeleton();
01294 SkDelete(LastSkeletonVertex);
01295 DrawSkeleton();
01296 }
01297 LastSkeletonVertex=NULL;
01298 }
01299 }
01300 else if(tool == SKSUBDIV){
01301 long l,nx,ny,nz;
01302 skel *sp,*tsp,*ssp;
01303 vertex *vp;
01304 if(IsWindow(ghwndSkEdit))MessageBeep(MB_OK);
01305 else{
01306 if((sp=PickSkeleton(x,y,ActiveView)) != NULL){
01307 DrawSkeleton();
01308 if(sp == FirstSp){
01309 tsp=MainSp;
01310 CreateSkeleton(FirstSp);
01311 VECCOPY(FirstSp->xyz,MainSp->xyz)
01312 ssp=tsp; while(ssp != NULL){
01313 if(ssp->at == FirstSp)ssp->at=MainSp;
01314 ssp=ssp->last;
01315 }
01316 if((vp=MainVp) != NULL)for(l=0;l<Nvert;l++,vp++){
01317 if(vp->sp == FirstSp)vp->sp=MainSp;
01318 }
01319 }
01320 else{
01321 nx=(sp->xyz[0]+sp->at->xyz[0])/2;
01322 ny=(sp->xyz[1]+sp->at->xyz[1])/2;
01323 nz=(sp->xyz[2]+sp->at->xyz[2])/2;
01324 CreateSkeleton(sp->at);
01325 sp->at = MainSp;
01326 MainSp->xyz[0]=nx;
01327 MainSp->xyz[1]=ny;
01328 MainSp->xyz[2]=nz;
01329 DefaultOrientAxes(MainSp);
01330 ZeroSkeletonBoundingBox(MainSp);
01331 }
01332 DrawSkeleton();
01333 }
01334 }
01335 }
01336 else if(tool == SKASSIGN){
01337 skel *sp;
01338 if((sp=PickSkeleton(x,y,ActiveView)) != NULL){
01339 GetSkeletonBoundBox(sp,1);
01340 FlashWindow(ghwnd_main,TRUE);
01341 SendPrgmMessage(IDS_OK,1);
01342 }
01343 }
01344 else if(tool == SKSELECT){
01345 LastSkeletonVertex=NULL;
01346 if((LastSkeletonVertex=PickSkeleton(x,y,ActiveView)) != NULL)
01347 FlashWindow(ghwnd_main,TRUE);
01348 }
01349 else if(tool == SKDUPLICATE){
01350 long delta;
01351 skel *sp;
01352 BOOL bContinue;
01353 LastSkeletonVertex=NULL;
01354 if((sp=PickSkeleton(x,y,ActiveView)) != NULL){
01355 if(sp == FirstSp)FlashWindow(ghwnd_main,TRUE);
01356 else {
01357 DrawSkeleton();
01358 delta=TVsizeX / 10.0;
01359 CreateSkeleton(sp->at);
01360 MainSp->xyz[0]=sp->xyz[0]+delta;
01361 MainSp->xyz[1]=sp->xyz[1];
01362 MainSp->xyz[2]=sp->xyz[2];
01363 strcpy(MainSp->name,sp->name); strcat(MainSp->name,"_c");
01364 DefaultOrientAxes(MainSp);
01365 ZeroSkeletonBoundingBox(MainSp);
01366 DuplicateSkeletonChildren(sp,MainSp,MainSp,delta);
01367 DrawSkeleton();
01368 }
01369 }
01370 }
01371 }
01372
01373 static void DuplicateSkeletonChildren(skel *from, skel *to, skel *OldMainSp, long delta){
01374 skel *sp;
01375 sp=FirstSp->next; while(sp != OldMainSp){
01376 if(sp->at == from){
01377 CreateSkeleton(to);
01378 MainSp->xyz[0]=sp->xyz[0]+delta;
01379 MainSp->xyz[1]=sp->xyz[1];
01380 MainSp->xyz[2]=sp->xyz[2];
01381 strcpy(MainSp->name,sp->name); strcat(MainSp->name,"_c");
01382 DefaultOrientAxes(MainSp);
01383 DuplicateSkeletonChildren(sp,MainSp,OldMainSp,delta);
01384 }
01385 sp=sp->next;
01386 }
01387 }
01388
01389
01390
01391
01392 #define ptrNMHDR ((LPNMHDR)lparam)
01393 #define ptrNM_TREEVIEW ((NM_TREEVIEW *)lparam)
01394 #define ptrTV_DISPINFO ((TV_DISPINFO *)lparam)
01395
01396 #define IDM_SKTB_ADD 100
01397 #define IDM_SKTB_INSERT 101
01398 #define IDM_SKTB_DELETE 102
01399 #define IDM_SKTB_SELECT 103
01400 #define IDM_SKTB_DESELECT 104
01401 #define IDM_SKTB_HIDE 105
01402 #define IDM_SKTB_UNHIDE 106
01403 #define IDM_SKTB_ASSIGN 107
01404 #define IDM_SKTB_DEASSIGN 108
01405
01406 static PSTR lpszSkTreeViewClass="SkTreeViewClass";
01407 static HWND hWndTreeView=NULL;
01408 static HWND hTBWnd=NULL;
01409 static HIMAGELIST hCoasterImageList=NULL;
01410
01411 #define NTOOLBARBUTTONS 13
01412
01413 static TBBUTTON tbb[NTOOLBARBUTTONS] = {
01414 {3,IDM_SKTB_SELECT, TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0 },
01415 {4,IDM_SKTB_DESELECT, TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0 },
01416 {0,0, TBSTATE_ENABLED,TBSTYLE_SEP, 0,0 },
01417 {2,IDM_SKTB_INSERT, TBSTATE_ENABLED,TBSTYLE_BUTTON|
01418 TBSTYLE_CHECK, 0,0 },
01419 {0,0, TBSTATE_ENABLED,TBSTYLE_SEP, 0,0 },
01420 {5,IDM_SKTB_HIDE, TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0 },
01421 {6,IDM_SKTB_UNHIDE, TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0 },
01422 {0,0, TBSTATE_ENABLED,TBSTYLE_SEP, 0,0 },
01423 {7,IDM_SKTB_ASSIGN, TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0 },
01424 {8,IDM_SKTB_DEASSIGN, TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0 },
01425 {0,0, TBSTATE_ENABLED,TBSTYLE_SEP, 0,0 },
01426 {0,IDM_SKTB_ADD, TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0 },
01427 {1,IDM_SKTB_DELETE, TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0 }
01428 };
01429
01430 static HTREEITEM AddTreeViewItem (HWND hWndTV,
01431 HTREEITEM hParent,
01432 HTREEITEM hInsertAfter,
01433 int iImage,
01434 int iSelectedImage,
01435 LPSTR szText,
01436 LPARAM lParam){
01437 TV_INSERTSTRUCT tvIns;
01438 tvIns.item.mask = TVIF_TEXT | TVIF_IMAGE |
01439 TVIF_SELECTEDIMAGE | TVIF_PARAM;
01440 tvIns.item.pszText = szText;
01441 tvIns.item.cchTextMax = sizeof(szText);
01442 tvIns.item.iImage = iImage;
01443 tvIns.item.iSelectedImage = iSelectedImage;
01444 tvIns.item.lParam = lParam;
01445 tvIns.hParent = hParent;
01446 tvIns.hInsertAfter = hInsertAfter;
01447 return TreeView_InsertItem(hWndTV,&tvIns);
01448 }
01449
01450 static void AddTwigsTo(skel *parent, HWND hWndTV){
01451 skel *sp;
01452 HTREEITEM hParent;
01453 sp=FirstSp;
01454 while(sp != NULL){
01455 if(sp->at == parent){
01456 hParent=(HTREEITEM)(sp->at->lParam);
01457 sp->lParam=(LPARAM)AddTreeViewItem(hWndTV,hParent,(HTREEITEM)TVI_FIRST,
01458 0,1,
01459 (LPSTR)sp->name,
01460 (LPARAM)sp);
01461 AddTwigsTo(sp,hWndTV);
01462 }
01463 sp=sp->next;
01464 }
01465 }
01466
01467 static BOOL TreeViewRecursive(skel *spTarget, skel *spDrag){
01468 skel *sp;
01469 while(spTarget != NULL){
01470 if(spTarget == spDrag)return TRUE;
01471 spTarget=spTarget->at;
01472 }
01473 return FALSE;
01474 }
01475
01476 static BOOL TreeviewMenuCommand(HWND hWnd, WORD id){
01477 long i;
01478 BOOL bFound;
01479 vertex *vp;
01480 skel *sp,*spp;
01481 HTREEITEM hTarget;
01482 TV_ITEM tvi;
01483 if(id == IDM_SKTB_INSERT){
01484 SkSelectFlag ^= 1;
01485 return TRUE;
01486 }
01487 if(sktool == YES){MessageBeep(MB_OK); return FALSE;}
01488 if((hTarget=TreeView_GetSelection(hWndTreeView)) == NULL)return FALSE;
01489 tvi.mask = TVIF_PARAM;
01490 tvi.hItem = hTarget;
01491 TreeView_GetItem(hWndTreeView,&tvi);
01492 if((sp=(skel *)tvi.lParam) == NULL)return FALSE;
01493 switch (id) {
01494 case IDM_SKTB_ADD:
01495 CreateSkeleton(sp);
01496 MainSp->lParam=(LPARAM)AddTreeViewItem(hWndTreeView,hTarget,
01497 (HTREEITEM)TVI_FIRST,
01498 0,1,
01499 (LPSTR)MainSp->name,
01500 (LPARAM)MainSp);
01501 TreeView_EnsureVisible(hWndTreeView,(HTREEITEM)MainSp->lParam);
01502 TreeView_SelectItem(hWndTreeView,(HTREEITEM)MainSp->lParam);
01503 break;
01504 case IDM_SKTB_DELETE:
01505 if(sp == FirstSp)break;
01506 TreeView_DeleteItem(hWndTreeView,hTarget);
01507 while(1){
01508 bFound=FALSE;
01509 spp=FirstSp; while(spp != NULL){
01510 if(spp != sp && TreeViewRecursive(spp,sp)){
01511 SkDelete(spp);
01512 bFound=TRUE;
01513 goto BKOUT;
01514 }
01515 spp=spp->next;
01516 }
01517 BKOUT:
01518 if(!bFound)break;
01519 }
01520 SkDelete(sp);
01521 break;
01522 case IDM_SKTB_SELECT:
01523 SelectByHierarchy(sp,1);
01524 break;
01525 case IDM_SKTB_DESELECT:
01526 SelectByHierarchy(sp,2);
01527 break;
01528 case IDM_SKTB_HIDE:
01529 SelectByHierarchy(sp,3);
01530 break;
01531 case IDM_SKTB_UNHIDE:
01532 SelectByHierarchy(sp,4);
01533 break;
01534 case IDM_SKTB_ASSIGN:
01535 GetSkeletonBoundBox(sp,1);
01536 break;
01537 case IDM_SKTB_DEASSIGN:
01538 if((vp=MainVp) != NULL)for(i=0;i<Nvert;i++,vp++){
01539 if(vp->sp == sp)vp->sp=NULL;
01540 }
01541 break;
01542 default:
01543 break;
01544 }
01545 return TRUE;
01546 }
01547
01548 static BOOL CALLBACK SkTreeViewWndProc(HWND hwnd, UINT msg, WPARAM wparam,
01549 LPARAM lparam ){
01550 static HIMAGELIST hDragImage=NULL;
01551 static HTREEITEM hDragItem=NULL;
01552 static BOOL bDragging=FALSE;
01553 static int ToolbarHeight;
01554 RECT rc,rc1;
01555 int dx,dy,x,y,xp,yp,xl,yl;
01556 DWORD dwStyle;
01557 skel *sp;
01558 switch( msg ){
01559 case WM_PAINT:
01560 PaintDialogBackground(hwnd,ghinst_main);
01561 break;
01562 case WM_INITDIALOG:
01563 SetClassLong(hwnd,GCL_HICON,
01564 (LONG)LoadIcon(ghinst_main,"MODELERICON"));
01565 xp=GetPrivateProfileInt(IniSection,"SKPOSX",-1,IniFilename);
01566 yp=GetPrivateProfileInt(IniSection,"SKPOSY",-1,IniFilename);
01567 xl=GetPrivateProfileInt(IniSection,"SKSIZX",-1,IniFilename);
01568 yl=GetPrivateProfileInt(IniSection,"SKSIZY",-1,IniFilename);
01569 if(xp < 0 || yp < 0 || xl < 0 || yl < 0){
01570 x=200; y=40; dx=248; dy=250;
01571 }
01572 else{
01573 x=xp; y=yp; dx=xl; dy=yl;
01574 }
01575 SetWindowPos(hwnd,NULL,x,y,dx,dy,SWP_NOZORDER);
01576
01577 dwStyle=WS_CHILD | WS_VISIBLE | WS_BORDER;
01578 if(Preferences.tooltips)dwStyle = dwStyle | TBSTYLE_TOOLTIPS;
01579 hTBWnd = CreateToolbarEx(hwnd,dwStyle,
01580 0,
01581 9,
01582 ghinst_main,
01583 IDBM_SKTOOLBAR,
01584 tbb,
01585 NTOOLBARBUTTONS,
01586 16,15,
01587 16,15,
01588 sizeof(TBBUTTON)
01589 );
01590 if(0){dx=32; dy=32;} else {dx=16; dy=16;}
01591 hCoasterImageList=ImageList_Create(
01592 dx,dy,
01593 TRUE,
01594 2,
01595 5
01596 );
01597 ImageList_AddIcon(hCoasterImageList,
01598 LoadIcon(ghinst_main,"TREEVIEWICON0"));
01599 ImageList_AddIcon(hCoasterImageList,
01600 LoadIcon(ghinst_main,"TREEVIEWICON1"));
01601 GetClientRect(hTBWnd,&rc1); ToolbarHeight=rc1.bottom+1;
01602 GetClientRect(hwnd,&rc);
01603
01604 hWndTreeView=GetDlgItem(hwnd,DLG_SKELETON_TREEVIEW);
01605 SetWindowPos(hWndTreeView,NULL,0,ToolbarHeight,
01606 rc.right,rc.bottom-ToolbarHeight,SWP_NOZORDER);
01607 if(hWndTreeView != NULL){
01608 TreeView_SetImageList(hWndTreeView,hCoasterImageList,0);
01609 ImageList_SetBkColor(hCoasterImageList,GetSysColor(COLOR_WINDOW));
01610 UpdateSkTreeView();
01611 sp=MainSp; while(sp != NULL){
01612 if(sp->at == FirstSp){
01613 TreeView_EnsureVisible(hWndTreeView,(HTREEITEM)(sp->lParam));
01614 TreeView_Expand(hWndTreeView,(HTREEITEM)(sp->lParam),TVE_EXPAND);
01615 }
01616 sp=sp->last;
01617 }
01618 }
01619 return TRUE;
01620 case WM_DESTROY:{
01621 char str[32];
01622 GetWindowRect(hwnd,&rc);
01623 sprintf(str,"%ld",rc.left);
01624 WritePrivateProfileString(IniSection,"SKPOSX",str,IniFilename);
01625 sprintf(str,"%ld",rc.top);
01626 WritePrivateProfileString(IniSection,"SKPOSY",str,IniFilename);
01627 sprintf(str,"%ld",rc.right-rc.left);
01628 WritePrivateProfileString(IniSection,"SKSIZX",str,IniFilename);
01629 sprintf(str,"%ld",rc.bottom-rc.top);
01630 WritePrivateProfileString(IniSection,"SKSIZY",str,IniFilename);
01631 if(hCoasterImageList != NULL)ImageList_Destroy(hCoasterImageList);
01632 hCoasterImageList=NULL;
01633 hWndTreeView=NULL;
01634 DestroyWindow(hTBWnd);
01635 hTBWnd=NULL;
01636 }
01637 break;
01638 case WM_SYSCOMMAND:
01639 switch(LOWORD(wparam & 0xfff0)){
01640 case SC_CLOSE:
01641 PostMessage(ghwnd_main,WM_COMMAND,IDM_HIERARCHY_NAME,0);
01642 break;
01643 default:
01644 return FALSE;
01645 }
01646 break;
01647 case WM_NOTIFY:
01648 switch (ptrNMHDR->code){
01649 case TTN_NEEDTEXT:{
01650 int idButton;
01651 LPTOOLTIPTEXT lpttt;
01652 lpttt=(LPTOOLTIPTEXT)lparam;
01653 lpttt->hinst=ghinst_main;
01654 idButton=lpttt->hdr.idFrom;
01655 switch(idButton){
01656 case IDM_SKTB_ADD:
01657 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_1); break;
01658 case IDM_SKTB_DELETE:
01659 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_2); break;
01660 case IDM_SKTB_INSERT:
01661 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_3); break;
01662 case IDM_SKTB_SELECT:
01663 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_4); break;
01664 case IDM_SKTB_DESELECT:
01665 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_5); break;
01666 case IDM_SKTB_HIDE:
01667 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_6); break;
01668 case IDM_SKTB_UNHIDE:
01669 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_7); break;
01670 case IDM_SKTB_ASSIGN:
01671 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_8); break;
01672 case IDM_SKTB_DEASSIGN:
01673 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_9); break;
01674 }
01675 }
01676 break;
01677 case TVN_BEGINLABELEDIT:
01678 if ((skel *)ptrTV_DISPINFO->item.lParam == FirstSp)return 1;
01679 else return 0;
01680 case TVN_ENDLABELEDIT:
01681 if(ptrTV_DISPINFO->item.pszText != NULL){
01682 ptrTV_DISPINFO->item.mask = TVIF_TEXT;
01683 sp=(skel *)ptrTV_DISPINFO->item.lParam;
01684 strcpy(sp->name,ptrTV_DISPINFO->item.pszText);
01685 TreeView_SetItem(
01686 ptrNMHDR->hwndFrom,
01687 &(ptrTV_DISPINFO->item)
01688 );
01689 return TRUE;
01690 }
01691 break;
01692 case TVN_BEGINDRAG:
01693 if((skel *)ptrNM_TREEVIEW->itemNew.lParam != FirstSp){
01694 hDragImage = TreeView_CreateDragImage(
01695 ptrNMHDR->hwndFrom,ptrNM_TREEVIEW->itemNew.hItem);
01696 TreeView_GetItemRect(
01697 ptrNMHDR->hwndFrom,
01698 ptrNM_TREEVIEW->itemNew.hItem,
01699 &rc,
01700 FALSE
01701 );
01702 hDragItem = ptrNM_TREEVIEW->itemNew.hItem;
01703 ImageList_SetDragCursorImage(hDragImage,0,0,0);
01704 ImageList_BeginDrag(hDragImage,0,0,0);
01705 ImageList_DragEnter(
01706 hWndTreeView,
01707 ptrNM_TREEVIEW->ptDrag.x,
01708 ptrNM_TREEVIEW->ptDrag.y
01709 );
01710 ImageList_DragShowNolock(TRUE);
01711 SetCapture(hwnd);
01712 bDragging=TRUE;
01713 return 0L;
01714 }
01715 break;
01716 default: break;
01717 }
01718 return FALSE;
01719 case WM_MOUSEMOVE:
01720 if(bDragging){
01721 HTREEITEM hTarget;
01722 TV_HITTESTINFO tvht;
01723 y=HIWORD(lparam)-ToolbarHeight;
01724 ImageList_DragMove(LOWORD(lparam),y);
01725 tvht.pt.x = LOWORD(lparam);
01726 tvht.pt.y = y;
01727 if((hTarget = TreeView_HitTest(hWndTreeView,&tvht)) != NULL){
01728 TV_ITEM tvi;
01729 tvi.mask = TVIF_PARAM;
01730 tvi.hItem = hTarget;
01731 TreeView_GetItem(hWndTreeView,&tvi);
01732 if(hTarget != TreeView_GetDropHilight(hWndTreeView)){
01733 ImageList_DragShowNolock(FALSE);
01734 TreeView_SelectDropTarget(hWndTreeView,hTarget);
01735 ImageList_DragShowNolock(TRUE);
01736 }
01737 return 0L;
01738 }
01739 if(hTarget != TreeView_GetDropHilight(hWndTreeView)){
01740 ImageList_DragShowNolock(FALSE);
01741 TreeView_SelectDropTarget(hWndTreeView,NULL);
01742 ImageList_DragShowNolock(TRUE);
01743 }
01744 }
01745 break;
01746 case WM_LBUTTONUP:
01747 if(bDragging){
01748 HTREEITEM hTarget;
01749 TV_ITEM tvi;
01750 skel *spTarget,*spDrag;
01751 ImageList_DragLeave(hWndTreeView);
01752 ImageList_EndDrag();
01753 ReleaseCapture();
01754 bDragging = FALSE;
01755 ImageList_Destroy(hDragImage);
01756 hDragImage = NULL;
01757 if((hTarget = TreeView_GetDropHilight(hWndTreeView)) != NULL){
01758 if(hTarget != hDragItem){
01759 tvi.mask = TVIF_PARAM;
01760 tvi.hItem = hDragItem;
01761 TreeView_GetItem(hWndTreeView,&tvi);
01762 spDrag=(skel *)tvi.lParam;
01763 tvi.hItem = hTarget;
01764 TreeView_GetItem(hWndTreeView,&tvi);
01765 spTarget=(skel *)tvi.lParam;
01766 if(sktool == NO && !TreeViewRecursive(spTarget,spDrag)){
01767 spDrag->at=spTarget;
01768 TreeView_DeleteItem(hWndTreeView,hDragItem);
01769 spDrag->lParam=(LPARAM)AddTreeViewItem(hWndTreeView,
01770 (HTREEITEM)spTarget->lParam,
01771 (HTREEITEM)TVI_FIRST,
01772 0,1,
01773 (LPSTR)spDrag->name,
01774 (LPARAM)spDrag);
01775 AddTwigsTo(spDrag,hWndTreeView);
01776 }
01777 else MessageBeep(MB_OK);
01778 }
01779 }
01780 TreeView_SelectDropTarget(hWndTreeView,NULL);
01781 }
01782 break;
01783 case WM_COMMAND:
01784
01785 if(LOWORD(wparam) == IDOK){;}
01786 else TreeviewMenuCommand(hwnd,LOWORD(wparam));
01787 break;
01788 case WM_SIZE:
01789 if(hTBWnd != NULL)SendMessage(hTBWnd,msg,wparam,lparam);
01790 if(hWndTreeView != NULL){
01791 SetWindowPos(hWndTreeView,NULL,
01792 0,ToolbarHeight,
01793 LOWORD(lparam),HIWORD(lparam)-ToolbarHeight,
01794 SWP_NOZORDER);
01795 }
01796 default:
01797 break;
01798 }
01799 return FALSE;
01800 }
01801
01802 void SkeletonTreeView(HWND hWndParent){
01803 WNDCLASS wc;
01804 HDC hdc,hdcMem;
01805 RECT rc;
01806 HBITMAP hbm,hbmold=NULL;
01807 char str[32];
01808 MSG msg;
01809 int x,y,dx,dy;
01810 if(ghwndSkEdit != NULL){
01811 DestroyWindow(ghwndSkEdit);
01812 ghwndSkEdit=NULL;
01813 return;
01814 }
01815 ghwndSkEdit=CreateDialog(ghinst_main,MAKEINTRESOURCE(DLG_SKELETON),
01816 hWndParent,(DLGPROC)SkTreeViewWndProc);
01817 UpdateWindow(ghwndSkEdit);
01818 if(ghwndSkEdit == NULL){
01819 return;
01820 }
01821 SendMessage(hTBWnd,TB_CHECKBUTTON,IDM_SKTB_INSERT,
01822 (LPARAM)MAKELONG(SkSelectFlag,0));
01823 return;
01824 }
01825
01826 void UpdateSkTreeView(void){
01827 if(!IsWindow(hWndTreeView))return;
01828 TreeView_DeleteItem(hWndTreeView,TVI_ROOT);
01829 FirstSp->lParam=(LPARAM)AddTreeViewItem(hWndTreeView,
01830 TVI_ROOT,
01831 (HTREEITEM)TVI_FIRST,
01832 0,1,
01833 (LPSTR)FirstSp->name,
01834 (LPARAM)FirstSp);
01835 AddTwigsTo(FirstSp,hWndTreeView);
01836 }
01837
01839
01840
01841 void SetSkToolbarState(BOOL state){
01842 int i;
01843 if(!IsWindow(ghwndSkEdit))return;
01844 for(i=0;i<NTOOLBARBUTTONS;i++)SendMessage(hTBWnd,
01845 TB_ENABLEBUTTON,(WPARAM)tbb[i].idCommand,(LPARAM)MAKELONG(state,0));
01846 }
01847
01848 void SkeletonToolBar(HWND hWndParent){
01849 WNDCLASS wc;
01850 HDC hdc,hdcMem;
01851 RECT rc;
01852 HBITMAP hbm,hbmold=NULL;
01853 char str[32];
01854 MSG msg;
01855 int x,y,dx,dy;
01856 if(ghwndSkToolbar != NULL){
01857 DestroyWindow(ghwndSkToolbar);
01858 ghwndSkToolbar=NULL;
01859 return;
01860 }
01861 ghwndSkToolbar=CreateDialog(ghinst_main,MAKEINTRESOURCE(DLG_SKTOOLBAR),
01862 hWndParent,(DLGPROC)SkToolBarDlgProc);
01863 UpdateWindow(ghwndSkToolbar);
01864 if(ghwndSkToolbar == NULL){
01865 return;
01866 }
01867 return;
01868 }
01869
01870 static BOOL CALLBACK SkToolBarDlgProc(HWND hwnd, UINT msg, WPARAM wparam,
01871 LPARAM lparam ){
01872 static TBBUTTON tbtns[10] = {
01873 {0,DLG_SKTOOLBAR_BUILD,TBSTATE_ENABLED,TBSTYLE_BUTTON|
01874 TBSTYLE_CHECKGROUP, 0,0 },
01875 {1,DLG_SKTOOLBAR_REPOSITION,TBSTATE_ENABLED,TBSTYLE_BUTTON|
01876 TBSTYLE_CHECKGROUP, 0,0 },
01877 {2,DLG_SKTOOLBAR_ROTATION,TBSTATE_ENABLED,TBSTYLE_BUTTON|
01878 TBSTYLE_CHECKGROUP, 0,0 },
01879 {3,DLG_SKTOOLBAR_REMOVE,TBSTATE_ENABLED,TBSTYLE_BUTTON|
01880 TBSTYLE_CHECKGROUP, 0,0 },
01881 {4,DLG_SKTOOLBAR_INSERT,TBSTATE_ENABLED,TBSTYLE_BUTTON|
01882 TBSTYLE_CHECKGROUP, 0,0 },
01883 {5,DLG_SKTOOLBAR_ATTACH,TBSTATE_ENABLED,TBSTYLE_BUTTON|
01884 TBSTYLE_CHECKGROUP, 0,0 },
01885 {6,DLG_SKTOOLBAR_SELECT,TBSTATE_ENABLED,TBSTYLE_BUTTON|
01886 TBSTYLE_CHECKGROUP, 0,0 },
01887 {7,DLG_SKTOOLBAR_DUPLICATE,TBSTATE_ENABLED,TBSTYLE_BUTTON|
01888 TBSTYLE_CHECKGROUP, 0,0 },
01889 {8,DLG_SKTOOLBAR_RUBBERBONES,TBSTATE_ENABLED,TBSTYLE_BUTTON|
01890 TBSTYLE_CHECKGROUP, 0,0 },
01891 {9,DLG_SKTOOLBAR_RENAME,TBSTATE_ENABLED,TBSTYLE_BUTTON|
01892 TBSTYLE_CHECKGROUP, 0,0 }
01893 };
01894 static HWND hWndTools=NULL;
01895 DWORD dwStyle;
01896 RECT rc;
01897 int x,y,xp,yp,id;
01898 switch( msg ){
01899 case WM_INITDIALOG:
01900 xp=GetPrivateProfileInt(IniSection,"SKTOOLBOXPOSX",-1,IniFilename);
01901 yp=GetPrivateProfileInt(IniSection,"SKTOOLBOXPOSY",-1,IniFilename);
01902 if(xp < 0 || yp < 0){
01903 x=200; y=40;
01904 }
01905 else{
01906 x=xp; y=yp;
01907 }
01908 dwStyle=WS_CHILD | WS_VISIBLE | WS_BORDER;
01909 if(Preferences.tooltips)dwStyle = dwStyle | TBSTYLE_TOOLTIPS;
01910 hWndTools = CreateToolbarEx(hwnd,dwStyle,
01911 0,
01912 10,
01913 ghinst_main,
01914 IDBM_SKTOOLBAR1,
01915 tbtns,
01916 10,
01917 16,15,
01918 16,15,
01919 sizeof(TBBUTTON)
01920 );
01921 id=DLG_SKTOOLBAR_BUILD;
01922 if (tool == SKGRAB ) id=DLG_SKTOOLBAR_REPOSITION;
01923 else if(tool == SKTWIST ) id=DLG_SKTOOLBAR_ROTATION;
01924 else if(tool == SKDELETE) id=DLG_SKTOOLBAR_REMOVE;
01925 else if(tool == SKSUBDIV) id=DLG_SKTOOLBAR_INSERT;
01926 else if(tool == SKASSIGN) id=DLG_SKTOOLBAR_ATTACH;
01927 else if(tool == SKSELECT) id=DLG_SKTOOLBAR_SELECT;
01928 else if(tool == SKDUPLICATE) id=DLG_SKTOOLBAR_DUPLICATE;
01929 else if(tool == SKRUBBERBONES ) id=DLG_SKTOOLBAR_RUBBERBONES;
01930 else if(tool == SKRENAME ) id=DLG_SKTOOLBAR_RENAME;
01931 SendMessage(hWndTools,TB_CHECKBUTTON,id,MAKELONG(TRUE,0));
01932 SetWindowPos(hwnd,NULL,x,y,0,0,SWP_NOZORDER|SWP_NOSIZE);
01933 return TRUE;
01934 case WM_DESTROY:{
01935 char str[32];
01936 GetWindowRect(hwnd,&rc);
01937 sprintf(str,"%ld",rc.left);
01938 WritePrivateProfileString(IniSection,"SKTOOLBOXPOSX",str,IniFilename);
01939 sprintf(str,"%ld",rc.top);
01940 WritePrivateProfileString(IniSection,"SKTOOLBOXPOSY",str,IniFilename);
01941 if(hWndTools != NULL)DestroyWindow(hWndTools);
01942 hWndTools=NULL;
01943 }
01944 break;
01945 case WM_SYSCOMMAND:
01946 switch(LOWORD(wparam & 0xfff0)){
01947 case SC_CLOSE:
01948 PostMessage(ghwnd_main,WM_COMMAND,IDM_STOP,0);
01949 break;
01950 default:
01951 return FALSE;
01952 }
01953 break;
01954 case WM_NOTIFY:
01955 switch (ptrNMHDR->code){
01956 case TTN_NEEDTEXT:{
01957 int idButton;
01958 LPTOOLTIPTEXT lpttt;
01959 lpttt=(LPTOOLTIPTEXT)lparam;
01960 lpttt->hinst=ghinst_main;
01961 idButton=lpttt->hdr.idFrom;
01962 switch(idButton){
01963 case DLG_SKTOOLBAR_BUILD:
01964 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_KT_1); break;
01965 case DLG_SKTOOLBAR_REPOSITION:
01966 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_KT_2); break;
01967 case DLG_SKTOOLBAR_ROTATION:
01968 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_KT_3); break;
01969 case DLG_SKTOOLBAR_REMOVE:
01970 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_KT_4); break;
01971 case DLG_SKTOOLBAR_INSERT:
01972 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_KT_5); break;
01973 case DLG_SKTOOLBAR_ATTACH:
01974 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_KT_6); break;
01975 case DLG_SKTOOLBAR_SELECT:
01976 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_KT_7); break;
01977 case DLG_SKTOOLBAR_DUPLICATE:
01978 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_KT_8); break;
01979 case DLG_SKTOOLBAR_RUBBERBONES:
01980 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_KT_9); break;
01981 case DLG_SKTOOLBAR_RENAME:
01982 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_KT_10); break;
01983 }
01984 }
01985 break;
01986 default: break;
01987 }
01988 return FALSE;
01989 case WM_COMMAND:
01990 if(LOWORD(wparam) == IDOK){;}
01991 else if(LOWORD(wparam) == DLG_SKTOOLBAR_BUILD){
01992 PostMessage(ghwnd_main,WM_COMMAND,IDM_HIERARCHY_BUILD,0);
01993 }
01994 else if(LOWORD(wparam) == DLG_SKTOOLBAR_REPOSITION){
01995 PostMessage(ghwnd_main,WM_COMMAND,IDM_HIERARCHY_STRETCH,0);
01996 }
01997 else if(LOWORD(wparam) == DLG_SKTOOLBAR_ROTATION){
01998 PostMessage(ghwnd_main,WM_COMMAND,IDM_HIERARCHY_TWIST,0);
01999 }
02000 else if(LOWORD(wparam) == DLG_SKTOOLBAR_REMOVE){
02001 PostMessage(ghwnd_main,WM_COMMAND,IDM_HIERARCHY_REMOVE,0);
02002 }
02003 else if(LOWORD(wparam) == DLG_SKTOOLBAR_INSERT){
02004 PostMessage(ghwnd_main,WM_COMMAND,IDM_HIERARCHY_INSERT,0);
02005 }
02006 else if(LOWORD(wparam) == DLG_SKTOOLBAR_ATTACH){
02007 PostMessage(ghwnd_main,WM_COMMAND,IDM_HIERARCHY_ATTACH,0);
02008 }
02009 else if(LOWORD(wparam) == DLG_SKTOOLBAR_SELECT){
02010 PostMessage(ghwnd_main,WM_COMMAND,IDM_HIERARCHY_SELECT,0);
02011 }
02012 else if(LOWORD(wparam) == DLG_SKTOOLBAR_DUPLICATE){
02013 PostMessage(ghwnd_main,WM_COMMAND,IDM_HIERARCHY_DUPLICATE,0);
02014 }
02015 else if(LOWORD(wparam) == DLG_SKTOOLBAR_RUBBERBONES){
02016 PostMessage(ghwnd_main,WM_COMMAND,IDM_HIERARCHY_RUBBERBONES,0);
02017 }
02018 else if(LOWORD(wparam) == DLG_SKTOOLBAR_RENAME){
02019 PostMessage(ghwnd_main,WM_COMMAND,IDM_HIERARCHY_RENAME,0);
02020 }
02021 break;
02022 default:
02023 break;
02024 }
02025 return FALSE;
02026 }