00001
00002
00003
00004 #define MODULE_ROBOT 1
00005
00006 #define TIME_DELAY 30
00007
00008 #include <io.h>
00009 #include <fcntl.h>
00010 #include "animate.h"
00011
00012 typedef double quaternion[4];
00013
00014 static void rotate_round_vector(double angle, vector v, double t[4][4]);
00015 static void TransformAxis(skel *sid, vector v, vector vv);
00016 static void SelectRobotArm(void);
00017 static void NameRobotDirectory(char *script_file, char *robo_dir);
00018 static void EditRobotTransform(int command);
00019 static void RobotSkeletonTreeView(HWND hWndParent);
00020 static void SelectTreeViewItem(void);
00021 static void GetBasisTransform(vector x, vector y, vector z,
00022 vector u, vector v, vector w,
00023 double T[4][4]);
00024
00025 static node *LastSelectedRobotNode=NULL;
00026 static object *SelectedRobot=NULL;
00027 static long SelectedRobotArm = -1;
00028
00029 long GetRobotVolume(long n, skel *sp, vector c){
00030 long i,size=UNIT;
00031 static double xmax=UNIT2,ymax=UNIT2,zmax=UNIT2,
00032 xmin=0,ymin=0,zmin=0;
00033 if(sp != NULL){
00034 xmin=ymin=zmin = MAXUNIT;
00035 xmax=ymax=zmax = -MAXUNIT;
00036 for(i=0;i<n;i++){
00037 if(sp->p[0] > xmax)xmax=sp->p[0];
00038 if(sp->pp[0] > xmax)xmax=sp->pp[0];
00039 if(sp->p[0] < xmin)xmin=sp->p[0];
00040 if(sp->pp[0] < xmin)xmin=sp->pp[0];
00041 if(sp->p[1] > ymax)ymax=sp->p[1];
00042 if(sp->pp[1] > ymax)ymax=sp->pp[1];
00043 if(sp->p[1] < ymin)ymin=sp->p[1];
00044 if(sp->pp[1] < ymin)ymin=sp->pp[1];
00045 if(sp->p[2] > zmax)zmax=sp->p[2];
00046 if(sp->pp[2] > zmax)zmax=sp->pp[2];
00047 if(sp->p[2] < zmin)zmin=sp->p[2];
00048 if(sp->pp[2] < zmin)zmin=sp->pp[2];
00049 sp++;
00050 }
00051 }
00052 size=max(xmax-xmin,ymax-ymin);
00053 size=max(size,zmax-zmin);
00054 c[0]=(double)(xmax+xmin)*0.5;
00055 c[1]=(double)(ymax+ymin)*0.5;
00056 c[2]=(double)(zmax+zmin)*0.5;
00057 return size;
00058 }
00059
00060 void DrawRobot(HDC hdc[], object *Op, point Offset, double p, double t
00061 , double a, short im, double ima
00062 , double sx, double sy, double sz, short status){
00063 int sh1,sv1,sh2,sv2,i,j,k,ep;
00064 point v1,v2;
00065 skel *sp;
00066 double mr,RoboT[4][4],x,y,z,xx,yy,zz;
00067 int ifd,ild;
00068 if(View == TRIVIEW){ifd=0;ild=3;}
00069 else {ifd=ActiveView; ild=ifd+1;}
00070 if(status == DESELECTED)DrawActorCentre(hdc,Offset,p,t,a,im,ima,TVsizeX/24);
00071 if(status == SELECTED)DrawArrow(hdc,Offset,p,t,a,im,ima,TVsizeX/24);
00072 mr=(double)(Op->lastframe - Op->firstframe+1);
00073 mr=(double)(CurrentFrame - Op->firstframe+1)/mr;
00074 if(Op->nskeleton > 0){
00075 InterpolateRobot(mr,Op,Op->last);
00076 RobotTransform(Offset,p,t,a,sx,sy,sz,im,ima,RoboT);
00077 sp=Op->skeleton;
00078 for(k=0;k<Op->nskeleton;k++){
00079 xx=(double)sp[k].pp[0];
00080 yy=(double)sp[k].pp[1];
00081 zz=(double)sp[k].pp[2];
00082 m4by1(RoboT,xx,yy,zz,&x,&y,&z);
00083 sp[k].pt[0]=(long)x;
00084 sp[k].pt[1]=(long)y;
00085 sp[k].pt[2]=(long)z;
00086 }
00087 for(k=0;k<Op->nskeleton;k++){
00088 CopyPoint(sp[k].pt,v1);
00089 if(k > 0 && (j=sp[k].id) < Op->nskeleton)CopyPoint(sp[j].pt,v2);
00090 else CopyPoint(v1,v2);
00091 if(in_stage_triview(v1) || in_stage_triview(v2)){
00092 for(i=ifd;i<ild;i++){
00093 GetWindowCoords(i,v1[0],v1[1],v1[2],&sh1,&sv1);
00094 GetWindowCoords(i,v2[0],v2[1],v2[2],&sh2,&sv2);
00095 MoveToEx(hdc[i],sh1,sv1,NULL); LineTo(hdc[i],sh2,sv2);
00096 if(status == SELECTED){
00097 HPEN holdpen;
00098 if(k == SelectedRobotArm)holdpen=SelectObject(hdc[i],ghEditPen);
00099 Rectangle(hdc[i],(int)sh1-3,(int)sv1-3,(int)sh1+3,(int)sv1+3);
00100 if(k == SelectedRobotArm)SelectObject(hdc[i],holdpen);
00101 }
00102 }
00103 }
00104 }
00105 }
00106 }
00107
00108 void DrawFullRobot(HDC hdc[], object *Op, point Offset, double p, double t
00109 , double a, short im, double ima
00110 , double sx, double sy, double sz, short status){
00111 short morphflag;
00112 int sh1,sv1,sh2,sv2,i,j,k,ep;
00113 point xyz,*Vp;
00114 skel *sp;
00115 double mr,RoboT[4][4],ViewT[4][4],x,y,z,xx,yy,zz;
00116 int ifd,ild;
00117 long *sid,Nv;
00118 morphflag=0;
00119 if(View == TRIVIEW){ifd=0;ild=3;}
00120 else {ifd=ActiveView; ild=ifd+1;}
00121 if(status == DESELECTED)DrawActorCentre(hdc,Offset,p,t,a,im,ima,TVsizeX/24);
00122 if(status == SELECTED)DrawArrow(hdc,Offset,p,t,a,im,ima,TVsizeX/24);
00123 mr=(double)(Op->lastframe - Op->firstframe+1);
00124 mr=(double)(CurrentFrame - Op->firstframe+1)/mr;
00125 if(Op->nskeleton > 0 && (sp=Op->skeleton) != NULL && (sid=Op->skid) != NULL){
00126 InterpolateRobot(mr,Op,Op->last);
00127 RobotTransform(Offset,p,t,a,sx,sy,sz,im,ima,RoboT);
00128 for(k=0;k<Op->nskeleton;k++){
00129 xx=(double)sp[k].pp[0];
00130 yy=(double)sp[k].pp[1];
00131 zz=(double)sp[k].pp[2];
00132 m4by1(RoboT,xx,yy,zz,&x,&y,&z);
00133 sp[k].pt[0]=(long)x;
00134 sp[k].pt[1]=(long)y;
00135 sp[k].pt[2]=(long)z;
00136 }
00137 if(Op->in_ram){
00138 Nv=Op->npoints;
00139 if(Nv > 0){
00140 if((Vp=(point *)X__Malloc(Nv*sizeof(point))) != NULL){
00141 for(i=0;i<Nv;i++){
00142 CopyPoint(Op->points[i],xyz);
00143 m4by4(RoboT,sp[sid[i]].T,ViewT);
00144 x = (double)(xyz[0]-Op->origin[0]);
00145 y = (double)(xyz[1]-Op->origin[1]);
00146 z = (double)(xyz[2]-Op->origin[2]);
00147 m4by1(ViewT,x,y,z,&xx,&yy,&zz);
00148 Vp[i][0]=(long)xx; Vp[i][1]=(long)yy; Vp[i][2]=(long)zz;
00149 }
00150 }
00151 else{
00152 SendPrgmQuery(IDQ_NOMEM3,0);
00153 Nv=0;
00154 }
00155 if(Nv > 0)for(k=0;k<Nv;k++){
00156 if(in_stage_triview(Vp[k])){
00157 for(i=ifd;i<ild;i++){
00158 GetWindowCoords(i,Vp[k][0],Vp[k][1],Vp[k][2],&sh1,&sv1);
00159 MoveToEx(hdc[i],sh1,sv1,NULL); LineTo(hdc[i],sh1+2,sv1);
00160 }
00161 }
00162 }
00163 if(Vp != NULL){ X__Free(Vp); Vp=NULL;}
00164 }
00165 }
00166 }
00167 DrawRobot(hdc,Op,Offset,p,t
00168 ,a,im,ima
00169 ,sx,sy,sz,status);
00170 }
00171
00172 void SkeletorOn(void){
00173 object *Op;
00174 EDIT_ACTION=YES;
00175 if(SelectedNode == NULL){
00176 SendPrgmQuery(IDQ_NRSELECT,0);
00177 return;
00178 }
00179 if(SelectedNode->type != ROBOT){
00180 SendPrgmQuery(IDQ_NOTAROBOT,0);
00181 return;
00182 }
00183 if(SelectedNode->fobj == NULL){
00184 SendPrgmQuery(IDQ_NOROBOTA,0);
00185 return;
00186 }
00187 Op=SelectedNode->fobj;
00188 while(Op != NULL){
00189 if(CurrentFrame == Op->lastframe){
00190 SelectedRobot=Op;
00191 tool=SKELETOR;
00192
00193
00194
00195
00196
00197 if(!IsWindow(ghwndSkEdit))RobotSkeletonTreeView(ghwnd_main);
00198 ReDrawStageDisplay(TRUE);
00199 return;
00200 }
00201 Op=Op->next;
00202 }
00203 SendPrgmQuery(IDQ_NOREDIT,0);
00204 return;
00205 }
00206
00207 void SkeletorOff(short disengage){
00208 tool=NOTOOL;
00209 if(IsWindow(ghwndSkEdit))RobotSkeletonTreeView(ghwnd_main);
00210 SelectedRobot=NULL;
00211 SelectedRobotArm = -1;
00212 ReDrawStageDisplay(TRUE);
00213 }
00214
00215 static void SelectRobotArm(void){
00216 BOOL flag=FALSE;
00217 long i;
00218 skel *sp;
00219 double d,dmin,dth;
00220 int sho,svo,H,V;
00221 POINT p;
00222 if(SelectedRobot == NULL)return;
00223 DrawInvertNode(ghdc_triview_Bitmap,SelectedNode,SELECTED);
00224
00225 sp=SelectedRobot->skeleton;
00226 dmin=(double)TVsizeX*(double)TVsizeX;
00227 dth=dmin/32/32;
00228 GetCursorPos(&p); ScreenToClient(ghwnd_current,&p);
00229 H=(int)p.x; V=(int)p.y;
00230 if(SelectedRobot->nskeleton > 0)for(i=0;i<SelectedRobot->nskeleton;i++){
00231 GetWindowCoords(ActiveView,sp->pt[0],sp->pt[1],sp->pt[2],&sho,&svo);
00232 if( (sho > H-4) && (sho < H+4) && (svo > V-4) && (svo < V+4)){
00233 d=(double)(sp->pt[0]-NpointerX)*(double)(sp->pt[0]-NpointerX)
00234 +(double)(sp->pt[1]-NpointerY)*(double)(sp->pt[1]-NpointerY)
00235 +(double)(sp->pt[2]-NpointerZ)*(double)(sp->pt[2]-NpointerZ);
00236 if(d < dmin){
00237 dmin=d;
00238 SelectedRobotArm=i;
00239 flag=TRUE;
00240 }
00241 }
00242 sp++;
00243 }
00244 DrawInvertNode(ghdc_triview_Bitmap,SelectedNode,SELECTED);
00245 if(View == ONEVIEW)UpdateWindow(ghwnd_current);
00246 else for(i=0;i<3;i++)UpdateWindow(ghwnd_triview[i]);
00247 if(flag && IsWindow(ghwndRobotView))PostMessage(ghwndRobotView,WM_DRAWROBOT,0,0);
00248 }
00249
00250 static int A_normalize(vector v){
00251 double n,nn;
00252 n= (double)((v[0]*v[0]) + (v[1]*v[1]) + (v[2]*v[2]));
00253 if(n < 1.e-10)return FAIL;
00254 nn=sqrt(n);
00255 n = 1.0 / nn;
00256 VECSCALE(n,v,v)
00257 return OK;
00258 }
00259
00260 static void TransformAxis(skel *sid, vector v, vector vv){
00261 vector t;
00262 VECSCALE((double)UNIT2*1000.0,v,t)
00263 VECSUM(t,(double)sid->p,t)
00264 m4by1(sid->T,t[0],t[1],t[2],&vv[0],&vv[1],&vv[2]);
00265 VECSUB(vv,(double)sid->pp,vv)
00266 A_normalize(vv);
00267 }
00268
00269 static void GetBasisTransform(vector x, vector y, vector z,
00270 vector u, vector v, vector w,
00271 double T[4][4]){
00272 int i,j;
00273 double a[3][3],t[4][4];
00274 double det;
00275 null_transform(T);
00276 null_transform(t);
00277 a[0][0]=x[0]; a[0][1]=x[1]; a[0][2]=x[2];
00278 a[1][0]=y[0]; a[1][1]=y[1]; a[1][2]=y[2];
00279 a[2][0]=z[0]; a[2][1]=z[1]; a[2][2]=z[2];
00280 det=a[0][0]*(a[1][1]*a[2][2] - a[2][1]*a[1][2])
00281 -a[0][1]*(a[1][0]*a[2][2] - a[2][0]*a[1][2])
00282 +a[0][2]*(a[1][0]*a[2][1] - a[2][0]*a[1][1]);
00283 if(fabs(det) < 1.e-10)return;
00284 det = 1.0/det;
00285 t[0][0] = +(a[1][1]*a[2][2] - a[2][1]*a[1][2])*det;
00286 t[1][0] = -(a[1][0]*a[2][2] - a[2][0]*a[1][2])*det;
00287 t[2][0] = +(a[1][0]*a[2][1] - a[2][0]*a[1][1])*det;
00288 t[0][1] = -(a[0][1]*a[2][2] - a[2][1]*a[0][2])*det;
00289 t[1][1] = +(a[0][0]*a[2][2] - a[2][0]*a[0][2])*det;
00290 t[2][1] = -(a[0][0]*a[2][1] - a[2][0]*a[0][1])*det;
00291 t[0][2] = +(a[0][1]*a[1][2] - a[1][1]*a[0][2])*det;
00292 t[1][2] = -(a[0][0]*a[1][2] - a[1][0]*a[0][2])*det;
00293 t[2][2] = +(a[0][0]*a[1][1] - a[1][0]*a[0][1])*det;
00294 m4by1(t,u[0],v[0],w[0],&T[0][0],&T[0][1],&T[0][2]);
00295 m4by1(t,u[1],v[1],w[1],&T[1][0],&T[1][1],&T[1][2]);
00296 m4by1(t,u[2],v[2],w[2],&T[2][0],&T[2][1],&T[2][2]);
00297 }
00298
00299 static void InvertRotationMatrix(double T[4][4], double t[4][4]){
00300 int i,j;
00301 double a[3][3];
00302 double det;
00303 null_transform(t);
00304 for(i=0;i<3;i++)for(j=0;j<3;j++)a[i][j]=T[i][j];
00305 det=a[0][0]*(a[1][1]*a[2][2] - a[2][1]*a[1][2])
00306 -a[0][1]*(a[1][0]*a[2][2] - a[2][0]*a[1][2])
00307 +a[0][2]*(a[1][0]*a[2][1] - a[2][0]*a[1][1]);
00308 if(fabs(det) < 1.e-10)return;
00309 det = 1.0/det;
00310 t[0][0] = +(a[1][1]*a[2][2] - a[2][1]*a[1][2])*det;
00311 t[1][0] = -(a[1][0]*a[2][2] - a[2][0]*a[1][2])*det;
00312 t[2][0] = +(a[1][0]*a[2][1] - a[2][0]*a[1][1])*det;
00313 t[0][1] = -(a[0][1]*a[2][2] - a[2][1]*a[0][2])*det;
00314 t[1][1] = +(a[0][0]*a[2][2] - a[2][0]*a[0][2])*det;
00315 t[2][1] = -(a[0][0]*a[2][1] - a[2][0]*a[0][1])*det;
00316 t[0][2] = +(a[0][1]*a[1][2] - a[1][1]*a[0][2])*det;
00317 t[1][2] = -(a[0][0]*a[1][2] - a[1][0]*a[0][2])*det;
00318 t[2][2] = +(a[0][0]*a[1][1] - a[1][0]*a[0][1])*det;
00319 }
00320
00321 static void rotate_round_vector(double angle, vector v, double t[4][4]){
00322 double dx,dy,dz,phi,theta,dxy;
00323 double t1[4][4],t2[4][4],t3[4][4];
00324 angle *= PI/180.0;
00325 dx=v[0]; dy=v[1]; dz=v[2];
00326 dxy=dx*dx+dy*dy;
00327 if(dxy < 0.00001){
00328 if(dz > 0.0)rotz(t, angle);
00329 else rotz(t,-angle);
00330 return;
00331 }
00332 dxy=sqrt(dxy);
00333 if (dx == 0.0 && dy > 0.0)phi = PI2;
00334 else if(dx == 0.0 && dy < 0.0)phi = -PI2;
00335 else phi = atan2(dy,dx);
00336 theta = atan2(dz,dxy);
00337 rotz(t3, -phi);
00338 roty(t2, -theta);
00339 m4by4(t2,t3,t1);
00340 rotx(t2, angle);
00341 m4by4(t2,t1,t3);
00342 roty(t2,theta);
00343 m4by4(t2,t3,t1);
00344 rotz(t2,phi);
00345 m4by4(t2,t1,t);
00346 }
00347
00348 int Skeletor(void){
00349 POINT pt;
00350 int xi,xo,MickeyX,I;
00351 double ltr[4][4],ctr[4][4];
00352 vector Tv,Rv,Xv={1.0,0.0,0.0},Yv={0.0,1.0,0.0},Zv={0.0,0.0,1.0};
00353 long i,j,k,evTime;
00354 skel *s;
00355 object *op;
00356 if(SelectedNode == NULL)return 1;
00357 if(SelectedNode->type != ROBOT)return 1;
00358 op=GetObjectAtFrame(SelectedNode,CurrentFrame);
00359 UpdateRobot(op);
00360
00361 if(SelectedRobot != NULL && SelectedRobot->lastframe != CurrentFrame){
00362 SendPrgmQuery(IDQ_ONLYKEYFRAME,0);
00363 return 0;
00364 }
00365 SelectRobotArm();
00366 if(SelectedRobot != NULL && SelectedRobotArm >= 0){
00367 SelectTreeViewItem();
00368 if(CurrentFrame == SelectedRobot->lastframe){
00369 s=SelectedRobot->skeleton;
00370 i=SelectedRobotArm;
00371 if(gToolFlags.flagK == 6){
00372 if(i > 0){
00373 VECSUB((double)(s+((s+i)->id))->p,(double)(s+i)->p,Tv)
00374 A_normalize(Tv);
00375 m4by1((s+i)->R,Tv[0],Tv[1],Tv[2],&Rv[0],&Rv[1],&Rv[2]);
00376 }
00377 else{
00378 VECCOPY(Zv,Rv)
00379 }
00380 }
00381 else if(gToolFlags.flagK > 2 && i > 0){
00382 if( gToolFlags.flagK == 3)VECCOPY(Xv,Tv)
00383 else if(gToolFlags.flagK == 4)VECCOPY(Yv,Tv)
00384 else VECCOPY(Zv,Tv)
00385 j=s[i].id;
00386 TransformAxis((s+j),s[j].u,s[j].uu);
00387 TransformAxis((s+j),s[j].v,s[j].vv);
00388 TransformAxis((s+j),s[j].w,s[j].ww);
00389 GetBasisTransform(s[j].uu,s[j].vv,s[j].ww,s[j].u,s[j].v,s[j].w,ltr);
00390 m4by1(ltr,Tv[0],Tv[1],Tv[2],&Rv[0],&Rv[1],&Rv[2]);
00391 }
00392 GetCursorPos(&pt); xo=(int)pt.x;
00393 evTime=GetTickCount()+TIME_DELAY;
00394 do {
00395 if(evTime > GetTickCount())continue;
00396 GetCursorPos(&pt); xi=pt.x;
00397 MickeyX = xi-xo; xo=xi;
00398 if(MickeyX != 0){
00399 if(MickeyX > 0)I=max( 1,min( 45,MickeyX));
00400 else I=min(-1,max(-45,MickeyX));
00401 DrawInvertNode(ghdc_triview_Bitmap,SelectedNode,SELECTED);
00402 if(i > 0){
00403 j=s[i].id;
00404 if(gToolFlags.flagK == 0)
00405 rotate_round_vector(I,s[j].v,ltr);
00406 else if(gToolFlags.flagK == 1)
00407 rotate_round_vector(I,s[j].u,ltr);
00408 else if(gToolFlags.flagK == 2)
00409 rotate_round_vector(I,s[j].w,ltr);
00410 else if(gToolFlags.flagK > 2 && gToolFlags.flagK <= 6)
00411 rotate_round_vector(I,Rv,ltr);
00412 else null_transform(ltr);
00413 m4by4(ltr,s[i].R,ctr); c4to4(ctr,s[i].R);
00414 }
00415 DrawInvertNode(ghdc_triview_Bitmap,SelectedNode,SELECTED);
00416 if(ghwndOpenGLview == NULL)PerspectiveView(0,0);
00417 if(IsWindow(ghwndRobotView)){
00418 SendMessage(ghwndRobotView,WM_DRAWROBOT,0,0);
00419 UpdateWindow(ghwndRobotView);
00420 }
00421 if(View == ONEVIEW)UpdateWindow(ghwnd_current);
00422 else{
00423 for(I=0;I<3;I++)UpdateWindow(ghwnd_triview[I]);
00424 }
00425 UpdateWindow(ghwnd_view);
00426 }
00427 evTime=GetTickCount()+TIME_DELAY;
00428 }
00429 while (GetAsyncKeyState(VK_LBUTTON) & 0x8000);
00430
00431 if(ghwndOpenGLview != NULL)UpdateGLview(TRUE);
00432 else PerspectiveView(0,1);
00433
00434 return 0;
00435 }
00436 else{
00437 ;
00438 }
00439 }
00440 return 1;
00441 }
00442
00443 void RobotTransform(point Offset, double p, double t, double a,
00444 double sx, double sy, double sz,
00445 short im, double ima, double RoboT[4][4]){
00446 double tr0[4][4],tr1[4][4],tr2[4][4],tr3[4][4],x,y,z;
00447 scal(tr1,sx,sy,sz);
00448 if(im > 0){
00449 if (im == 1)rotz(tr0,ima*PIo180);
00450 else if(im == 2)rotx(tr0,ima*PIo180);
00451 else if(im == 3)roty(tr0,ima*PIo180);
00452 roty(tr2,t*PI/180.0);
00453 m4by4(tr2,tr0,tr3);
00454 }
00455 else{
00456 roty(tr3,t*PIo180);
00457 }
00458 m4by4(tr3,tr1,tr2);
00459 rotx(tr3,a*PIo180);
00460 m4by4(tr3,tr2,tr1);
00461 rotz(tr2,p*PIo180);
00462 m4by4(tr2,tr1,tr3);
00463 tram(tr1,Offset[0],Offset[1],Offset[2]);
00464 m4by4(tr1,tr3,RoboT);
00465 return;
00466 }
00467
00468 static void NameRobotDirectory(char *script_file, char *robo_dir){
00469 long l;
00470 l=strlen(script_file);
00471 strcpy(robo_dir,script_file);
00472 strcpy((robo_dir+l-4),".skd");
00473 }
00474
00475 short OpenRobotDirectory(char * script_file){
00476 SECURITY_ATTRIBUTES sa;
00477 char str[255];
00478 sa.nLength=sizeof(sa);
00479 sa.lpSecurityDescriptor=NULL;
00480 sa.bInheritHandle=FALSE;
00481 NameRobotDirectory(script_file,str);
00482 if(CreateDirectory(str,&sa))return 1;
00483
00484 RemoveRobotDirectory(script_file);
00485 if(CreateDirectory(str,&sa))return 1;
00486 else return 0;
00487 }
00488
00489 void RemoveRobotDirectory(char *script_file){
00490 HANDLE h;
00491 WIN32_FIND_DATA ffd,*lpffd;
00492 char str[255],strr[255],title[64];
00493 NameRobotDirectory(script_file,str);
00494 sprintf(strr,"%s\\$*.*",str);
00495 lpffd=&ffd;
00496 if((h=FindFirstFile(strr,lpffd)) == INVALID_HANDLE_VALUE){
00497 if(!RemoveDirectory(str)){
00498 LoadString(ghinst_main,IDX_MISC_ERROR1,title,64);
00499 MessageBox(NULL,str,title,MB_OK);
00500 }
00501 return;
00502 }
00503 sprintf(strr,"%s\\%s",str,lpffd->cFileName);
00504 if(!DeleteFile(strr))MessageBeep(MB_OK);
00505 while(FindNextFile(h,lpffd)){
00506 sprintf(strr,"%s\\%s",str,lpffd->cFileName);
00507 if(!DeleteFile(strr))MessageBeep(MB_OK);
00508 }
00509 if(GetLastError() != ERROR_NO_MORE_FILES){
00510 SendPrgmQuery(IDQ_BADNEXTFILE,3);
00511 }
00512 if(!FindClose(h))SendPrgmQuery(IDQ_BADFILE,3);
00513 if(!RemoveDirectory(str))MessageBeep(MB_OK);
00514 }
00515
00516 void GetRobotScriptName(char *script_file, long node_id,
00517 short lastframe, char *robot_name){
00518 char str[255];
00519 NameRobotDirectory(script_file,str);
00520 sprintf(robot_name,"%s\\$%d.%ld",str,lastframe,node_id);
00521 }
00522
00523 short RobotFileExists(char *robot_name){
00524 int fd;
00525 if((fd=open(robot_name,O_RDONLY)) < 0)return 0;
00526 close(fd);
00527 return 1;
00528 }
00529
00530 static void EditRobotTransform(int command){
00531 object *Op;
00532 skel *sp;
00533 long j,id;
00534 if((Op=SelectedRobot) == NULL)return;
00535 if(command == 0){
00536 sp=Op->skeleton;
00537 for(j=0;j<Op->nskeleton;j++){
00538 null_transform(sp->R);
00539 null_transform(sp->Q);
00540 null_transform(sp->T);
00541 sp++;
00542 }
00543 }
00544 else if(command == 2){
00545 if(SelectedRobotArm >= 0 && SelectedRobotArm < Op->nskeleton){
00546 sp=(Op->skeleton+SelectedRobotArm);
00547 null_transform(sp->R);
00548 null_transform(sp->Q);
00549 null_transform(sp->T);
00550 sp=Op->skeleton;
00551 if((GetAsyncKeyState(VK_SHIFT) & 0x8000) == 0x8000){
00552 for(j=0;j<Op->nskeleton;j++){
00553 id=sp->id;
00554 while(id != 0){
00555 if(id == SelectedRobotArm){
00556 null_transform(sp->R);
00557 null_transform(sp->Q);
00558 null_transform(sp->T);
00559 break;
00560 }
00561 id=(Op->skeleton+id)->id;
00562 }
00563 sp++;
00564 }
00565 }
00566 }
00567 }
00568 else if(command == 1){
00569 if(Op->last != NULL && Op->last->nskeleton == Op->nskeleton){
00570 j=(long)(Op->last->nskeleton)*(long)sizeof(skel);
00571 memcpy(Op->skeleton,Op->last->skeleton,j);
00572 }
00573 else MessageBeep(MB_OK);
00574 }
00575 ReDrawStageDisplay(TRUE);
00576 PerspectiveView(0,0);
00577 return;
00578 }
00579
00580 void WriteRobot(object *Op, char *robot_name){
00581 long i,j,n;
00582 FILE *frobot;
00583 skel *sk;
00584 if((frobot = fopen(robot_name,"w")) != NULL){
00585 if((n=Op->nskeleton) > 0 && (sk=Op->skeleton) != NULL){
00586 fprintf(frobot,"%ld\n",n);
00587 for(i=0;i<n;i++){
00588 for(j=0;j<4;j++)fprintf(frobot,"%lf %lf %lf %lf\n",
00589 sk[i].R[j][0],sk[i].R[j][1],sk[i].R[j][2],sk[i].R[j][3]);
00590 }
00591 }
00592 else{
00593 fprintf(frobot,"0\n");
00594 }
00595 fclose(frobot);
00596 }
00597 }
00598
00599 static int nSkeleton;
00600 skel *Skeleton;
00601
00602 static void ApplyTransformToChildren(int id, double T[4][4]){
00603 static double x,y,z;
00604 static double sst[4][4],t1[4][4],t2[4][4];
00605 int i;
00606 for(i=1;i<nSkeleton;i++){
00607 if(Skeleton[i].id == id){
00608 tram(t1,-(Skeleton+id)->p[0],-(Skeleton+id)->p[1],-(Skeleton+id)->p[2]);
00609 m4by4((Skeleton+i)->Q,t1,t2);
00610 tram(t1, (Skeleton+id)->p[0], (Skeleton+id)->p[1], (Skeleton+id)->p[2]);
00611 m4by4(t1,t2,sst);
00612 m4by4(T,sst,Skeleton[i].T);
00613 m4by1(Skeleton[i].T,
00614 (double)Skeleton[i].p[0],
00615 (double)Skeleton[i].p[1],
00616 (double)Skeleton[i].p[2],&x,&y,&z);
00617 Skeleton[i].pp[0]=(long)x;
00618 Skeleton[i].pp[1]=(long)y;
00619 Skeleton[i].pp[2]=(long)z;
00620 ApplyTransformToChildren(i,Skeleton[i].T);
00621 }
00622 }
00623 return;
00624 }
00625
00626 void SetRobotToWalkPath(node *Np){
00627 char nodename[255];
00628 node *OnPath;
00629 object *Op,*Opath;
00630 position *Pp,*Ppath;
00631 align *Ap,*Apn;
00632 point cp,lp,pathpos,pathposA;
00633 vector delta,deltaa;
00634 int pathff;
00635 double pl,d,distance=0.0,dd,dxy,x,y,z;
00636 if((OnPath=SelectNode(nodename,NO,ghwnd_main)) != NULL){
00637 if(OnPath->type == PATH){
00638
00639 Ap=Np->fali; while(Ap != NULL){Apn=Ap->next; DeleteAlign(Np,Ap->firstframe); Ap=Apn;}
00640 Ppath=OnPath->fpos;
00641 Opath=OnPath->fobj;
00642
00643 if(Opath == NULL)return;
00644 pathff=Opath->firstframe-1;
00645
00646
00647 Op=Np->fobj; while(Op != NULL){
00648 Op->firstframe += pathff;
00649 Op->lastframe += pathff;
00650 Op=Op->next;
00651 }
00652 Pp=Np->fpos; while(Pp != NULL){
00653 Pp->firstframe += pathff;
00654 Pp->lastframe += pathff;
00655 Pp=Pp->next;
00656 }
00657
00658 pl=PathLength(Opath->firstpathpoint,Opath->pathtype,Opath->npathpoints);
00659 dd = pl*0.01;
00660
00661 Pp=Np->fpos; while(Pp != NULL){
00662 if(Pp == Np->fpos)VECCOPY(Pp->finish,lp)
00663 else VECCOPY(cp,lp)
00664 VECCOPY(Pp->finish,cp)
00665 VECSUB(cp,lp,delta)
00666 d=sqrt(DOT(delta,delta));
00667 distance += d;
00668
00669
00670 GetPathPositionAtDistance(OnPath,Opath,distance,pathpos);
00671 GetPathPositionAtDistance(OnPath,Opath,distance+dd,pathposA);
00672 VECSUB(pathposA,pathpos,deltaa);
00673
00674 if(Ppath != NULL)VECSUM(Ppath->finish,pathpos,pathpos)
00675 VECCOPY(pathpos,Pp->finish)
00676
00677 Ap=CreateAlign(Np,Pp->firstframe,Pp->lastframe);
00678 if(Ap!= NULL && A_normalize(deltaa)){
00679 x=deltaa[0]; y=deltaa[1]; z=deltaa[2];
00680 dxy=sqrt(x*x+y*y);
00681 Ap->theta=0.0;
00682 Ap->phi=RAD2DEG*atan2(y,x);
00683 if(GetAsyncKeyState(VK_CONTROL) & 0x8000){
00684 Ap->phi -= 90.0; if(Ap->phi < -180.0)Ap->phi += 360.0;
00685 }
00686 else{
00687 Ap->phi += 90.0; if(Ap->phi > 180.0)Ap->phi -= 360.0;
00688 }
00689 Ap->alpha = -RAD2DEG*atan2(z,dxy);
00690
00691 }
00692 Pp=Pp->next;
00693 }
00694 }
00695 else MessageBox(NULL,"Not a path",NULL,MB_OK);
00696 }
00697 }
00698
00699 void ExportRobotSequence(node *Np){
00700 FILE *pz;
00701 skel *sk;
00702 object *Op;
00703 position *Pp;
00704 point ptstart={0,0.0};
00705 int i,j,n,nr,ko,np,nf=0,ns=0;
00706 if(SelectSfxFileName(1,gszRSQfile,gszRSQdir,IDX_MISC_EXPORT_ROBOT,
00707 "(*.RSQ)|*.rsq|",ghwndTimeline) == TRUE){
00708 AppendFileExtension(gszRSQfile,".rsq");
00709 if((pz=fopen(gszRSQfile,"w")) != NULL){
00710 Op=Np->fobj; nr=0;
00711 if(Op != NULL)ns=Op->firstframe;
00712 while(Op != NULL){
00713 nr++;
00714 if(Op->next == NULL)nf=Op->lastframe;
00715 Op=Op->next;
00716 }
00717 fprintf(pz,"%ld %ld %ld %ld\n%s\n",nr,ns,nf,nf-ns+1,Np->fobj->name);
00718 Op=Np->fobj; ko=1; while(Op != NULL){
00719 fprintf(pz,"%ld %ld %ld\n",ko,Op->firstframe,Op->lastframe);
00720 if((n=Op->nskeleton) > 0 && (sk=Op->skeleton) != NULL){
00721 fprintf(pz,"%ld\n",n);
00722 for(i=0;i<n;i++){
00723 for(j=0;j<4;j++)fprintf(pz,"%lf %lf %lf %lf\n",
00724 sk[i].R[j][0],sk[i].R[j][1],sk[i].R[j][2],sk[i].R[j][3]);
00725 }
00726 }
00727 else{ fprintf(pz,"0\n"); }
00728 ko++;
00729 Op=Op->next;
00730 }
00731
00732 np=0;
00733 if((Pp=Np->fpos) != NULL){
00734 while(Pp != NULL){
00735 if(np == 0)VECCOPY(Pp->finish,ptstart)
00736 np++;
00737 Pp=Pp->next;
00738 }
00739 }
00740 fprintf(pz,"%ld %ld %ld %ld\n",np,ptstart[0],ptstart[1],ptstart[2]);
00741 if(np > 0){
00742 Pp=Np->fpos; while(Pp != NULL){
00743 fprintf(pz,"%ld %ld %ld %ld %ld\n",Pp->firstframe,Pp->lastframe,
00744 Pp->finish[0]-ptstart[0],Pp->finish[1]-ptstart[1],Pp->finish[2]-ptstart[2]);
00745 Pp=Pp->next;
00746 }
00747 }
00748 fclose(pz);
00749 }
00750 }
00751 }
00752
00753 long ImportRobotSequence(long n, node *Np, char *filename,long firstframe, long lastframe){
00754
00755 long r,i,j,k,retval=OK,nseq,nfirst,nlast,nfr,ff,ffp,lf,ko,kff,klf,nsk,nsk1,np;
00756 point startpoint;
00757 long dx,dy,dz;
00758 char robot_name[MAX_FILE];
00759 object *tempobj;
00760 position *Pp,*LastPp;
00761 skel *sk;
00762 FILE *pz;
00763 BOOL bEject=FALSE;
00764
00765
00766 DeletePositionIn(Np,firstframe,lastframe);
00767 if((pz=fopen(filename,"r")) != NULL){
00768 DeleteCostume(Np,firstframe);
00769 ff=firstframe;
00770 ffp=firstframe;
00771 for(r=0;r<n;r++){
00772 fscanf(pz,"%ld %ld %ld %ld",&nseq,&nfirst,&nlast,&nfr);
00773 fscanf(pz," %[^\n]",robot_name);
00774
00775 if(ff > lastframe){
00776 double m1,m2,m3,m4;
00777 for(i=0;i<nseq;i++){
00778 fscanf(pz,"%ld %ld %ld\n",&ko,&kff,&klf);
00779 fscanf(pz,"%ld\n",&nsk);
00780 if(nsk > 0){
00781 for(k=0;k<nsk;k++){
00782 for(j=0;j<4;j++)fscanf(pz,"%lf %lf %lf %lf",&m1,&m2,&m3,&m4);
00783 }
00784 }
00785 }
00786 }
00787 else{
00788 for(i=0;i<nseq;i++){
00789 fscanf(pz,"%ld %ld %ld\n",&ko,&kff,&klf);
00790 lf=ff+(klf-kff);
00791 lf=min(lf,lastframe);
00792 if(r == 0 || i > 0 || lf-ff > 1){
00793 tempobj=CreateCostume(Np,ff,lf);
00794 if(fail_op == YES || tempobj == NULL){fail_op=NO; retval=FAIL; goto ALL_DONE;}
00795 if(r > 0 && i == 1 && tempobj->last != NULL)tempobj->firstframe = tempobj->last->lastframe + 1;
00796 strcpy(tempobj->name,robot_name);
00797 tempobj->morph=0;
00798 if(LoadMeshObject(tempobj->name,tempobj,YES,YES,YES) == FAIL){
00799 DeleteCostume(Np,ff);
00800 retval=FAIL;
00801 goto ALL_DONE;
00802 }
00803 }
00804 fscanf(pz,"%ld\n",&nsk);
00805 nsk1=tempobj->nskeleton;
00806 sk=tempobj->skeleton;
00807 if(sk == NULL || nsk1 != nsk){
00808 MessageBox(NULL,"Incompatible Skeletons",NULL,MB_OK); retval=FAIL; goto ALL_DONE;
00809 }
00810 if(nsk > 0){
00811
00812 for(k=0;k<nsk;k++){
00813 for(j=0;j<4;j++)fscanf(pz,"%lf %lf %lf %lf",
00814 &sk[k].R[j][0],&sk[k].R[j][1], &sk[k].R[j][2], &sk[k].R[j][3]);
00815 }
00816 }
00817 ff=lf+1;
00818 }
00819 }
00820
00821 fscanf(pz,"%ld %ld %ld %ld",&np,&startpoint[0],&startpoint[1],&startpoint[2]);
00822 if(np > 0){
00823
00824 LastPp=Pp=Np->fpos; while(Pp != NULL){
00825 LastPp=Pp;
00826 Pp=Pp->next;
00827 }
00828 if(LastPp != NULL)VECCOPY(LastPp->finish,startpoint)
00829 else {
00830 startpoint[0] = NpointerX; startpoint[1] = NpointerY; startpoint[2] = NpointerZ;
00831 }
00832 for(i=0;i<np;i++){
00833 fscanf(pz,"%ld %ld %ld %ld %ld\n",&kff,&klf,&dx,&dy,&dz);
00834 if(ffp <= lastframe){
00835 lf=ffp+(klf-kff);
00836 lf=min(lf,lastframe);
00837 if(r == 0 || i > 0 || lf-ffp > 1){
00838 Pp=CreatePosition(Np,ffp,lf);
00839 if(Pp != NULL){
00840 Pp->type=TWEEN;
00841 if(r > 0 && i == 1 && Pp->last != NULL)Pp->firstframe = Pp->last->lastframe + 1;
00842
00843
00844 Pp->finish[0]=startpoint[0]+dx;
00845 Pp->finish[1]=startpoint[1]+dy;
00846 Pp->finish[2]=startpoint[2]+dz;
00847 }
00848 }
00849 ffp=lf+1;
00850 }
00851 }
00852 }
00853 rewind(pz);
00854 }
00855 ALL_DONE:
00856 fclose(pz);
00857 }
00858 return retval;
00859 }
00860
00861
00862 #define EPSILON 1.0e-6
00863
00864 static void MatrixToQuaternion(double m[4][4], quaternion q){
00865 double w4,x2;
00866 q[0]=0.25*(1.0+m[0][0]+m[1][1]+m[2][2]);
00867 if(q[0] > EPSILON){
00868 q[0]=sqrt(q[0]);
00869 w4=1.0/(4.0*q[0]);
00870 q[1]=(m[1][2]-m[2][1])*w4;
00871 q[2]=(m[2][0]-m[0][2])*w4;
00872 q[3]=(m[0][1]-m[1][0])*w4;
00873 }
00874 else{
00875 q[0]=0.0;
00876 q[1]= -0.5*(m[1][1]+m[2][2]);
00877 if(q[1] > EPSILON){
00878 q[1]=sqrt(q[1]);
00879 x2=1.0/(2.0*q[1]);
00880 q[2]=m[0][1]*x2;
00881 q[3]=m[0][2]*x2;
00882 }
00883 else{
00884 q[1]=0.0;
00885 q[2]=0.5*(1.0-m[2][2]);
00886 if(q[2] > EPSILON){
00887 q[2]=sqrt(q[2]);
00888 q[3]=m[1][2]/(2.0*q[2]);
00889 }
00890 else{
00891 q[2]=0.0;
00892 q[3]=1.0;
00893 }
00894 }
00895 }
00896 return;
00897 }
00898
00899 static void QuaternionToMatrix(quaternion q, double m[4][4]){
00900 double w,x,y,z,x2,y2,z2;
00901 w=q[0]; x=q[1]; y=q[2]; z=q[3]; x2=x*x; y2=y*y; z2=z*z;
00902 m[0][0]=1.0-2*y2-2*z2; m[0][1]=2*x*y+2*w*z; m[0][2]=2*x*z-2*w*y;
00903 m[1][0]=2*x*y-2*w*z; m[1][1]=1.0-2*x2-2*z2; m[1][2]=2*y*z+2*w*x;
00904 m[2][0]=2*x*z+2*w*y; m[2][1]=2*y*z-2*w*x; m[2][2]=1.0-2*x2-2*y2;
00905 m[3][3]=1.0; m[0][3]=m[1][3]=m[2][3]=m[3][0]=m[3][1]=m[3][2]=0.0;
00906 return;
00907 }
00908
00909 static void Slerp(double mr, quaternion q1, quaternion q2, quaternion q){
00910 double sum,beta1,beta2,theta;
00911 sum=q1[0]*q2[0]+q1[1]*q2[1]+q1[2]*q2[2]+q1[3]*q2[3];
00912 if(sum > 1.0)sum=1.0;
00913 theta=acos(sum);
00914 if(theta < EPSILON){ beta1=1.0-mr; beta2=mr;}
00915 else{
00916 beta1=sin((1.0-mr)*theta)/sin(theta);
00917 beta2=sin(mr*theta)/sin(theta);
00918 }
00919 q[0]=beta1*q1[0]+beta2*q2[0];
00920 q[1]=beta1*q1[1]+beta2*q2[1];
00921 q[2]=beta1*q1[2]+beta2*q2[2];
00922 q[3]=beta1*q1[3]+beta2*q2[3];
00923 }
00924
00925 void InterpolateRobot(double mr, object *Op, object *LastOp){
00926 int i;
00927 quaternion q,q1,q2;
00928 nSkeleton=Op->nskeleton;
00929 Skeleton=Op->skeleton;
00930 if(mr < 1.0 && LastOp != NULL && Op->nskeleton == LastOp->nskeleton){
00931
00932 #if 0
00933 for(i=0;i<nSkeleton;i++){
00934 MatrixToQuaternion((LastOp->skeleton+i)->R,q1);
00935 MatrixToQuaternion((Skeleton+i)->R,q2);
00936 Slerp(mr,q1,q2,q);
00937 QuaternionToMatrix(q,(Skeleton+i)->Q);
00938 }
00939 #else
00940
00941 quaternion Qi={1.0,0.0,0.0,0.0};
00942 double Q[4][4],Ri[4][4];
00943 for(i=0;i<nSkeleton;i++){
00944 InvertRotationMatrix((LastOp->skeleton+i)->R,Ri);
00945 m4by4((Skeleton+i)->R,Ri,Q);
00946 MatrixToQuaternion(Q,q2);
00947 Slerp(mr,Qi,q2,q);
00948 QuaternionToMatrix(q,Q);
00949
00950 m4by4(Q,(LastOp->skeleton+i)->R,(Skeleton+i)->Q);
00951 }
00952 #endif
00953 }
00954 else{
00955 for(i=0;i<nSkeleton;i++)c4to4((Skeleton+i)->R,(Skeleton+i)->Q);
00956 }
00957 ApplyTransformToChildren(0,Skeleton[0].T);
00958 return;
00959 }
00960
00961
00962
00963 #define ptrNMHDR ((LPNMHDR)lparam)
00964 #define ptrNM_TREEVIEW ((NM_TREEVIEW *)lparam)
00965 #define ptrTV_DISPINFO ((TV_DISPINFO *)lparam)
00966
00967 #define BOUND(x,min,max) ((x) < (min) ? (min) : ((x) > (max) ? (max) : (x)))
00968
00969 #define IDM_SKTB_V 100
00970 #define IDM_SKTB_U 101
00971 #define IDM_SKTB_W 102
00972 #define IDM_SKTB_X 103
00973 #define IDM_SKTB_Y 104
00974 #define IDM_SKTB_Z 105
00975 #define IDM_SKTB_R 106
00976 #define IDM_SKTB_RESET 107
00977 #define IDM_SKTB_COPY 108
00978 #define IDM_SKTB_SAVE 109
00979 #define IDM_SKTB_LOAD 110
00980 #define IDM_SKTB_ZOOM 111
00981 #define IDM_SKTB_ZOOM_STATE 112
00982 #define IDM_SKTB_RESET_SELECT 113
00983 #define IDM_SKTB_OVERLAY 114
00984 #define IDM_SKTB_TRANSPARENT 115
00985 #define IDM_SKTB_POINTS 116
00986
00987 static LRESULT CALLBACK RobotOglViewWndProc(HWND, UINT, WPARAM, LPARAM);
00988 static LRESULT CALLBACK RobotHdcViewWndProc(HWND, UINT, WPARAM, LPARAM);
00989
00990 static PSTR lpszSkTreeViewClass="SkTreeViewClass";
00991 static PSTR lpszRobotViewClass="RobotViewClass";
00992 static HWND hWndTreeView=NULL;
00993 static HWND hTBWnd=NULL;
00994 static HIMAGELIST hCoasterImageList=NULL;
00995 static HDC hdcRobotView=NULL;
00996 static HBITMAP hbmRobotView=NULL,hbmOldRobotView=NULL;
00997 static int RobotViewXpos=-1,RobotViewYpos=-1,
00998 RobotViewXsize=0,RobotViewYsize=0;
00999 SkTreeViewXpos=-1,SkTreeViewYpos=-1,
01000 SkTreeViewXsize=0,SkTreeViewYsize=0;
01001 static BOOL RobotZoomFlag=FALSE,RobotZoomState=FALSE,
01002 RobotOverlayFlag=FALSE,RobotGlassFlag=FALSE,
01003 RobotPointsFlag;
01004
01005 #define NTOOLBARBITMAPS 17
01006 #define NTOOLBARBUTTONS 22 // 18
01007
01008 static TBBUTTON tbb[NTOOLBARBUTTONS] = {
01009 {9,IDM_SKTB_LOAD, TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0 },
01010 {10,IDM_SKTB_SAVE, TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0 },
01011 {0,0, TBSTATE_ENABLED,TBSTYLE_SEP, 0,0 },
01012 {7,IDM_SKTB_RESET, TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0 },
01013 {13,IDM_SKTB_RESET_SELECT, TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0 },
01014 {8,IDM_SKTB_COPY, TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0 },
01015 {0,0, TBSTATE_ENABLED,TBSTYLE_SEP, 0,0 },
01016 {11,IDM_SKTB_ZOOM, TBSTATE_ENABLED,TBSTYLE_BUTTON|
01017 TBSTYLE_CHECK,0,0 },
01018 {12,IDM_SKTB_ZOOM_STATE, TBSTATE_ENABLED,TBSTYLE_BUTTON|
01019 TBSTYLE_CHECK,0,0 },
01020
01021 {0,0, TBSTATE_ENABLED,TBSTYLE_SEP, 0,0 },
01022 {14,IDM_SKTB_OVERLAY,TBSTATE_ENABLED,TBSTYLE_BUTTON|
01023 TBSTYLE_CHECK,0,0 },
01024 {15,IDM_SKTB_TRANSPARENT,TBSTATE_ENABLED,TBSTYLE_BUTTON|
01025 TBSTYLE_CHECK,0,0 },
01026 {16,IDM_SKTB_POINTS,TBSTATE_ENABLED,TBSTYLE_BUTTON|
01027 TBSTYLE_CHECK,0,0 },
01028
01029 {0,0, TBSTATE_ENABLED|TBSTATE_WRAP,TBSTYLE_SEP,0,0 },
01030 {0,0, TBSTATE_ENABLED,TBSTYLE_SEP, 0,0 },
01031 {0,IDM_SKTB_V,TBSTATE_ENABLED|TBSTATE_CHECKED,TBSTYLE_BUTTON|
01032 TBSTYLE_CHECKGROUP, 0,0 },
01033 {1,IDM_SKTB_U,TBSTATE_ENABLED,TBSTYLE_BUTTON|
01034 TBSTYLE_CHECKGROUP, 0,0 },
01035 {2,IDM_SKTB_W,TBSTATE_ENABLED,TBSTYLE_BUTTON|
01036 TBSTYLE_CHECKGROUP, 0,0 },
01037 {6,IDM_SKTB_R,TBSTATE_ENABLED,TBSTYLE_BUTTON|
01038 TBSTYLE_CHECKGROUP, 0,0 },
01039 {5,IDM_SKTB_Y,TBSTATE_ENABLED,TBSTYLE_BUTTON|
01040 TBSTYLE_CHECKGROUP, 0,0 },
01041 {4,IDM_SKTB_X,TBSTATE_ENABLED,TBSTYLE_BUTTON|
01042 TBSTYLE_CHECKGROUP, 0,0 },
01043 {3,IDM_SKTB_Z,TBSTATE_ENABLED,TBSTYLE_BUTTON|
01044 TBSTYLE_CHECKGROUP, 0,0 }
01045 };
01046
01047 static HTREEITEM AddTreeViewItem (HWND hWndTV,
01048 HTREEITEM hParent,
01049 HTREEITEM hInsertAfter,
01050 int iImage,
01051 int iSelectedImage,
01052 LPSTR szText,
01053 LPARAM lParam){
01054 TV_INSERTSTRUCT tvIns;
01055 tvIns.item.mask = TVIF_TEXT | TVIF_IMAGE |
01056 TVIF_SELECTEDIMAGE | TVIF_PARAM;
01057 tvIns.item.pszText = szText;
01058 tvIns.item.cchTextMax = sizeof(szText);
01059 tvIns.item.iImage = iImage;
01060 tvIns.item.iSelectedImage = iSelectedImage;
01061 tvIns.item.lParam = lParam;
01062 tvIns.hParent = hParent;
01063 tvIns.hInsertAfter = hInsertAfter;
01064 return TreeView_InsertItem(hWndTV,&tvIns);
01065 }
01066
01067 static void SelectTreeViewItem(void){
01068 skel *sp;
01069 int n;
01070 if(SelectedRobot == NULL)return;
01071 if((sp=SelectedRobot->skeleton) == NULL)return;
01072 n=SelectedRobot->nskeleton;
01073 if(SelectedRobotArm < 0 || SelectedRobotArm >= n)return;
01074 TreeView_EnsureVisible(hWndTreeView,(HTREEITEM)(sp+SelectedRobotArm)->lParam);
01075 TreeView_Select(hWndTreeView,(HTREEITEM)(sp+SelectedRobotArm)->lParam,TVGN_CARET);
01076 }
01077
01078 static void AddTwigsTo(long id, HWND hWndTV){
01079 int i;
01080 skel *sp;
01081 HTREEITEM hParent;
01082 sp=(SelectedRobot->skeleton+1);
01083 for(i=1;i<SelectedRobot->nskeleton;i++){
01084 if(sp->id == id){
01085 hParent=(HTREEITEM)((SelectedRobot->skeleton+id)->lParam);
01086 sp->lParam=(LPARAM)AddTreeViewItem(hWndTV,hParent,(HTREEITEM)TVI_FIRST,
01087 0,1,
01088 (LPSTR)sp->name,
01089 (LPARAM)i);
01090 AddTwigsTo(i,hWndTV);
01091 }
01092 sp++;
01093 }
01094 }
01095
01096 static void UpdateSkTreeView(void){
01097 int i;
01098 skel *sp;
01099 object *Op;
01100 if(!IsWindow(hWndTreeView))return;
01101 TreeView_DeleteItem(hWndTreeView,TVI_ROOT);
01102 SelectedRobot->skeleton->lParam=(LPARAM)AddTreeViewItem(hWndTreeView,
01103 TVI_ROOT,
01104 (HTREEITEM)TVI_FIRST,
01105 0,1,
01106 (LPSTR)SelectedRobot->skeleton->name,
01107 (LPARAM)0);
01108 AddTwigsTo(0,hWndTreeView);
01109 for(i=1;i<SelectedRobot->nskeleton;i++){
01110 sp=(SelectedRobot->skeleton+i);
01111 if(sp->id == 0){
01112 TreeView_EnsureVisible(hWndTreeView,(HTREEITEM)sp->lParam);
01113 TreeView_Expand(hWndTreeView,(HTREEITEM)sp->lParam,TVE_EXPAND);
01114 }
01115 }
01116
01117
01118
01119 if(SelectedNode != NULL){
01120 Op=SelectedNode->fobj;
01121 while(Op != NULL){
01122 if(Op != SelectedRobot){
01123 for(i=0;i<SelectedRobot->nskeleton;i++){
01124 if(i < Op->nskeleton)
01125 (Op->skeleton+i)->lParam=(SelectedRobot->skeleton+i)->lParam;
01126 }
01127 }
01128 Op=Op->next;
01129 }
01130 }
01131 }
01132
01133 static BOOL TreeviewMenuCommand(HWND hWnd, WORD id){
01134 FILE *pz;
01135 long k;
01136 switch (id) {
01137 case IDM_SKTB_V:
01138 gToolFlags.flagK=0;
01139 break;
01140 case IDM_SKTB_U:
01141 gToolFlags.flagK=1;
01142 break;
01143 case IDM_SKTB_W:
01144 gToolFlags.flagK=2;
01145 break;
01146 case IDM_SKTB_X:
01147 gToolFlags.flagK=3;
01148 break;
01149 case IDM_SKTB_Y:
01150 gToolFlags.flagK=4;
01151 break;
01152 case IDM_SKTB_Z:
01153 gToolFlags.flagK=5;
01154 break;
01155 case IDM_SKTB_R:
01156 gToolFlags.flagK=6;
01157 break;
01158 case IDM_SKTB_RESET:
01159 EditRobotTransform(0);
01160 break;
01161 case IDM_SKTB_RESET_SELECT:
01162 EditRobotTransform(2);
01163 break;
01164 case IDM_SKTB_COPY:
01165 EditRobotTransform(1);
01166 break;
01167 case IDM_SKTB_ZOOM:
01168 RobotZoomFlag ^= 1;
01169 break;
01170 case IDM_SKTB_ZOOM_STATE:
01171 RobotZoomState ^= 1;
01172 break;
01173 case IDM_SKTB_SAVE:
01174 if(SelectSfxFileName(1,gszPZEfile,gszPZEdir,
01175 IDX_MISC_SAVEPOSE,"(*.PZE)|*.pze|",ghwnd_main) == TRUE){
01176 AppendFileExtension(gszPZEfile,".pze");
01177 if((pz=fopen(gszPZEfile,"wb")) != NULL){
01178 k=0xFEFE;
01179 fwrite(&k,sizeof(long),1,pz);
01180 k=0;
01181 fwrite(&k,sizeof(long),1,pz);
01182 fwrite(SelectedRobot->name,255,1,pz);
01183 fwrite(&(SelectedRobot->nskeleton),sizeof(long),1,pz);
01184 if(SelectedRobot->nskeleton > 0)
01185 for(k=0;k<SelectedRobot->nskeleton;k++){
01186 fwrite(SelectedRobot->skeleton[k].R,sizeof(double),16,pz);
01187 }
01188 fclose(pz);
01189 }
01190 else MessageBeep(MB_OK);
01191 }
01192 break;
01193 case IDM_SKTB_LOAD:
01194 if(SelectSfxFileName(0,gszPZEfile,gszPZEdir,
01195 IDX_MISC_LOADPOSE,"(*.PZE)|*.pze|",ghwnd_main) == TRUE){
01196 if((pz=fopen(gszPZEfile,"rb")) != NULL){
01197 fread(&k,sizeof(long),1,pz);
01198 if(k == 0xFEFE){
01199 char robo_name[256];
01200 fread(&k,sizeof(long),1,pz);
01201 fread(robo_name,255,1,pz);
01202 fread(&k,sizeof(long),1,pz);
01203 if(k == SelectedRobot->nskeleton){
01204 if(SelectedRobot->nskeleton > 0){
01205 for(k=0;k<SelectedRobot->nskeleton;k++){
01206 fread(SelectedRobot->skeleton[k].R,sizeof(double),16,pz);
01207 }
01208 ReDrawStageDisplay(TRUE);
01209 PerspectiveView(0,0);
01210 }
01211 }
01212 else SendPrgmQuery(IDQ_BADPOSE,0);
01213 }
01214 else SendPrgmQuery(IDQ_NOTPOSE,0);
01215 fclose(pz);
01216 }
01217 else MessageBeep(MB_OK);
01218 }
01219 break;
01220 case IDM_SKTB_OVERLAY:
01221 RobotOverlayFlag ^= 1;
01222 break;
01223 case IDM_SKTB_TRANSPARENT:
01224 RobotGlassFlag ^= 1;
01225 break;
01226 case IDM_SKTB_POINTS:
01227 RobotPointsFlag ^= 1;
01228 break;
01229 default:
01230 break;
01231 }
01232 if(IsWindow(ghwndRobotView))PostMessage(ghwndRobotView,WM_DRAWROBOT,0,0);
01233 return TRUE;
01234 }
01235
01236 static LRESULT CALLBACK SkTreeViewWndProc(HWND hwnd, UINT msg, WPARAM wparam,
01237 LPARAM lparam ){
01238 static int ToolbarHeight;
01239 TV_ITEM tvi;
01240 RECT rc,rc1;
01241 int dx,dy,y;
01242 DWORD dwStyle;
01243 skel *sp;
01244 switch( msg ){
01245 case WM_CREATE:
01246 dwStyle=WS_CHILD | WS_VISIBLE | WS_BORDER;
01247 if(Preferences.tooltips)dwStyle = dwStyle | TBSTYLE_TOOLTIPS;
01248 hTBWnd = CreateToolbarEx(hwnd,dwStyle,
01249 0,
01250 NTOOLBARBITMAPS,
01251 ghinst_main,
01252 IDBM_SKTOOLBAR,
01253 tbb,
01254 NTOOLBARBUTTONS,
01255 16,15,
01256 16,15,
01257 sizeof(TBBUTTON)
01258 );
01259 SendMessage(hTBWnd,TB_AUTOSIZE,0,0);
01260 gToolFlags.flagK=0;
01261 if(0){dx=32; dy=32;} else {dx=16; dy=16;}
01262 hCoasterImageList=ImageList_Create(
01263 dx,dy,
01264 TRUE,
01265 2,
01266 5
01267 );
01268 ImageList_AddIcon(hCoasterImageList,
01269 LoadIcon(ghinst_main,"TREEVIEWICON0"));
01270 ImageList_AddIcon(hCoasterImageList,
01271 LoadIcon(ghinst_main,"TREEVIEWICON1"));
01272 GetClientRect(hTBWnd,&rc1); ToolbarHeight=rc1.bottom+1;
01273 GetClientRect(hwnd,&rc);
01274 hWndTreeView = CreateWindowEx(0,WC_TREEVIEW,
01275 " ",
01276 WS_VISIBLE | WS_CHILD | WS_BORDER |
01277 TVS_HASLINES | TVS_HASBUTTONS |
01278 TVS_EDITLABELS | TVS_LINESATROOT,
01279 0,ToolbarHeight,
01280 rc.right, rc.bottom,
01281 hwnd,
01282 (HMENU)0,
01283 ghinst_main,
01284 NULL
01285 );
01286 if(hWndTreeView != NULL){
01287 TreeView_SetImageList(hWndTreeView,hCoasterImageList,0);
01288 ImageList_SetBkColor(hCoasterImageList,GetSysColor(COLOR_WINDOW));
01289 UpdateSkTreeView();
01290 }
01291 LastSelectedRobotNode=SelectedNode;
01292 UpdateRobot(SelectedRobot);
01293 break;
01294 case WM_DESTROY:{
01295 char str[32];
01296 GetWindowRect(hwnd,&rc);
01297 sprintf(str,"%ld",rc.left);
01298 WritePrivateProfileString(IniSection,"RSPOSX",str,IniFilename);
01299 sprintf(str,"%ld",rc.top);
01300 WritePrivateProfileString(IniSection,"RSPOSY",str,IniFilename);
01301 sprintf(str,"%ld",rc.right-rc.left);
01302 WritePrivateProfileString(IniSection,"RSSIZX",str,IniFilename);
01303 sprintf(str,"%ld",rc.bottom-rc.top);
01304 WritePrivateProfileString(IniSection,"RSSIZY",str,IniFilename);
01305 SkTreeViewXpos=rc.left; SkTreeViewYpos=rc.top;
01306 SkTreeViewXsize=rc.right-rc.left; SkTreeViewYsize=rc.bottom-rc.top;
01307 if(hCoasterImageList != NULL)ImageList_Destroy(hCoasterImageList);
01308 hCoasterImageList=NULL;
01309 DestroyWindow(hWndTreeView);
01310 hWndTreeView=NULL;
01311 DestroyWindow(hTBWnd);
01312 hTBWnd=NULL;
01313 }
01314 break;
01315 case WM_SYSCOMMAND:
01316 switch(LOWORD(wparam & 0xfff0)){
01317 case SC_CLOSE:
01318
01319 PostQuitMessage(0);
01320 break;
01321 default:
01322 return(DefWindowProc(hwnd,msg,wparam,lparam));
01323 }
01324 break;
01325 case WM_NOTIFY:
01326 switch (ptrNMHDR->code){
01327 case TTN_NEEDTEXT:{
01328 int idButton;
01329 LPTOOLTIPTEXT lpttt;
01330 lpttt=(LPTOOLTIPTEXT)lparam;
01331 lpttt->hinst=ghinst_main;
01332 idButton=lpttt->hdr.idFrom;
01333 switch(idButton){
01334 case IDM_SKTB_V:
01335 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_1); break;
01336 case IDM_SKTB_U:
01337 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_2); break;
01338 case IDM_SKTB_W:
01339 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_3); break;
01340 case IDM_SKTB_X:
01341 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_4); break;
01342 case IDM_SKTB_Y:
01343 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_5); break;
01344 case IDM_SKTB_Z:
01345 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_6); break;
01346 case IDM_SKTB_R:
01347 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_7); break;
01348 case IDM_SKTB_RESET:
01349 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_8); break;
01350 case IDM_SKTB_COPY:
01351 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_9); break;
01352 case IDM_SKTB_LOAD:
01353 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_0); break;
01354 case IDM_SKTB_SAVE:
01355 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_A); break;
01356 case IDM_SKTB_ZOOM:
01357 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_B); break;
01358 case IDM_SKTB_ZOOM_STATE:
01359 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_C); break;
01360 case IDM_SKTB_RESET_SELECT:
01361 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_D); break;
01362 case IDM_SKTB_OVERLAY:
01363 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_E); break;
01364 case IDM_SKTB_TRANSPARENT:
01365 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_F); break;
01366 case IDM_SKTB_POINTS:
01367 lpttt->lpszText=MAKEINTRESOURCE(IDI_TIP_K_G); break;
01368 }
01369 }
01370 break;
01371 case TVN_SELCHANGED:
01372 if(ptrNM_TREEVIEW->action == TVC_BYKEYBOARD ||
01373 ptrNM_TREEVIEW->action == TVC_BYMOUSE){
01374 tvi.mask = TVIF_PARAM;
01375 tvi.hItem = ptrNM_TREEVIEW->itemNew.hItem;
01376 TreeView_GetItem(hWndTreeView,&tvi);
01377 DrawInvertNode(ghdc_triview_Bitmap,SelectedNode,SELECTED);
01378 SelectedRobotArm=(long)tvi.lParam;
01379 DrawInvertNode(ghdc_triview_Bitmap,SelectedNode,SELECTED);
01380 if(IsWindow(ghwndRobotView))PostMessage(ghwndRobotView,WM_DRAWROBOT,0,0);
01381 }
01382 break;
01383 case TVN_BEGINLABELEDIT:
01384 return 1;
01385 break;
01386 default: break;
01387 }
01388 return (DefWindowProc(hwnd,msg,wparam,lparam));
01389 case WM_COMMAND:
01390 return TreeviewMenuCommand(hwnd,LOWORD(wparam));
01391 break;
01392 case WM_SIZE:
01393 if(hTBWnd != NULL){
01394 SendMessage(hTBWnd,msg,wparam,lparam);
01395 }
01396 if(hWndTreeView != NULL){
01397 SetWindowPos(hWndTreeView,NULL,
01398 0,ToolbarHeight,
01399 LOWORD(lparam),HIWORD(lparam)-ToolbarHeight,
01400 SWP_NOZORDER);
01401 }
01402 break;
01403 default:
01404 return(DefWindowProc(hwnd,msg,wparam,lparam));
01405 }
01406 return( 0L );
01407 }
01408
01409 static void ThreadSkeletonTreeView(void *);
01410 static void RobotSkeletonTreeView(HWND hWndParent){
01411 void (*fp)(void *);
01412 if(ghwndSkEdit != NULL){
01413 PostMessage(ghwndSkEdit,WM_SYSCOMMAND,SC_CLOSE,0);
01414 return;
01415 }
01416 fp=ThreadSkeletonTreeView;
01417 #if __WATCOMC__ && __WATCOMC__ < 1100
01418 _beginthread(fp,0,65536,(void *)hWndParent);
01419 #else
01420 _beginthread(fp,0,(void *)hWndParent);
01421 #endif
01422 }
01423
01424 static void ThreadSkeletonTreeView(void *arg){
01425 WNDCLASS wc;
01426 RECT rc;
01427 int xp,yp,xl,yl;
01428 HWND hWndParent;
01429 hWndParent=(HWND)arg;
01430 RobotZoomFlag=FALSE;
01431 RobotZoomState=FALSE;
01432 RobotOverlayFlag=FALSE;
01433 RobotGlassFlag=FALSE;
01434 RobotPointsFlag=FALSE;
01435 wc.lpszClassName = lpszSkTreeViewClass;
01436 wc.style = CS_HREDRAW | CS_VREDRAW;
01437 wc.lpfnWndProc = (WNDPROC)SkTreeViewWndProc;
01438 wc.cbClsExtra = 0;
01439 wc.cbWndExtra = 0;
01440 wc.hInstance = ghinst_main;
01441 wc.hIcon = LoadIcon(ghinst_main,"ANIMATORICON");
01442 wc.hCursor = LoadCursor(NULL,IDC_ARROW);
01443 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
01444 wc.lpszMenuName = NULL;
01445 if(!RegisterClass(&wc))return;
01446 GetWindowRect(ghwndTools,&rc);
01447 if(SkTreeViewXpos < 0){
01448 xp=GetPrivateProfileInt(IniSection,"RSPOSX",-1,IniFilename);
01449 yp=GetPrivateProfileInt(IniSection,"RSPOSY",-1,IniFilename);
01450 xl=GetPrivateProfileInt(IniSection,"RSSIZX",-1,IniFilename);
01451 yl=GetPrivateProfileInt(IniSection,"RSSIZY",-1,IniFilename);
01452 if(xp < 0 || yp < 0 || xl < 0 || yl < 0){
01453 SkTreeViewXsize=185;
01454 SkTreeViewYsize=255;
01455 if(bToolpannelLeft)SkTreeViewXpos=rc.right+5;
01456 else SkTreeViewXpos=rc.left-SkTreeViewXsize-5;
01457 SkTreeViewYpos=rc.top;
01458 }
01459 else{
01460 SkTreeViewXsize=xl;
01461 SkTreeViewYsize=yl;
01462 SkTreeViewXpos=xp;
01463 SkTreeViewYpos=yp;
01464 }
01465 }
01466 LoadString(ghinst_main,IDX_MISC_ROBOTHIERARCHY,res_str,256);
01467 ghwndSkEdit = CreateWindow(
01468 wc.lpszClassName,res_str,
01469 WS_POPUP | WS_CAPTION | !WS_SYSMENU | WS_THICKFRAME,
01470 SkTreeViewXpos,SkTreeViewYpos,
01471 SkTreeViewXsize,SkTreeViewYsize,
01472 hWndParent,NULL,ghinst_main,NULL);
01473 ShowWindow(ghwndSkEdit,SW_SHOW);
01474 UpdateWindow(ghwndSkEdit);
01475 if(ghwndSkEdit == NULL){
01476 UnregisterClass(lpszSkTreeViewClass,ghinst_main);
01477 return;
01478 }
01479 wc.lpszClassName = lpszRobotViewClass;
01480 wc.style = CS_HREDRAW | CS_VREDRAW;
01481 if(Preferences.use_gl_robot)wc.lpfnWndProc = (WNDPROC)RobotOglViewWndProc;
01482 else wc.lpfnWndProc = (WNDPROC)RobotHdcViewWndProc;
01483 wc.cbClsExtra = 0;
01484 wc.cbWndExtra = 0;
01485 wc.hInstance = ghinst_main;
01486 wc.hIcon = LoadIcon(ghinst_main,"ANIMATORICON");
01487 wc.hCursor = ghcurPan;
01488 wc.hbrBackground = NULL;
01489 wc.lpszMenuName = NULL;
01490 if(!RegisterClass(&wc))return;
01491 LoadString(ghinst_main,IDX_MISC_ROBOTVIEW,res_str,256);
01492 if(RobotViewXpos < 0){
01493 xp=GetPrivateProfileInt(IniSection,"RVPOSX",-1,IniFilename);
01494 yp=GetPrivateProfileInt(IniSection,"RVPOSY",-1,IniFilename);
01495 xl=GetPrivateProfileInt(IniSection,"RVSIZX",-1,IniFilename);
01496 yl=GetPrivateProfileInt(IniSection,"RVSIZY",-1,IniFilename);
01497 if(xp < 0 || yp < 0 || xl < 0 || yl < 0){
01498 RobotViewXpos=150; RobotViewYpos=100;
01499 RobotViewXsize=300; RobotViewYsize=300;
01500 }
01501 else{
01502 RobotViewXpos=xp; RobotViewYpos=yp;
01503 RobotViewXsize=xl; RobotViewYsize=yl;
01504 }
01505 }
01506 ghwndRobotView = CreateWindow(
01507 wc.lpszClassName,res_str,
01508 WS_POPUP | WS_CAPTION | !WS_SYSMENU | WS_THICKFRAME |
01509 WS_VSCROLL | WS_HSCROLL |
01510 WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
01511 RobotViewXpos,RobotViewYpos,
01512 RobotViewXsize,RobotViewYsize,
01513 hWndParent,NULL,ghinst_main,NULL);
01514 ShowWindow(ghwndRobotView,SW_SHOW);
01515 UpdateWindow(ghwndRobotView);
01516 if(ghwndRobotView == NULL){
01517 UnregisterClass(lpszRobotViewClass,ghinst_main);
01518 return;
01519 }
01520
01521 {
01522 MSG msg;
01523 while(GetMessage(&msg,NULL,0,0)){
01524 TranslateMessage(&msg);
01525 DispatchMessage(&msg);
01526 }
01527 DestroyWindow(ghwndSkEdit);
01528 UnregisterClass(lpszSkTreeViewClass,ghinst_main);
01529 ghwndSkEdit=NULL;
01530 if(ghwndRobotView != NULL){
01531 DestroyWindow(ghwndRobotView);
01532 UnregisterClass(lpszRobotViewClass,ghinst_main);
01533 ghwndRobotView=NULL;
01534 }
01535
01536 _endthread();
01537 }
01538
01539 return;
01540 }
01541
01542 void UpdateRobot(object *Op){
01543 if(ghwndSkEdit == NULL)return;
01544 if(SelectedNode == NULL || SelectedNode->type != ROBOT){
01545 PostMessage(ghwnd_main,WM_COMMAND,IDM_STOP_TOOL,0);
01546 return;
01547 }
01548 if(SelectedNode != LastSelectedRobotNode){
01549
01550 PostMessage(ghwnd_main,WM_COMMAND,IDM_STOP_TOOL,0);
01551 return;
01552 }
01553 if(Op != SelectedRobot){
01554 vector c;
01555 SelectedRobot=Op;
01556 if(Op == NULL)SelectedRobotArm= -1;
01557 else GetRobotVolume(Op->nskeleton,Op->skeleton,c);
01558 }
01559 return;
01560 }
01561
01562 static LRESULT CALLBACK RobotHdcViewWndProc(HWND hwnd, UINT msg,
01563 WPARAM wparam,LPARAM lparam ){
01564 static BOOL flag=FALSE,mmoved=FALSE,bTrackPan=FALSE;
01565 static long xs,ys;
01566 static double up_angle=0.0,round_angle=0.0;
01567 char str[32];
01568 double old;
01569 HDC hdc;
01570 RECT rc;
01571 int i,iPos,iMax,iMin,dn;
01572 switch( msg ){
01573 case WM_CREATE:{
01574 vector c;
01575 GetRobotVolume(SelectedRobot->nskeleton,SelectedRobot->skeleton,c);
01576 hdc=GetDC(hwnd);
01577 hdcRobotView=CreateCompatibleDC(hdc);
01578 ReleaseDC(hwnd,hdc);
01579 SetScrollRange(hwnd, SB_VERT, -89,89,TRUE);
01580 SetScrollRange(hwnd, SB_HORZ, -179,179,TRUE);
01581 SetScrollPos(hwnd,SB_HORZ,(int)round_angle,TRUE);
01582 SetScrollPos(hwnd,SB_VERT,(int)up_angle,TRUE);
01583 }
01584 break;
01585 case WM_DESTROY:
01586 if(hbmOldRobotView != NULL)SelectObject(hdcRobotView,hbmOldRobotView);
01587 if(hdcRobotView != NULL)DeleteDC(hdcRobotView);
01588 hdcRobotView=NULL;
01589 if(hbmRobotView != NULL)DeleteObject(hbmRobotView);
01590 hbmRobotView=NULL; hbmOldRobotView=NULL;
01591 GetWindowRect(hwnd,&rc);
01592 RobotViewXpos=rc.left; RobotViewYpos=rc.top;
01593 RobotViewXsize=rc.right-rc.left; RobotViewYsize=rc.bottom-rc.top;
01594 sprintf(str,"%ld",rc.left);
01595 WritePrivateProfileString(IniSection,"RVPOSX",str,IniFilename);
01596 sprintf(str,"%ld",rc.top);
01597 WritePrivateProfileString(IniSection,"RVPOSY",str,IniFilename);
01598 sprintf(str,"%ld",rc.right-rc.left);
01599 WritePrivateProfileString(IniSection,"RVSIZX",str,IniFilename);
01600 sprintf(str,"%ld",rc.bottom-rc.top);
01601 WritePrivateProfileString(IniSection,"RVSIZY",str,IniFilename);
01602 break;
01603 case WM_SYSCOMMAND:
01604 switch(LOWORD(wparam & 0xfff0)){
01605 case SC_CLOSE:
01606 break;
01607 default:
01608 return(DefWindowProc(hwnd,msg,wparam,lparam));
01609 }
01610 break;
01611 case WM_SIZE:
01612 if(hbmOldRobotView != NULL)SelectObject(hdcRobotView,hbmOldRobotView);
01613 if(hbmRobotView != NULL)DeleteObject(hbmRobotView);
01614 hbmRobotView=NULL;
01615
01616
01617 SelectObject(hdcRobotView,ghRobotBrush);
01618 GetClientRect(hwnd,&rc);
01619 hdc=GetDC(hwnd);
01620 hbmRobotView=CreateCompatibleBitmap(hdc,rc.right,rc.bottom);
01621 ReleaseDC(hwnd,hdc);
01622 hbmOldRobotView=SelectObject(hdcRobotView,hbmRobotView);
01623 PatBlt(hdcRobotView,0,0,rc.right,rc.bottom,PATCOPY);
01624 SendMessage(hwnd,WM_DRAWROBOT,0,0);
01625 break;
01626 case WM_LBUTTONDOWN:
01627 mmoved=FALSE;
01628 xs=LOWORD(lparam);
01629 ys=HIWORD(lparam);
01630 SetCapture(hwnd);
01631 bTrackPan=TRUE;
01632 break;
01633 case WM_MOUSEMOVE:
01634 if(bTrackPan){
01635 long dx,dy;
01636 dx=(short)LOWORD(lparam)-xs; xs=(short)LOWORD(lparam);
01637 dy=(short)HIWORD(lparam)-ys; ys=(short)HIWORD(lparam);
01638 if(labs(dx) > 0 || labs(dy) > 0){
01639 mmoved=TRUE;
01640 round_angle=round_angle+(double)dx;
01641 while(round_angle < -180.0)round_angle += 360.0;
01642 while(round_angle > 180.0)round_angle -= 360.0;
01643 SetScrollPos(hwnd,SB_HORZ,(int)round_angle,TRUE);
01644 up_angle=up_angle+(double)dy;
01645 if(up_angle > -90 && up_angle < 90)
01646 SetScrollPos(hwnd,SB_VERT,(int)up_angle,TRUE);
01647 SendMessage(hwnd,WM_DRAWROBOT,0,0);
01648 UpdateWindow(ghwndRobotView);
01649
01650 }
01651 }
01652 break;
01653 case WM_LBUTTONUP:
01654 if(bTrackPan){
01655 ReleaseCapture();
01656 bTrackPan=FALSE;
01657 }
01658 if(mmoved){
01659 mmoved=FALSE;
01660 break;
01661 }
01662 mmoved=FALSE;
01663 case WM_DRAWROBOT:
01664 if(SelectedRobot != NULL && (i=SelectedRobotArm) > 0){
01665 skel *s;
01666 s=SelectedRobot->skeleton;
01667 if((i=s[i].id) >= 0){
01668 if(gToolFlags.flagK == 0)TransformAxis((s+i),s[i].v,s[i].vv);
01669 if(gToolFlags.flagK == 1)TransformAxis((s+i),s[i].u,s[i].uu);
01670 if(gToolFlags.flagK == 2)TransformAxis((s+i),s[i].w,s[i].ww);
01671 }
01672 }
01673 DrawViewRobot(hdcRobotView,hbmRobotView,hwnd,
01674 SelectedNode,SelectedRobotArm,(int)gToolFlags.flagK,
01675 round_angle,up_angle,RobotZoomFlag,RobotZoomState);
01676 break;
01677 case WM_VSCROLL:
01678 GetScrollRange(hwnd,SB_VERT,&iMin,&iMax);
01679 iPos = GetScrollPos(hwnd, SB_VERT);
01680 switch (LOWORD(wparam)) {
01681 case SB_LINEDOWN: dn = 1; break;
01682 case SB_LINEUP: dn = -1; break;
01683 case SB_PAGEDOWN: dn = 5; break;
01684 case SB_PAGEUP: dn = -5; break;
01685 case SB_THUMBTRACK:
01686 case SB_THUMBPOSITION: dn = (int)(short)HIWORD(wparam)-iPos; break;
01687 default: dn = 0;
01688 }
01689 if ((dn = BOUND (iPos + dn, iMin, iMax) - iPos) != 0) {
01690 SetScrollPos(hwnd, SB_VERT, iPos + dn, TRUE);
01691 old=up_angle;
01692 up_angle=(double)(iPos+dn);
01693 if(old != up_angle){
01694 SendMessage(hwnd,WM_DRAWROBOT,0,0);
01695 UpdateWindow(ghwndRobotView);
01696 }
01697 }
01698 break;
01699 case WM_HSCROLL:
01700 GetScrollRange(hwnd, SB_HORZ, &iMin, &iMax);
01701 iPos = GetScrollPos(hwnd, SB_HORZ);
01702 switch (LOWORD(wparam)) {
01703 case SB_LINEDOWN: dn = 1; break;
01704 case SB_LINEUP: dn = -1; break;
01705 case SB_PAGEDOWN: dn = 5; break;
01706 case SB_PAGEUP: dn = -5; break;
01707 case SB_THUMBTRACK:
01708 case SB_THUMBPOSITION: dn = (int)(short)HIWORD(wparam) - iPos; break;
01709 default: dn = 0;
01710 }
01711 if ((dn = BOUND (iPos + dn, iMin, iMax) - iPos) != 0) {
01712 SetScrollPos(hwnd, SB_HORZ, iPos + dn, TRUE);
01713 old=round_angle;
01714 round_angle=(double)(iPos+dn);
01715 if(old != round_angle){
01716 SendMessage(hwnd,WM_DRAWROBOT,0,0);
01717 UpdateWindow(ghwndRobotView);
01718 }
01719 }
01720 break;
01721 case WM_PAINT: {
01722 HDC hdc;
01723 PAINTSTRUCT ps;
01724 HPALETTE hpalT;
01725 hdc=BeginPaint(hwnd,&ps);
01726
01727
01728 GetClientRect(hwnd,&rc);
01729 if(hdcRobotView != NULL)
01730 BitBlt(hdc,0,0,rc.right,rc.bottom,hdcRobotView,0,0,SRCCOPY);
01731
01732 EndPaint(hwnd,&ps);
01733 }
01734 break;
01735 default:
01736 return(DefWindowProc(hwnd,msg,wparam,lparam));
01737 }
01738 return( 0L );
01739 }
01740
01741
01742
01743
01744
01745 #include <gl\gl.h>
01746 #include <gl\glu.h>
01747
01748 static HPALETTE hRobotPalette=NULL,hRobotOldPalette=NULL;
01749 static HGLRC hRC=NULL;
01750 static HDC hRobotDC=NULL;
01751 static RECT oldRobotRect;
01752 static GLfloat near_plane,far_plane;
01753 static GLfloat gbRed=0.0,gbGreen=0.1,gbBlue=0.3;
01754
01755 static unsigned char threeto8[8] = {
01756 0, 0111>>1, 0222>>1, 0333>>1, 0444>>1, 0555>>1, 0666>>1, 0377
01757 };
01758
01759 static unsigned char twoto8[4] = {
01760 0, 0x55, 0xaa, 0xff
01761 };
01762
01763 static unsigned char oneto8[2] = {
01764 0, 255
01765 };
01766
01767 static int defaultOverride[13] = {
01768 0, 3, 24, 27, 64, 67, 88, 173, 181, 236, 247, 164, 91
01769 };
01770
01771 static PALETTEENTRY defaultPalEntry[20] = {
01772 { 0, 0, 0, 0 },
01773 { 0x80,0, 0, 0 },
01774 { 0, 0x80,0, 0 },
01775 { 0x80,0x80,0, 0 },
01776 { 0, 0, 0x80, 0 },
01777 { 0x80,0, 0x80, 0 },
01778 { 0, 0x80,0x80, 0 },
01779 { 0xC0,0xC0,0xC0, 0 },
01780
01781 { 192, 220, 192, 0 },
01782 { 166, 202, 240, 0 },
01783 { 255, 251, 240, 0 },
01784 { 160, 160, 164, 0 },
01785
01786 { 0x80,0x80,0x80, 0 },
01787 { 0xFF,0, 0, 0 },
01788 { 0, 0xFF,0, 0 },
01789 { 0xFF,0xFF,0, 0 },
01790 { 0, 0, 0xFF, 0 },
01791 { 0xFF,0, 0xFF, 0 },
01792 { 0, 0xFF,0xFF, 0 },
01793 { 0xFF,0xFF,0xFF, 0 }
01794 };
01795
01796 static unsigned char ComponentFromIndex(int i, UINT nbits, UINT shift){
01797 unsigned char val;
01798 val = (unsigned char) (i >> shift);
01799 switch (nbits) {
01800 case 1:
01801 val &= 0x1;
01802 return oneto8[val];
01803 case 2:
01804 val &= 0x3;
01805 return twoto8[val];
01806 case 3:
01807 val &= 0x7;
01808 return threeto8[val];
01809 default:
01810 return 0;
01811 }
01812 }
01813
01814 static void CreateRGBPalette(HDC hDC){
01815 PIXELFORMATDESCRIPTOR pfd;
01816 LOGPALETTE *pPal;
01817 int n, i;
01818 n = GetPixelFormat(hDC);
01819 DescribePixelFormat(hDC, n, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
01820 if(pfd.dwFlags & PFD_NEED_PALETTE) {
01821 n = 1 << pfd.cColorBits;
01822 pPal = (PLOGPALETTE)LocalAlloc(LMEM_FIXED, sizeof(LOGPALETTE) +
01823 n * sizeof(PALETTEENTRY));
01824 pPal->palVersion = 0x300;
01825 pPal->palNumEntries = n;
01826 for (i=0; i<n; i++) {
01827 pPal->palPalEntry[i].peRed =
01828 ComponentFromIndex(i, pfd.cRedBits, pfd.cRedShift);
01829 pPal->palPalEntry[i].peGreen =
01830 ComponentFromIndex(i, pfd.cGreenBits, pfd.cGreenShift);
01831 pPal->palPalEntry[i].peBlue =
01832 ComponentFromIndex(i, pfd.cBlueBits, pfd.cBlueShift);
01833 pPal->palPalEntry[i].peFlags = 0;
01834 }
01835 if((pfd.cColorBits == 8) &&
01836 (pfd.cRedBits == 3) && (pfd.cRedShift == 0) &&
01837 (pfd.cGreenBits == 3) && (pfd.cGreenShift == 3) &&
01838 (pfd.cBlueBits == 2) && (pfd.cBlueShift == 6)) {
01839 for(i = 1 ; i <= 12 ; i++)
01840 pPal->palPalEntry[defaultOverride[i]] = defaultPalEntry[i];
01841 }
01842 hRobotPalette = CreatePalette(pPal);
01843 LocalFree(pPal);
01844 hRobotOldPalette = SelectPalette(hDC,hRobotPalette,FALSE);
01845 n = RealizePalette(hDC);
01846 }
01847 }
01848
01849 static BOOL bSetupPixelFormat(HDC hDC){
01850 static PIXELFORMATDESCRIPTOR pfd = {
01851 sizeof(PIXELFORMATDESCRIPTOR),
01852 1,
01853 PFD_DRAW_TO_WINDOW |
01854 PFD_SUPPORT_OPENGL |
01855 PFD_DOUBLEBUFFER,
01856 PFD_TYPE_RGBA,
01857 24,
01858 0, 0, 0, 0, 0, 0,
01859 0,
01860 0,
01861 0,
01862 0, 0, 0, 0,
01863 32,
01864 0,
01865 0,
01866 PFD_MAIN_PLANE,
01867 0,
01868 0, 0, 0
01869 };
01870 int pixelformat;
01871 if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 ){
01872 MessageBox(NULL, "ChoosePixelFormat failed", "Error", MB_OK);
01873 return FALSE;
01874 }
01875 if (SetPixelFormat(hDC, pixelformat, &pfd) == FALSE) {
01876 MessageBox(NULL, "SetPixelFormat failed", "Error", MB_OK);
01877 return FALSE;
01878 }
01879 CreateRGBPalette(hDC);
01880 return TRUE;
01881 }
01882
01883 static GLvoid initializeGLrobot(HWND hWnd){
01884 GLfloat aspect;
01885 GLfloat d[]={1.0,1.0,1.0,1.0};
01886 GLfloat a[]={0.1,0.1,0.1,1.0};
01887 GLfloat s[]={1.0,1.0,1.0,1.0};
01888 GLfloat p[]={0.5,0.5,0.5,0.0};
01889 if(1)p[3]=1.0;
01890 else p[3]=0.0;
01891 GetClientRect(hWnd, &oldRobotRect);
01892 glClearColor(gbRed,gbGreen,gbBlue,1.0);
01893 glMatrixMode(GL_PROJECTION);
01894 aspect = (GLfloat) oldRobotRect.right / oldRobotRect.bottom;;
01895 near_plane = 1.5; far_plane = 9.5;
01896 gluPerspective(45.0, aspect, near_plane, far_plane);
01897 glMatrixMode( GL_MODELVIEW );
01898 glLoadIdentity();
01899 glClearDepth(1.0);
01900 glEnable(GL_DEPTH_TEST);
01901 if(0)glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE);
01902 else glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,GL_FALSE);
01903 glEnable(GL_LIGHT0);
01904 glLightfv(GL_LIGHT0,GL_DIFFUSE,d);
01905 glLightfv(GL_LIGHT0,GL_AMBIENT,a);
01906 glLightfv(GL_LIGHT0,GL_SPECULAR,s);
01907 glLightfv(GL_LIGHT0,GL_POSITION,p);
01908 glLightf(GL_LIGHT0,GL_LINEAR_ATTENUATION,0.125);
01909 glLightf(GL_LIGHT0,GL_QUADRATIC_ATTENUATION,0.02);
01910 glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
01911 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
01912 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
01913 glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_FASTEST);
01914 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
01915 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
01916 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
01917 }
01918
01919 static void DrawViewRobotGL(HWND hWnd,
01920 node *Np, int arm, int axis,
01921 double ra, double ua,
01922 BOOL zoom,BOOL zoom_state){
01923 GLfloat glos_color[]={1.0,1.0,1.0,1.0};
01924 GLfloat shiny[]={100.0};
01925 short ep1[6]={0,4,0,1,2,0};
01926 short ep2[6]={1,7,4,5,6,3};
01927 short ep3[6]={2,6,5,6,7,7};
01928 short ep4[6]={3,5,1,2,3,4};
01929 double scale,size,x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4,
01930 t1[4][4],t2[4][4],t3[4][4];
01931 vector cc,p1,p2,p3,p4,p21,p41,nn;
01932 long i,j,k,n,Nv;
01933 object *Op;
01934 skel *sp;
01935 if(Np->type == ROBOT && ((Op=Np->fobj) != NULL))while(Op != NULL){
01936 if(CurrentFrame >= Op->firstframe && CurrentFrame <= Op->lastframe){
01937 if((n=Op->nskeleton) == 0 || (sp=Op->skeleton) == NULL)break;
01938
01939 size=(double)GetRobotVolume(n,NULL,cc);
01940 scale=3.25/size;
01941 if(zoom && arm >=0 && arm < n){
01942 if(zoom_state && (j=(sp+arm)->id) >= 0 && j < n){
01943 tram(t1,-((sp+j)->pp[0]),-((sp+j)->pp[1]),-((sp+j)->pp[2]));
01944 scale *= 5.0;
01945 }
01946 else{
01947 tram(t1,-((sp+arm)->pp[0]),-((sp+arm)->pp[1]),-((sp+arm)->pp[2]));
01948 scale *= 4.0;
01949 }
01950 }
01951 else tram(t1,-cc[0],-cc[1],-cc[2]);
01952 rotz(t2, ra*PIo180);
01953 m4by4(t2,t1,t3);
01954 rotx(t1, ua*PIo180);
01955 m4by4(t1,t3,t2);
01956
01957 if(!RobotPointsFlag){
01958 glEnable(GL_LIGHTING);
01959 glEnable(GL_COLOR_MATERIAL);
01960 if(RobotGlassFlag){
01961 glEnable(GL_BLEND);
01962 glDepthMask(GL_FALSE);
01963 glBlendFunc(GL_SRC_ALPHA,GL_ONE);
01964 }
01965 glBegin(GL_QUADS);
01966 glMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS,shiny);
01967 glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,glos_color);
01968 for(k=0;k<n;k++){
01969 m4by4(t2,(sp+k)->T,t3);
01970 if(k == arm)glColor4f(1.0,0.3,0.3,1.0);
01971 else glColor4f(1.0,1.0,0.3,1.0);
01972 for(i=0;i<6;i++){
01973 m4by1(t3,(double)(sp+k)->bx[ep1[i]][0]
01974 ,(double)(sp+k)->bx[ep1[i]][1]
01975 ,(double)(sp+k)->bx[ep1[i]][2]
01976 ,&x1,&y1,&z1);
01977 p1[0]=scale*(x1); p1[1]=scale*(y1); p1[2]=scale*(z1);
01978 m4by1(t3,(double)(sp+k)->bx[ep2[i]][0]
01979 ,(double)(sp+k)->bx[ep2[i]][1]
01980 ,(double)(sp+k)->bx[ep2[i]][2]
01981 ,&x2,&y2,&z2);
01982 p2[0]=scale*(x2); p2[1]=scale*(y2); p2[2]=scale*(z2);
01983 m4by1(t3,(double)(sp+k)->bx[ep3[i]][0]
01984 ,(double)(sp+k)->bx[ep3[i]][1]
01985 ,(double)(sp+k)->bx[ep3[i]][2]
01986 ,&x3,&y3,&z3);
01987 p3[0]=scale*(x3); p3[1]=scale*(y3); p3[2]=scale*(z3);
01988 m4by1(t3,(double)(sp+k)->bx[ep4[i]][0]
01989 ,(double)(sp+k)->bx[ep4[i]][1]
01990 ,(double)(sp+k)->bx[ep4[i]][2]
01991 ,&x4,&y4,&z4);
01992 p4[0]=scale*(x4); p4[1]=scale*(y4); p4[2]=scale*(z4);
01993 VECSUB(p2,p1,p21)
01994 VECSUB(p4,p1,p41)
01995 CROSS(p21,p41,nn)
01996 A_normalize(nn);
01997 glNormal3f(nn[0],nn[2],-nn[1]);
01998 glVertex3f(p1[0],p1[2],-p1[1]);
01999 glVertex3f(p2[0],p2[2],-p2[1]);
02000 glVertex3f(p3[0],p3[2],-p3[1]);
02001 glVertex3f(p4[0],p4[2],-p4[1]);
02002 }
02003 }
02004 glEnd();
02005 if(RobotGlassFlag){
02006 glDepthMask(GL_TRUE);
02007 glDisable(GL_BLEND);
02008 }
02009 glDisable(GL_COLOR_MATERIAL);
02010 glDisable(GL_LIGHTING);
02011 } else {
02012
02013 Nv=Op->npoints;
02014 if(Nv > 0 && Op->in_ram){
02015 glEnable(GL_COLOR_MATERIAL);
02016 if(RobotZoomFlag)glPointSize(3.0);
02017 else glPointSize(1.5);
02018 glBegin(GL_POINTS);
02019 glMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS,shiny);
02020 glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,glos_color);
02021 for(k=0;k<n;k++){
02022 m4by4(t2,(sp+k)->T,t3);
02023 if(k == arm)glColor4f(1.0,0.3,0.3,1.0);
02024 else glColor4f(1.0,1.0,0.3,1.0);
02025 for(i=0;i<Nv;i++){
02026 if(Op->skid[i] == k){
02027 m4by1(t3,(double)(Op->points[i][0] - Op->origin[0])
02028 ,(double)(Op->points[i][1] - Op->origin[1])
02029 ,(double)(Op->points[i][2] - Op->origin[2])
02030 ,&x1,&y1,&z1);
02031 p1[0]=scale*(x1); p1[1]=scale*(y1); p1[2]=scale*(z1);
02032 glVertex3f(p1[0],p1[2],-p1[1]);
02033 }
02034 }
02035 }
02036 glEnd();
02037 glDisable(GL_COLOR_MATERIAL);
02038 }
02039 }
02040
02041 for(k=0;k<n;k++){
02042 x1=(double)sp[k].pp[0]; y1=(double)sp[k].pp[1]; z1=(double)sp[k].pp[2];
02043 m4by1(t2,x1,y1,z1,&x2,&y2,&z2);
02044 sp[k].wk[0]=(long)x2; sp[k].wk[1]=(long)y2; sp[k].wk[2]=(long)z2;
02045 }
02046 glLineWidth(2.0);
02047 if(RobotOverlayFlag)glDepthFunc(GL_ALWAYS);
02048 glBegin(GL_LINES);
02049 for(k=0;k<n;k++){
02050 x1=(double)sp[k].wk[0]; y1=(double)sp[k].wk[1]; z1=(double)sp[k].wk[2];
02051 j=sp[k].id;
02052 if(j < 0)continue;
02053 x2=(double)sp[j].wk[0]; y2=(double)sp[j].wk[1]; z2=(double)sp[j].wk[2];
02054 x1=scale*(x1); y1=scale*(y1); z1=scale*(z1);
02055 x2=scale*(x2); y2=scale*(y2); z2=scale*(z2);
02056 glColor3f(1.0,1.0,0.0);
02057 glVertex3f(x1,z1,-y1);
02058 glVertex3f(x2,z2,-y2);
02059 if(k == arm && axis < 7){
02060 vector pp,x={2.0,0.0,0.0},y={0.0,2.0,0.0},z={0.0,0.0,2.0};
02061
02062 if (axis == 0)VECCOPY((double)sp[j].vv,pp)
02063 else if(axis == 1)VECCOPY((double)sp[j].uu,pp)
02064 else if(axis == 2)VECCOPY((double)sp[j].ww,pp)
02065 else if(axis == 3)VECCOPY(x,pp)
02066 else if(axis == 4)VECCOPY(y,pp)
02067 else if(axis == 5)VECCOPY(z,pp)
02068 if(axis == 0 && (i=sp[j].id) >= 0){
02069 x1=sp[i].pp[0]; y1=sp[i].pp[1]; z1=sp[i].pp[2];
02070 }
02071 else if(axis < 6){
02072 x1=(double)sp[j].pp[0]+(double)pp[0]*size*0.1;
02073 y1=(double)sp[j].pp[1]+(double)pp[1]*size*0.1;
02074 z1=(double)sp[j].pp[2]+(double)pp[2]*size*0.1;
02075 }
02076 else {x1=sp[k].pp[0]; y1=sp[k].pp[1]; z1=sp[k].pp[2];}
02077 m4by1(t2,x1,y1,z1,&x3,&y3,&z3);
02078 x3=scale*(x3); y3=scale*(y3); z3=scale*(z3);
02079 glColor3f(1.0,1.0,1.0);
02080 glLineWidth(4.0);
02081 glVertex3f(x2,z2,-y2);
02082 glVertex3f(x3,z3,-y3);
02083 glLineWidth(2.0);
02084 }
02085 }
02086 glEnd();
02087 if(RobotOverlayFlag)glDepthFunc(GL_LESS);
02088 break;
02089 }
02090 Op=Op->next;
02091 }
02092 }
02093
02094 static GLvoid drawRobotGLscene(HWND hWnd, double up_angle, double round_angle){
02095 HDC hDC;
02096 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
02097 if(1)glShadeModel(GL_FLAT);
02098 else glShadeModel(GL_SMOOTH);
02099 glPushMatrix();
02100 glLoadIdentity();
02101 glTranslatef(0.0, 0.0, -5.0);
02102
02103
02104 DrawViewRobotGL(hWnd,
02105 SelectedNode,SelectedRobotArm,(int)gToolFlags.flagK,
02106 round_angle,up_angle,RobotZoomFlag,RobotZoomState);
02107 glPopMatrix();
02108 glFinish();
02109 hDC = wglGetCurrentDC();
02110 SwapBuffers(hDC);
02111 }
02112
02113 static GLvoid resizeRobotGL(HWND hWnd){
02114 RECT rect;
02115 GLfloat aspect;
02116 GetClientRect(hWnd, &rect);
02117 glViewport(0,0,rect.right,rect.bottom);
02118 oldRobotRect.right = rect.right;
02119 oldRobotRect.bottom = rect.bottom;
02120 glMatrixMode(GL_PROJECTION);
02121 glLoadIdentity();
02122 aspect = (GLfloat)oldRobotRect.right/oldRobotRect.bottom;
02123 gluPerspective( 45.0, aspect, near_plane, far_plane);
02124 glMatrixMode( GL_MODELVIEW );
02125 glLoadIdentity();
02126 }
02127
02128 static LRESULT CALLBACK RobotOglViewWndProc(HWND hwnd, UINT msg,
02129 WPARAM wparam, LPARAM lparam ){
02130 static BOOL flag=FALSE,mmoved=FALSE,bTrackPan=FALSE;
02131 static long xs,ys;
02132 static double up_angle=0.0,round_angle=0.0;
02133 char str[32];
02134 double old;
02135 HDC hDC;
02136 RECT rc;
02137 int i,iPos,iMax,iMin,dn;
02138 switch( msg ){
02139 case WM_CREATE:{
02140 vector c;
02141 GetRobotVolume(SelectedRobot->nskeleton,SelectedRobot->skeleton,c);
02142 SetScrollRange(hwnd, SB_VERT, -89,89,TRUE);
02143 SetScrollRange(hwnd, SB_HORZ, -179,179,TRUE);
02144 SetScrollPos(hwnd,SB_HORZ,(int)round_angle,TRUE);
02145 SetScrollPos(hwnd,SB_VERT,(int)up_angle,TRUE);
02146 hRobotDC = GetDC(hwnd);
02147 bSetupPixelFormat(hRobotDC);
02148 hRC = wglCreateContext(hRobotDC);
02149 wglMakeCurrent(hRobotDC,hRC);
02150 initializeGLrobot(hwnd);
02151 }
02152 break;
02153 case WM_DESTROY:
02154 wglMakeCurrent(NULL,NULL);
02155 if(hRC != NULL)wglDeleteContext(hRC);
02156 if(hRobotDC != NULL)ReleaseDC(hwnd,hRobotDC);
02157 GetWindowRect(hwnd,&rc);
02158 RobotViewXpos=rc.left; RobotViewYpos=rc.top;
02159 RobotViewXsize=rc.right-rc.left; RobotViewYsize=rc.bottom-rc.top;
02160 sprintf(str,"%ld",rc.left);
02161 WritePrivateProfileString(IniSection,"RVPOSX",str,IniFilename);
02162 sprintf(str,"%ld",rc.top);
02163 WritePrivateProfileString(IniSection,"RVPOSY",str,IniFilename);
02164 sprintf(str,"%ld",rc.right-rc.left);
02165 WritePrivateProfileString(IniSection,"RVSIZX",str,IniFilename);
02166 sprintf(str,"%ld",rc.bottom-rc.top);
02167 WritePrivateProfileString(IniSection,"RVSIZY",str,IniFilename);
02168 break;
02169 case WM_SYSCOMMAND:
02170 switch(LOWORD(wparam & 0xfff0)){
02171 case SC_CLOSE:
02172 break;
02173 default:
02174 return(DefWindowProc(hwnd,msg,wparam,lparam));
02175 }
02176 break;
02177 case WM_SIZE:
02178 resizeRobotGL(hwnd);
02179 break;
02180 case WM_LBUTTONDOWN:
02181 mmoved=FALSE;
02182 xs=LOWORD(lparam);
02183 ys=HIWORD(lparam);
02184 SetCapture(hwnd);
02185 bTrackPan=TRUE;
02186 break;
02187 case WM_MOUSEMOVE:
02188 if(bTrackPan){
02189 long dx,dy;
02190 dx=(short)LOWORD(lparam)-xs; xs=(short)LOWORD(lparam);
02191 dy=(short)HIWORD(lparam)-ys; ys=(short)HIWORD(lparam);
02192 if(labs(dx) > 0 || labs(dy) > 0){
02193 mmoved=TRUE;
02194 round_angle=round_angle+(double)dx;
02195 while(round_angle < -180.0)round_angle += 360.0;
02196 while(round_angle > 180.0)round_angle -= 360.0;
02197 SetScrollPos(hwnd,SB_HORZ,(int)round_angle,TRUE);
02198 up_angle=up_angle+(double)dy;
02199 if(up_angle > -90 && up_angle < 90)
02200 SetScrollPos(hwnd,SB_VERT,(int)up_angle,TRUE);
02201 InvalidateRect(hwnd, NULL, FALSE);
02202 }
02203 }
02204 break;
02205 case WM_LBUTTONUP:
02206 if(bTrackPan){
02207 ReleaseCapture();
02208 bTrackPan=FALSE;
02209 }
02210 if(mmoved){
02211 mmoved=FALSE;
02212 break;
02213 }
02214 mmoved=FALSE;
02215 case WM_DRAWROBOT:
02216 if(SelectedRobot != NULL && (i=SelectedRobotArm) > 0){
02217 skel *s;
02218 s=SelectedRobot->skeleton;
02219 if((i=s[i].id) >= 0){
02220 if(gToolFlags.flagK == 0)TransformAxis((s+i),s[i].v,s[i].vv);
02221 if(gToolFlags.flagK == 1)TransformAxis((s+i),s[i].u,s[i].uu);
02222 if(gToolFlags.flagK == 2)TransformAxis((s+i),s[i].w,s[i].ww);
02223 }
02224 }
02225 InvalidateRect(hwnd,NULL,FALSE);
02226 break;
02227 case WM_VSCROLL:
02228 GetScrollRange(hwnd,SB_VERT,&iMin,&iMax);
02229 iPos = GetScrollPos(hwnd, SB_VERT);
02230 switch (LOWORD(wparam)) {
02231 case SB_LINEDOWN: dn = 1; break;
02232 case SB_LINEUP: dn = -1; break;
02233 case SB_PAGEDOWN: dn = 5; break;
02234 case SB_PAGEUP: dn = -5; break;
02235 case SB_THUMBTRACK:
02236 case SB_THUMBPOSITION: dn = (int)(short)HIWORD(wparam)-iPos; break;
02237 default: dn = 0;
02238 }
02239 if ((dn = BOUND (iPos + dn, iMin, iMax) - iPos) != 0) {
02240 SetScrollPos(hwnd, SB_VERT, iPos + dn, TRUE);
02241 old=up_angle;
02242 up_angle=(double)(iPos+dn);
02243 if(old != up_angle){
02244 SendMessage(hwnd,WM_DRAWROBOT,0,0);
02245 UpdateWindow(ghwndRobotView);
02246 }
02247 }
02248 break;
02249 case WM_HSCROLL:
02250 GetScrollRange(hwnd, SB_HORZ, &iMin, &iMax);
02251 iPos = GetScrollPos(hwnd, SB_HORZ);
02252 switch (LOWORD(wparam)) {
02253 case SB_LINEDOWN: dn = 1; break;
02254 case SB_LINEUP: dn = -1; break;
02255 case SB_PAGEDOWN: dn = 5; break;
02256 case SB_PAGEUP: dn = -5; break;
02257 case SB_THUMBTRACK:
02258 case SB_THUMBPOSITION: dn = (int)(short)HIWORD(wparam) - iPos; break;
02259 default: dn = 0;
02260 }
02261 if ((dn = BOUND (iPos + dn, iMin, iMax) - iPos) != 0) {
02262 SetScrollPos(hwnd, SB_HORZ, iPos + dn, TRUE);
02263 old=round_angle;
02264 round_angle=(double)(iPos+dn);
02265 if(old != round_angle){
02266 SendMessage(hwnd,WM_DRAWROBOT,0,0);
02267 UpdateWindow(ghwndRobotView);
02268 }
02269 }
02270 break;
02271 case WM_PAINT: {
02272 PAINTSTRUCT ps;
02273 BeginPaint(hwnd,&ps);
02274 drawRobotGLscene(hwnd,up_angle,round_angle);
02275 EndPaint(hwnd,&ps);
02276 }
02277 break;
02278 case WM_QUERYNEWPALETTE:{
02279 HPALETTE hpalOld;
02280 if(hRobotPalette != NULL){
02281 hDC = GetDC(hwnd);
02282 hpalOld = SelectPalette(hDC, hRobotPalette, FALSE);
02283 RealizePalette(hDC);
02284 InvalidateRect(hwnd,NULL,TRUE);
02285 UpdateWindow(hwnd);
02286 if(hpalOld != NULL)SelectPalette(hDC, hpalOld, FALSE);
02287 ReleaseDC(hwnd,hDC);
02288 return TRUE;
02289 }
02290 return FALSE;
02291 }
02292 case WM_PALETTECHANGED:{
02293 HPALETTE hpalOld;
02294 if(hRobotPalette != NULL){
02295 if (wparam != (WPARAM)hwnd){
02296 hDC = GetDC(hwnd);
02297 hpalOld = SelectPalette(hDC,hRobotPalette,FALSE);
02298 RealizePalette(hDC);
02299 UpdateColors(hDC);
02300 if(hpalOld != NULL)SelectPalette(hDC,hpalOld,FALSE);
02301 ReleaseDC(hwnd,hDC);
02302 }
02303 }
02304 }
02305 break;
02306 default:
02307 return(DefWindowProc(hwnd,msg,wparam,lparam));
02308 }
02309 return( 0L );
02310 }
02311
02312
02313