00001
00002
00003
00004
00005 #define MODULE_LOADER
00006
00007 #include "render.h"
00008
00009 extern char gszHomeDir[];
00010
00011 extern char TempPath[];
00012
00013 typedef double quaternion[4];
00014
00015 static void InterpolateRobot(double mr, long n, skel *sk1, skel *sk2);
00016 static long RenderReadNurbs(long, long clen);
00017 static long *RenderReadSkeleton(long clen, short version, skel **sp, long *);
00018 static short R_ReadAxis(long, long clen);
00019 static short R_ReadFaces(long, long clen, int version);
00020 static short R_ReadVertices(long, long clen);
00021 static short R_ReadVertText(long, long clen, BOOL);
00022 static short R_ReadFaceMapping(long ObjectID, long clen);
00023 static short R_ReadImaps(long, long clen, long frame,
00024 char *objectfilename, char *str, BOOL new_type);
00025 static unsigned char *ReadShaderFromBuffer(long id, matl *Mat, unsigned char *b);
00026 static short R_ReadMaterial(long id, long, long clen);
00027 static void CompleteImageMapLoading(long, char *);
00028 static void LoadEmbededImageMaps(long, long clen, char *objectfilename);
00029 static short R_ReadMorphShader(long clen,
00030 char *objectfilename, char *str);
00031 static void R_MorphVector(long, vector b, ivector Mx, double mr);
00032 static int IdentifyImageFileType(char *fn);
00033
00034 HANDLE fp;
00035 DWORD dwRead;
00036 static char str[10]={0,0,0,0,0, 0,0,0,0,0};
00037 static long newface,newvert;
00038 static int number_of_file_extensions=6;
00039 static char *image_file_extensions[]={".gif",".tga",".tif",".jpg",".png",".bmp"};
00040 static double ruler_length;
00041 static int IdentifyImageFileType(char *fn){
00042 int i; char last4[5];
00043 last4[4]=0;
00044 strncpy(last4,(fn+strlen(fn)-4),4);
00045 strlwr(last4);
00046 for(i=0;i<number_of_file_extensions;i++){
00047 if(strncmp((char *)last4,image_file_extensions[i],4) == 0)return i;
00048 }
00049 return -1;
00050 }
00051
00052 char R_getl(long *val){
00053 long l,l0,l1,l2,l3;
00054 ReadFile(fp,&l,sizeof(long),&dwRead,NULL);
00055 l0 = (l >> 24) & 0x000000ff;
00056 l1 = (l >> 16) & 0x000000ff;
00057 l2 = (l >> 8) & 0x000000ff;
00058 l3 = (l ) & 0x000000ff;
00059 *val = (l3 << 24) | (l2 << 16) | (l1 << 8) | l0;
00060 return(1);
00061 }
00062
00063 char R_getsht(short * val){
00064 short s,s0,s1;
00065 ReadFile(fp,&s,sizeof(short),&dwRead,NULL);
00066 s0 = (s >> 8) & 0x00ff;
00067 s1 = (s ) & 0x00ff;
00068 *val = (s1 << 8) | s0;
00069 return(1);
00070 }
00071
00072 char R_getusht(unsigned short * val){
00073 unsigned short s,s0,s1;
00074 ReadFile(fp,&s,sizeof(short),&dwRead,NULL);
00075 s0 = (s >> 8) & 0x00ff;
00076 s1 = (s ) & 0x00ff;
00077 *val = (s1 << 8) | s0;
00078 return(1);
00079 }
00080
00081 static unsigned short GetUshortFromBuffer(unsigned char *b){
00082 return ((unsigned short)(*b) << 8) | (unsigned short)(*(b+1));
00083 }
00084
00085 static short GetShortFromBuffer(unsigned char *b){
00086 return ((short)(*b) << 8) | (short)(*(b+1));
00087 }
00088
00089 static long GetLongFromBuffer(unsigned char *b){
00090 return ((long)(*b) << 24) | ((long)(*(b+1)) << 16) |
00091 ((long)(*(b+2)) << 8) | (long)(*(b+3));
00092 }
00093
00095
00096 static void R_MorphVector(long ObjectID, vector b, ivector Mx, double mr){
00097 long i,j;
00098 for(i=0;i<3;i++){
00099 R_getl(&j); j=j+Object[ObjectID].Centre[i]-Mx[i];
00100 b[i]=(b[i]-(double)j)*mr + (double)j;
00101 }
00102 }
00103
00104 #define MORPH1(a,b,m) { a = (unsigned char)(((double)b -(double)a)*(m) + (double)a);}
00105 #define MORPH2(a,b,m) { a = (unsigned char)(((double)b -(double)a)*(m) + (double)a);}
00106
00107 static unsigned char *ReadMorphShaderFromBuffer(long id, matl *Mat, unsigned char *b){
00108 char tempname[256],tempparam[512];
00109 long version,active,in_use,ln,lp;
00110 version=GetLongFromBuffer(b); b+= 4;
00111 active =GetLongFromBuffer(b); b+= 4;
00112 in_use =GetLongFromBuffer(b); b+= 4;
00113 Mat->shaderID[id] = -1;
00114 if(in_use){
00115 ln=GetLongFromBuffer(b); b+= 4;
00116 lp=GetLongFromBuffer(b); b+= 4;
00117 memcpy(tempname,b,ln+1); b += ln+1;
00118 memcpy(tempparam,b,lp+1); b += lp+1;
00119
00120
00121
00122
00123 }
00124 return b;
00125 }
00126
00127 static short MorphMaterial(long id, long ObjectID, long clen, double mr){
00128 long i,j,v,l,n;
00129 unsigned char *buffer=NULL,*b,color[3],texco[3];
00130 matl *Mat;
00131 buffer=(unsigned char *)X__Malloc(clen);
00132 if(buffer == NULL)return -1;
00133 ReadFile(fp,buffer,clen,&dwRead,NULL);
00134 b=buffer; n=GetLongFromBuffer(b); b+= 4;
00135 if(n > 0){
00136
00137 n=min(n,Object[ObjectID].NoMats);
00138 for(i=0;i<n;i++){
00139 Mat=(Object[ObjectID].Tbase+(long)i);
00140 b+= 4; b+= 32;
00141 memcpy(color,b,3); b+= 3;
00142 memcpy(texco,b,3); b+= 3;
00143 for(j=0;j<3;j++)MORPH1(Mat->color[j],color[j],1.0-mr)
00144 for(j=0;j<3;j++)MORPH1(Mat->texco[j],texco[j],1.0-mr)
00145 b += 5*3; b+= 24;
00146 for(j=0;j<3;j++){l=GetLongFromBuffer(b); b+= 4; MORPH2(Mat->ax.bo[j],l,mr) }
00147 for(j=0;j<3;j++){l=GetLongFromBuffer(b); b+= 4; MORPH2(Mat->ax.bu[j],l,mr) }
00148 for(j=0;j<3;j++){l=GetLongFromBuffer(b); b+= 4; MORPH2(Mat->ax.bv[j],l,mr) }
00149 VECCOPY(Mat->ax.bo,Mat->ax.boin)
00150 VECCOPY(Mat->ax.bu,Mat->ax.buin)
00151 VECCOPY(Mat->ax.bv,Mat->ax.bvin)
00152 for(j=0;j<4;j++)b=ReadMorphShaderFromBuffer(j,Mat,b);
00153 b+= 20; b += 16*4; b += 16*4;
00154 if(id > 1)b += 512;
00155 }
00156 }
00157 X__Free(buffer);
00158 return 0;
00159 }
00160
00161 static short MorphFaces(long ObjectID, long clen, int version, double mo){
00162 long i,j,nf,sf;
00163 unsigned char color[3];
00164 unsigned char *buffer=NULL,*b;
00165 face *f;
00166 if (version == 0)nf=clen/18;
00167 else if(version == 1)nf=clen/24;
00168 else nf=clen/20;
00169 if(nf == 0)return -1;
00170 sf=sizeof(face);
00171 buffer=(unsigned char *)X__Malloc(clen);
00172 if(buffer == NULL)return -1;
00173 ReadFile(fp,buffer,clen,&dwRead,NULL);
00174 nf=min(nf,Object[ObjectID].NoFaces);
00175 f=Object[ObjectID].Fbase;
00176 b=buffer;
00177
00178 for(i=0;i<nf;i++,f++){
00179 if(version == 0) b+= 6; else b+= 12;
00180 memcpy(color,b,3);b+=3;
00181 if(version == 2) b+= 5; else b+= 9;
00182 for(j=0;j<3;j++)MORPH1(f->color[j],color[j],1.0-mo)
00183 }
00184 X__Free(buffer);
00185 return 0;
00186 }
00187
00188 long LoadMorphObject(long ObjectID, short mo, char *FileName,double mr,
00189 char *QmorphFile,double qr){
00190 unsigned char *buffer=NULL,*b;
00191 long CHUNKsize,FORMsize,i,j,nm;
00192 ivector Mx,Mv,Mq;
00193 vector V0,V1,VM;
00194 vertex *v;
00195 face *f;
00196 int same=1;
00197 Mx[0]=0; Mx[1]=0; Mx[2]=0;
00198 if((fp=GetRenderRelativeHandle((char *)strlwr(FileName),NULL,NULL))
00199 == INVALID_HANDLE_VALUE){ Render_Message(20,1,NULL); goto X__ERROR;
00200 }
00201 ReadFile(fp,str,4,&dwRead,NULL);
00202 if(dwRead != 4 || strcmp(str,"FORM") != 0){
00203 Render_Message(21,1,NULL); CloseHandle(fp); goto X__ERROR;
00204 }
00205 ReadFile(fp,&FORMsize,4,&dwRead,NULL); ReadFile(fp,str,4,&dwRead,NULL);
00206 if(dwRead != 4 || (strcmp(str,"OFXM"))){
00207 Render_Message(22,1,NULL); CloseHandle(fp); goto X__ERROR;
00208 }
00209 loop:
00210 if(!ReadFile(fp,str,4,&dwRead,NULL))goto end;
00211 if(dwRead != 4)goto end;
00212 if (R_getl(&CHUNKsize) != 1)goto end;
00213 if(strcmp(str,"AXIS") == 0){
00214 R_getl(&j); Mx[0] = j; R_getl(&j); Mx[1] = j; R_getl(&j); Mx[2] = j;
00215 R_MorphVector(ObjectID,Object[ObjectID].Abase.bo,Mx,mr);
00216 R_MorphVector(ObjectID,Object[ObjectID].Abase.bu,Mx,mr);
00217 R_MorphVector(ObjectID,Object[ObjectID].Abase.bv,Mx,mr);
00218 VECCOPY(Object[ObjectID].Abase.bo,Object[ObjectID].Abase.boin)
00219 VECCOPY(Object[ObjectID].Abase.bu,Object[ObjectID].Abase.buin)
00220 VECCOPY(Object[ObjectID].Abase.bv,Object[ObjectID].Abase.bvin)
00221 }
00222 else if (strcmp(str,"VERT") == 0){
00223 nm=CHUNKsize/12;
00224 nm=min(nm,Object[ObjectID].NoVertices);
00225 v=Object[ObjectID].Vbase;
00226 for(i=0;i<nm;i++){
00227 R_getl(&j); Mv[0] = j+Object[ObjectID].Centre[0]-Mx[0];
00228 R_getl(&j); Mv[1] = j+Object[ObjectID].Centre[1]-Mx[1];
00229 R_getl(&j); Mv[2] = j+Object[ObjectID].Centre[2]-Mx[2];
00230 v[i].p[0] = (v[i].p[0]-(double)Mv[0])*mr + (double)Mv[0];
00231 v[i].p[1] = (v[i].p[1]-(double)Mv[1])*mr + (double)Mv[1];
00232 v[i].p[2] = (v[i].p[2]-(double)Mv[2])*mr + (double)Mv[2];
00233 }
00234 }
00235 else if(strcmp(str,"SFCE") == 0){if(MorphFaces(ObjectID,CHUNKsize,0,mr) < 0); goto end;}
00236 else if(strcmp(str,"LFCE") == 0){if(MorphFaces(ObjectID,CHUNKsize,1,mr) < 0); goto end;}
00237 else if(strcmp(str,"NFCE") == 0){if(MorphFaces(ObjectID,CHUNKsize,2,mr) < 0) goto end;}
00238 else if(strcmp(str,"MTL1") == 0){MorphMaterial(1,ObjectID,CHUNKsize,mr); goto end;}
00239 else if(strcmp(str,"MTL2") == 0){MorphMaterial(2,ObjectID,CHUNKsize,mr); goto end;}
00240 else if(strcmp(str,"IMAP") == 0)goto end;
00241 else if(strcmp(str,"IMA2") == 0)goto end;
00242 else if(strcmp(str,"EMAP") == 0)goto end;
00243 else R_getchunk(CHUNKsize);
00244 goto loop;
00245 end: CloseHandle(fp);
00246 return 1;
00247 X__ERROR:
00248 return 0;
00249 }
00250
00251
00252
00253 static long *RenderReadSkeleton(long clen, short version, skel **sp, long *ns){
00254 short ss;
00255 long s;
00256 skel *Skeleton;
00257 long n,i,j,k,l,l0,l1,l2,*jj,*Skid;
00258 char name[32];
00259 Skeleton=NULL;
00260 Skid=NULL;
00261 R_getl(&n); *ns=n;
00262 if((*sp=(skel *)X__Malloc(n*(long)sizeof(skel))) != NULL)Skeleton=*sp;
00263 for(i=0;i<n;i++){
00264 R_getl(&l0); R_getl(&l1); R_getl(&l2);
00265 if(version > 2)R_getl(&s);
00266 else{R_getsht(&ss); s=(long)ss;}
00267 if(Skeleton != NULL){
00268 (Skeleton+i)->id=(long)s;
00269 (Skeleton+i)->p[0] = (double)(l0);
00270 (Skeleton+i)->p[1] = (double)(l1);
00271 (Skeleton+i)->p[2] = (double)(l2);
00272 VECCOPY((Skeleton+i)->p,(Skeleton+i)->pcopy)
00273 }
00274 if(version > 0){
00275 ReadFile(fp,name,sizeof(char)*16,&dwRead,NULL);
00276 if(version > 3){
00277 R_getl(&l);
00278 (Skeleton+i)->weight=(double)l/1000.0;
00279 R_getl(&l);
00280 (Skeleton+i)->wrange=(double)l/1000.0;
00281 R_getl(&l);
00282 (Skeleton+i)->wzone=(double)l/1000.0;
00283 }
00284 else { (Skeleton+i)->weight=1.0; (Skeleton+i)->wrange=1000.0; (Skeleton+i)->wzone=1.0;}
00285 }
00286 if(version > 1){
00287 for(j=0;j<3;j++){R_getl(&l);}
00288 for(j=0;j<3;j++){R_getl(&l);}
00289 for(j=0;j<3;j++){R_getl(&l);}
00290 for(j=0;j<8;j++)for(k=0;k<3;k++)R_getl(&l);
00291 }
00292 }
00293 R_getl(&n);
00294 if(n > 0){
00295 if(n == newvert){
00296 if((Skid=(long *)X__Malloc(n*(long)sizeof(long))) != NULL)jj=Skid;
00297 }
00298 for(i=0;i<n;i++){
00299 if(version > 2)R_getl(&s);
00300 else {R_getsht(&ss); s=(long)ss;}
00301 if(Skid != NULL)*jj++ = (long)s;
00302 }
00303 }
00304 return Skid;
00305 }
00306
00307 typedef struct tVECTOR4tag {
00308 tDOUBLE x,y,z,w;
00309 BOOL selected;
00310 char pad[4];
00311 } tvector4;
00312
00313 static long RenderReadNurbs(long ObjectID, long clen){
00314 DWORD dwRead;
00315 BOOL readit=TRUE;
00316 long i,j,k,N;
00317 nurbs *n,*Np;
00318 vector4 *p;
00319 tvector4 P;
00320 tDOUBLE tD;
00321
00322
00323
00324
00325
00326
00327
00328
00329 ReadFile(fp,&N,sizeof(long),&dwRead,NULL);
00330 if(N == 0)return -1;
00331 if((Np=(nurbs *)X__Malloc(N*sizeof(nurbs))) == NULL)return -1;
00332 for(k=0;k<N;k++){
00333 n=(Np+k);
00334 ReadFile(fp,&(n->properties),sizeof(NurbsProperties),&dwRead,NULL);
00335 ReadFile(fp,&(n->numU),sizeof(long),&dwRead,NULL);
00336 ReadFile(fp,&(n->numV),sizeof(long),&dwRead,NULL);
00337 ReadFile(fp,&(n->orderU),sizeof(long),&dwRead,NULL);
00338 ReadFile(fp,&(n->orderV),sizeof(long),&dwRead,NULL);
00339 AllocNurbs(n,NULL,NULL);
00340 for(i=0;i<n->numU + n->orderU; i++){
00341 ReadFile(fp,&tD,sizeof(tDOUBLE),&dwRead,NULL);
00342 n->kvU[i]=(double)tD;
00343 }
00344 for(i=0;i<n->numV + n->orderV; i++){
00345 ReadFile(fp,&tD,sizeof(tDOUBLE),&dwRead,NULL);
00346 n->kvV[i]=(double)tD;
00347 }
00348 for(i=0;i<n->numV; i++)
00349 for(j=0;j<n->numU; j++){
00350 ReadFile(fp,&P,sizeof(tvector4),&dwRead,NULL);
00351 p=&(n->points[i][j]);
00352 p->x=(double)P.x;
00353 p->y=(double)P.y;
00354 p->z=(double)P.z;
00355 p->w=(double)P.w;
00356 }
00357 }
00358 if(readit){
00359 Object[ObjectID].Nbase=Np;
00360 Object[ObjectID].NoNurbs=N;
00361 }
00362 return 0;
00363 }
00364
00365 static void CompleteImageMapLoading(long ObjectID, char *objectfilename){
00366
00367
00368 int i,n,l,m;
00369 imap *Map;
00370 if((n=Object[ObjectID].NoMaps) > 0 &&
00371 (Map=Object[ObjectID].Mbase) != NULL){
00372
00373 for(i=0;i<n;i++,Map++){
00374
00375 if(SetupImageMap(Map,objectfilename) != 1){
00376
00377 Render_Message(28,0,NULL);
00378 if((m=Object[ObjectID].NoFaces) > 0)for(l=0;l<m;l++){
00379 if(Object[ObjectID].Fbase[l].ffmap >= 0)
00380 if(Object[ObjectID].Fbase[l].ffmap == i)
00381 Object[ObjectID].Fbase[l].ffmap = -1;
00382 }
00383 }
00384 }
00385 }
00386 }
00387
00388 #define temp_image_name "OFX_R_$$"
00389
00390 static void LoadEmbededImageMaps(long ObjectID, long clen, char *objectfilename){
00391 HANDLE fq;
00392 char *buffer;
00393 char name[256],tempfile[256];
00394 long i,j,n,l,m,v,in_use,f_size;
00395 int id;
00396 DWORD dwRead,dwSize,dwWrite;
00397 imap *Map;
00398 R_getl(&n); if(n != Object[ObjectID].NoMaps){
00399 MessageBox(NULL,"Map reading error",NULL,MB_OK);
00400 R_getchunk(clen-4);
00401 return;
00402 }
00403
00404 if((n=Object[ObjectID].NoMaps) > 0 &&
00405 (Map=Object[ObjectID].Mbase) != NULL){
00406 for(i=0;i<n;i++,Map++){
00407 for(j=0;j<4;j++){
00408 R_getl(&v);
00409 R_getl(&in_use);
00410
00411 if(!in_use)continue;
00412 R_getl(&l);
00413 R_getl(&f_size);
00414 ReadFile(fp,name,l+1,&dwRead,NULL);
00415
00416 if((buffer=(unsigned char*)X__Malloc(f_size)) == NULL){
00417 R_getchunk(f_size);
00418 continue;
00419 }
00420 ReadFile(fp,buffer,f_size,&dwRead,NULL);
00421 id=IdentifyImageFileType(name);
00422 if(id < 0){
00423 MessageBox(NULL,"Bad Type",NULL,MB_OK);
00424 }
00425 if(!CheckSingleRenderImageMap(Map,name,objectfilename,tempfile,j)){
00426 if(id < 0){
00427
00428
00429 goto FREEPOINT;
00430 }
00431 sprintf(tempfile,"%s%s%s",TempPath,temp_image_name,image_file_extensions[id]);
00432
00433
00434 fq=CreateFile(tempfile,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,
00435 FILE_ATTRIBUTE_NORMAL,(HANDLE)NULL);
00436 if(fq == INVALID_HANDLE_VALUE){
00437 MessageBox(NULL,tempfile,"Bad Handle",MB_OK);
00438 }
00439 else{
00440 dwSize=f_size;
00441 if(WriteFile(fq,buffer,dwSize,&dwWrite,NULL) != 0 && dwWrite == dwSize){
00442 CloseHandle(fq);
00443 LoadSingleRenderImageMap(Map,name,objectfilename,tempfile,j);
00444 remove(tempfile);
00445 }
00446 else CloseHandle(fq);
00447 }
00448 }
00449 FREEPOINT: X__Free(buffer);
00450 }
00451 }
00452 }
00453 }
00454
00455 static short R_ReadImaps(long ObjectID, long clen, long frame, char *objectfilename,
00456 char *str, BOOL new_type){
00457 unsigned char *buffer=NULL,*b;
00458 imap *temp_map,*Map;
00459 unsigned char t_colour[3];
00460 char brushmaptype,moziac,p,r,q,t;
00461 char fsurf[256],frefl[256],fbump[256],ftran[256],tempstr[256];
00462 long i,j,k,l,m,brushangle;
00463 long m_p,ff_p,fd_p,lf_p,
00464 m_r,ff_r,fd_r,lf_r,
00465 m_b,ff_b,fd_b,lf_b,
00466 m_t,ff_t,fd_t,lf_t;
00467 short s;
00468 buffer=(unsigned char *)X__Malloc(clen);
00469 if(buffer == NULL)return -1;
00470 ReadFile(fp,buffer,clen,&dwRead,NULL);
00471 b=buffer;
00472 j=GetLongFromBuffer(b); b+= 4;
00473 if(j > 0){
00474 temp_map = (imap *)X__Malloc(j*sizeof(imap));
00475 if(temp_map == NULL){
00476 Render_Message(13,0,NULL);
00477 X__Free(buffer);
00478 return -1;
00479 }
00480 memset(temp_map,0,j*sizeof(imap));
00481 Object[ObjectID].Mbase=temp_map;
00482 Object[ObjectID].NoMaps=j;
00483 for(i=0;i<j;i++){
00484 Map=(temp_map+(long)i);
00485 Map->bLoadedS=FALSE; Map->bLoadedR=FALSE;
00486 Map->bLoadedB=FALSE; Map->bLoadedT=FALSE;
00487 Map->bAnimS=Map->bAnimR=Map->bAnimB=Map->bAnimT=FALSE;
00488 Map->map = PLANE;
00489 Map->angle = 1.0;
00490 Map->moziac = NO;
00491 Map->p24R = Map->p24G = Map->p24B = NULL;
00492 Map->p24Rrefl = Map->p24Grefl = Map->p24Brefl = NULL;
00493 Map->p24Rbump = Map->p24Gbump = Map->p24Bbump = NULL;
00494 Map->p24Rtran = Map->p24Gtran = Map->p24Btran = NULL;
00495 Map->p[0]=(double)GetLongFromBuffer(b); b+= 4;
00496 Map->p[1]=(double)GetLongFromBuffer(b); b+= 4;
00497 Map->p[2]=(double)GetLongFromBuffer(b); b+= 4;
00498 VECCOPY(Map->p,Map->pin)
00499 Map->x[0]=(double)GetLongFromBuffer(b); b+= 4;
00500 Map->x[1]=(double)GetLongFromBuffer(b); b+= 4;
00501 Map->x[2]=(double)GetLongFromBuffer(b); b+= 4;
00502 VECCOPY(Map->x,Map->xin)
00503 Map->y[0]=(double)GetLongFromBuffer(b); b+= 4;
00504 Map->y[1]=(double)GetLongFromBuffer(b); b+= 4;
00505 Map->y[2]=(double)GetLongFromBuffer(b); b+= 4;
00506 VECCOPY(Map->y,Map->yin)
00507 m_p =GetLongFromBuffer(b); b+= 4; b+= 12;
00508 m_r =GetLongFromBuffer(b); b+= 4; b+= 12;
00509 m_b =GetLongFromBuffer(b); b+= 4; b+= 12;
00510 m_t =GetLongFromBuffer(b); b+= 4; b+= 12;
00511 l=GetLongFromBuffer(b); b+= 4;
00512 l=GetLongFromBuffer(b); b+= 4; brushmaptype=(char)l;
00513 brushangle=GetLongFromBuffer(b); b+= 4;
00514 for(k=0;k<4;k++){
00515 m=GetLongFromBuffer(b); b+= 4;
00516 }
00517 memcpy(tempstr,b,32); b+= 32;
00518 p = *b++;
00519 r = *b++;
00520 q = *b++;
00521 t = *b++;
00522 Map->kt = *b++;
00523 Map->pp=GetShortFromBuffer(b); b+= 2;
00524 Map->rp=GetShortFromBuffer(b); b+= 2;
00525 Map->bp=GetShortFromBuffer(b); b+= 2;
00526 b+=2;
00527 if(t > 0)Map->tp=255; else Map->tp=0;
00528 memcpy(t_colour,b,3); b+=3;
00529 memcpy(t_colour,b,3); b+=3;
00530 memcpy(t_colour,b,3); b+=3;
00531 memcpy(Map->kc,b,3); b+=3;
00532 memset(fsurf,0,256); memcpy(fsurf,b,250); b+=256;
00533 if((m=strlen(fsurf)) == 0 || m > 248)p=0;
00534 memset(frefl,0,256); memcpy(frefl,b,250); b+=256;
00535 if((m=strlen(frefl)) == 0 || m > 248)r=0;
00536 memset(fbump,0,256); memcpy(fbump,b,250); b+=256;
00537 if((m=strlen(fbump)) == 0 || m > 248)q=0;
00538 memset(ftran,0,256); memcpy(ftran,b,250); b+=256;
00539 if((m=strlen(ftran)) == 0 || m > 248)t=0;
00540 if(new_type){
00541 b+= 4;
00542 Map->bDecal=(BOOL)GetLongFromBuffer(b); b+= 4;
00543 Map->bShaded=(BOOL)GetLongFromBuffer(b); b+= 4;
00544 Map->bTiled=(BOOL)GetLongFromBuffer(b); b+= 4;
00545 }
00546 else{
00547 Map->bShaded=TRUE;
00548 Map->bTiled=TRUE;
00549 Map->bDecal=FALSE;
00550 }
00551 moziac=NO;
00552 if(brushmaptype == PLANE_MOZIAC) { brushmaptype = PLANE; moziac=YES;}
00553 if(brushmaptype == CYLINDER_MOZIAC){ brushmaptype = CYLINDER; moziac=YES;}
00554 if(p && m_p == ANIMBRUSH)Map->bAnimS=TRUE;
00555 if(r && m_r == ANIMBRUSH)Map->bAnimR=TRUE;
00556 if(q && m_b == ANIMBRUSH)Map->bAnimB=TRUE;
00557 if(t && m_t == ANIMBRUSH)Map->bAnimT=TRUE;
00558 if(p) strcpy(Map->filename,fsurf); else Map->pp = -1;
00559 if(r) strcpy(Map->frefl,frefl); else Map->rp = -1;
00560 if(q) strcpy(Map->fbump,fbump); else Map->bp = -1;
00561 if(t) strcpy(Map->ftran,ftran); else Map->tp = -1;
00562
00563
00564
00565
00566 Map->map=(short)brushmaptype;
00567 Map->angle=360.0/(double)brushangle;
00568 Map->moziac=moziac;
00569 }
00570 }
00571 X__Free(buffer);
00572 return 0;
00573 }
00574
00575 static unsigned char *ReadShaderFromBuffer(long id, matl *Mat, unsigned char *b){
00576 char tempname[256],tempparam[512];
00577 long version,active,in_use,ln,lp;
00578 version=GetLongFromBuffer(b); b+= 4;
00579 active =GetLongFromBuffer(b); b+= 4;
00580 in_use =GetLongFromBuffer(b); b+= 4;
00581
00582 Mat->shaderID[id] = -1;
00583 if(in_use){
00584 ln=GetLongFromBuffer(b); b+= 4;
00585 lp=GetLongFromBuffer(b); b+= 4;
00586 memcpy(tempname,b,ln+1); b += ln+1;
00587 memcpy(tempparam,b,lp+1); b += lp+1;
00588 if(active && LoadExternalTexture(tempname,tempparam) == OK){
00589 Mat->shaderID[id]=Nshader-1;
00590
00591
00592 }
00593
00594 }
00595 return b;
00596 }
00597
00598 static short R_ReadMaterial(long id, long ObjectID, long clen){
00599 long i,j,v,l,n;
00600 unsigned char *buffer=NULL,*b;
00601 matl *temp_mat,*Mat;
00602 buffer=(unsigned char *)X__Malloc(clen);
00603 if(buffer == NULL)return -1;
00604 ReadFile(fp,buffer,clen,&dwRead,NULL);
00605 b=buffer;
00606 n=GetLongFromBuffer(b); b+= 4;
00607
00608 if(n > 0){
00609
00610 temp_mat = (matl *)X__Malloc(n*sizeof(matl));
00611 if(temp_mat == NULL){
00612 Render_Message(13,0,NULL);
00613 X__Free(buffer);
00614 return -1;
00615 }
00616 Object[ObjectID].Tbase=temp_mat;
00617 Object[ObjectID].NoMats=n;
00618 for(i=0;i<n;i++){
00619 Mat=(temp_mat+(long)i);
00620 v=GetLongFromBuffer(b); b+= 4;
00621
00622 b+=32;
00623 memcpy(Mat->color,b,3); b+= 3;
00624 memcpy(Mat->texco,b,3); b+= 3;
00625 b += 5*3;
00626 l=GetLongFromBuffer(b); b+= 4; Mat->gloss=min(15,l/255);
00627 l=GetLongFromBuffer(b); b+= 4; Mat->refl=l;
00628 l=GetLongFromBuffer(b); b+= 4; Mat->transp=l;
00629 l=GetLongFromBuffer(b); b+= 4; if(l < 100)l=1000; Mat->refractive_index=l;
00630 l=GetLongFromBuffer(b); b+= 4; Mat->bInternalShader=(BOOL)l;
00631 l=GetLongFromBuffer(b); b+= 4; Mat->internalShaderID=l;
00632 for(j=0;j<3;j++){l=GetLongFromBuffer(b); b+= 4; Mat->ax.bo[j]=(double)l;}
00633 for(j=0;j<3;j++){l=GetLongFromBuffer(b); b+= 4; Mat->ax.bu[j]=(double)l;}
00634 for(j=0;j<3;j++){l=GetLongFromBuffer(b); b+= 4; Mat->ax.bv[j]=(double)l;}
00635 VECCOPY(Mat->ax.bo,Mat->ax.boin)
00636 VECCOPY(Mat->ax.bu,Mat->ax.buin)
00637 VECCOPY(Mat->ax.bv,Mat->ax.bvin)
00638 for(j=0;j<4;j++)b=ReadShaderFromBuffer(j,Mat,b);
00639 l=GetLongFromBuffer(b); b+= 4; Mat->bSmooth=(BOOL)l;
00640 l=GetLongFromBuffer(b); b+= 4; Mat->bShiny=(BOOL)l;
00641 l=GetLongFromBuffer(b); b+= 4; Mat->bClear=(BOOL)l;
00642 l=GetLongFromBuffer(b); b+= 4; Mat->bGlassEdge=(BOOL)l;
00643 l=GetLongFromBuffer(b); b+= 4; Mat->bUseSurfaceMapping=(BOOL)l;
00644 for(j=0;j<16;j++){l=GetLongFromBuffer(b); b+= 4; Mat->params[j]=(unsigned char)l;}
00645 b += 16*4;
00646
00647
00648
00649
00650 if(id > 1){
00651 memcpy(Mat->other_properties,b,512); b+= 512;
00652 sscanf(Mat->other_properties,"%lf %lf %lf %lf %lf %lf",
00653 &(Mat->mmw_params[0]),&(Mat->mmw_params[1]),&(Mat->mmw_params[2]),
00654 &(Mat->mmw_params[3]),&(Mat->mmw_params[4]),&(Mat->mmw_params[5]));
00655 }
00656 }
00657 }
00658 X__Free(buffer);
00659 return 0;
00660 }
00661
00662 static short R_ReadFaces(long ObjectID, long clen, int version){
00663 long i,sf;
00664 long mm;
00665 unsigned char texture,brush,pad,attrib;
00666 unsigned char *buffer=NULL,*b;
00667 face *f;
00668 if (version == 0)newface=clen/18;
00669 else if(version == 1)newface=clen/24;
00670 else newface=clen/20;
00671 if(newface == 0)return -1;
00672 sf=sizeof(face);
00673 mm=newface*(long)sf;
00674 Object[ObjectID].Fbase=(face *)X__Malloc(mm);
00675 Object[ObjectID].NoFaces=newface;
00676 f=Object[ObjectID].Fbase;
00677 if(f == NULL){Render_Message(9,0,NULL); return -1;}
00678 buffer=(unsigned char *)X__Malloc(clen);
00679 if(buffer == NULL)return -1;
00680 ReadFile(fp,buffer,clen,&dwRead,NULL);
00681 b=buffer;
00682 for(i=0;i<newface;i++){
00683 if(version == 0){
00684 f->V[0]=(UNSIGNED)GetUshortFromBuffer(b); b+= 2;
00685 f->V[1]=(UNSIGNED)GetUshortFromBuffer(b); b+= 2;
00686 f->V[2]=(UNSIGNED)GetUshortFromBuffer(b); b+= 2;
00687 }
00688 else{
00689 f->V[0]=(UNSIGNED)GetLongFromBuffer(b); b+= 4;
00690 f->V[1]=(UNSIGNED)GetLongFromBuffer(b); b+= 4;
00691 f->V[2]=(UNSIGNED)GetLongFromBuffer(b); b+= 4;
00692 }
00693 memcpy(f->color,b,3); b+=3;
00694 if(version == 2){
00695 f->bShiny = FALSE;
00696 f->bSmooth= *b++;
00697 f->ffmat = GetShortFromBuffer(b); b+= 2;
00698 f->ffmap = GetShortFromBuffer(b); b+= 2;
00699 }
00700 else{
00701 *b++; *b++; *b++;
00702 attrib = *b++;
00703 *b++;
00704 f->ffmap = (short)(*b++);
00705 f->ffmat = -1;
00706 if(attrib & 0x80)f->bSmooth=TRUE; else f->bSmooth=FALSE;
00707 if(attrib & 0x20)f->bShiny=TRUE; else f->bShiny=FALSE;
00708 if(!(attrib & 0x40))f->ffmap = -1;
00709 *b++; *b++; *b++;
00710 }
00711 f->bFmc=FALSE;
00712 f->pn[0][0]=0.0; f->pn[0][1]=0.0; f->pn[0][2]=0.0;
00713 f->pn[1][0]=0.0; f->pn[1][1]=0.0; f->pn[1][2]=0.0;
00714 f->pn[2][0]=0.0; f->pn[2][1]=0.0; f->pn[2][2]=0.0;
00715 f->n[0]=0.0; f->n[1]=0.0; f->n[2]=0.0;
00716 f->c=0.0;
00717 f++;
00718 }
00719 X__Free(buffer);
00720 return 0;
00721 }
00722
00723 static short R_ReadVertices(long ObjectID, long clen){
00724 vertex *v;
00725 long i,mm,sv;
00726 unsigned char *buffer=NULL,*b;
00727 newvert=clen/12;
00728 if(newvert == 0)return -1;
00729 sv=sizeof(vertex);
00730 mm=newvert*(long)sv;
00731 if(newvert > 65535L && sizeof(UNSIGNED) < 4){
00732 Render_Message(16,0,NULL);
00733 return -1;
00734 }
00735 Object[ObjectID].Vbase=(vertex *)X__Malloc(mm);
00736 Object[ObjectID].NoVertices=newvert;
00737 v=Object[ObjectID].Vbase;
00738 if(v == NULL){
00739 Render_Message(9,0,NULL);
00740 return -1;
00741 }
00742 buffer=(unsigned char *)X__Malloc(clen);
00743 if(buffer == NULL)return -1;
00744 ReadFile(fp,buffer,clen,&dwRead,NULL);
00745 b=buffer;
00746 for(i=0;i<newvert;i++){
00747 v->p[0]=(double)GetLongFromBuffer(b); b+= 4;
00748 v->p[1]=(double)GetLongFromBuffer(b); b+= 4;
00749 v->p[2]=(double)GetLongFromBuffer(b); b+= 4;
00750 v->x=0; v->y=0;
00751 v->u=0; v->v=0;
00752 v++;
00753 }
00754 X__Free(buffer);
00755 return 0;
00756 }
00757
00758 static short R_ReadVertText(long ObjectID, long clen, BOOL vtx2){
00759 vertex *v;
00760 long i,n,xx,id;
00761 unsigned char *buffer=NULL,*b;
00762 n=clen/12;
00763 i=Object[ObjectID].NoVertices;
00764 if(n == 0)return 0;
00765 if(n > i)return -1;
00766 buffer=(unsigned char *)X__Malloc(clen);
00767 if(buffer == NULL)return -1;
00768 ReadFile(fp,buffer,clen,&dwRead,NULL);
00769 b=buffer;
00770 v=Object[ObjectID].Vbase;
00771 for(i=0;i<n;i++){
00772 id=GetLongFromBuffer(b); b+= 4;
00773 if(vtx2)id=i;
00774 xx=GetLongFromBuffer(b); b+= 4; v[id].u=(double)xx*0.000001;
00775 xx=GetLongFromBuffer(b); b+= 4; v[id].v=(1.0 - (double)xx*0.000001);
00776 }
00777 X__Free(buffer);
00778 return 0;
00779 }
00780
00781 static short R_ReadFaceMapping(long ObjectID, long clen){
00782 long i,j,nn,ix,iy;
00783 face *f;
00784 unsigned char *buffer=NULL,*b;
00785 nn=clen/28;
00786 i=Object[ObjectID].NoFaces;
00787 if(nn > i)return -1;
00788 if(nn == 0)return 0;
00789 buffer=(unsigned char *)X__Malloc(clen);
00790 if(buffer == NULL)return -1;
00791 ReadFile(fp,buffer,clen,&dwRead,NULL);
00792 b=buffer;
00793 f=Object[ObjectID].Fbase;
00794 for(i=0;i<nn;i++){
00795 f->bFmc=(BOOL)GetLongFromBuffer(b); b+= 4;
00796 for(j=0;j<3;j++){
00797 ix=GetLongFromBuffer(b); b+= 4;
00798 iy=GetLongFromBuffer(b); b+= 4;
00799 f->uu[j]=(double)ix*0.000001;
00800 f->vv[j]=(1.0 - (double)iy*0.000001);
00801 f->ww[j]=0.5;
00802
00803 }
00804 f++;
00805 }
00806 X__Free(buffer);
00807 return 0;
00808 }
00809
00810
00811 long FindNumberVertices(char *ofile, long *nvs){
00812 long CHUNKsize,FORMsize;
00813 char FileName[256];
00814 strcpy(FileName,ofile);
00815 *nvs = -1;
00816 if((fp=GetRenderRelativeHandle((char *)strlwr(FileName),NULL,NULL))
00817 == INVALID_HANDLE_VALUE){
00818 return 0;
00819 }
00820 ReadFile(fp,str,4,&dwRead,NULL);
00821 if (dwRead != 4 || strcmp(str,"FORM") != 0)goto end;
00822 ReadFile(fp,&FORMsize,4,&dwRead,NULL);
00823 ReadFile(fp,str,4,&dwRead,NULL);
00824 if (dwRead != 4 || (strcmp(str,"OFXM") != 0 && strcmp(str,"AAPO") != 0))goto end;
00825 loop:
00826 if(!ReadFile(fp,str,4,&dwRead,NULL))goto end;
00827 if(dwRead != 4 )goto end;
00828 if(R_getl(&CHUNKsize) != 1)goto end;
00829 if(strcmp(str,"VERT") == 0){
00830 *nvs=CHUNKsize/12;
00831 goto end;
00832 }
00833 else R_getchunk(CHUNKsize);
00834 goto loop;
00835 end:
00836 CloseHandle(fp);
00837 return 1;
00838 }
00839
00840 long R_LoadObject(long ObjectID, char *FileName, long frame, short robo,
00841 double robo_ratio,
00842 char *robo_file1, char *robo_file2){
00843 long CHUNKsize,FORMsize,l;
00844 long nsk,*Skids=NULL;
00845 skel *Skeleton=NULL;
00846
00847 if((fp=GetRenderRelativeHandle((char *)strlwr(FileName),NULL,NULL))
00848 == INVALID_HANDLE_VALUE){
00849 Render_Message(30,1,FileName);
00850 return 0;
00851 }
00852 newface=0; newvert=0; nsk=0;
00853 ReadFile(fp,str,4,&dwRead,NULL);
00854
00855 if(strcmp(str,"FORM") != 0){
00856 Render_Message(21,1,NULL);
00857 return 0;
00858 }
00859 ReadFile(fp,&FORMsize,sizeof(long),&dwRead,NULL);
00860 ReadFile(fp,str,4,&dwRead,NULL);
00861
00862
00863 if(dwRead != 4 || (strcmp(str,"OFXM") != 0 && strcmp(str,"AAPO") != 0)){
00864 Render_Message(22,1,NULL);
00865 return 0;
00866 }
00867 Object[ObjectID].Centre[0]=0;
00868 Object[ObjectID].Centre[1]=0;
00869 Object[ObjectID].Centre[2]=0;
00870
00871 Object[ObjectID].Abase.bo[0]=0;
00872 Object[ObjectID].Abase.bo[1]=0;
00873 Object[ObjectID].Abase.bo[2]=0;
00874 Object[ObjectID].Abase.bu[0]=UNIT;
00875 Object[ObjectID].Abase.bu[1]=0;
00876 Object[ObjectID].Abase.bu[2]=0;
00877 Object[ObjectID].Abase.bv[0]=0;
00878 Object[ObjectID].Abase.bv[1]=UNIT;
00879 Object[ObjectID].Abase.bv[2]=0;
00880 loop:
00881 if(!ReadFile(fp,str,4,&dwRead,NULL))goto end;
00882
00883 if(dwRead != 4)goto end;
00884 if (R_getl(&CHUNKsize) != 1)goto end;
00885 if (strcmp(str,"VERT") == 0){if(R_ReadVertices(ObjectID,CHUNKsize) < 0)return -1;}
00886 else if(strcmp(str,"VTEX") == 0){if(R_ReadVertText(ObjectID,CHUNKsize,FALSE) < 0)return -1;}
00887 else if(strcmp(str,"VTX2") == 0){if(R_ReadVertText(ObjectID,CHUNKsize,TRUE) < 0)return -1;}
00888 else if(strcmp(str,"SFCE") == 0){if(R_ReadFaces(ObjectID,CHUNKsize,0) < 0)return -1;}
00889 else if(strcmp(str,"LFCE") == 0){if(R_ReadFaces(ObjectID,CHUNKsize,1) < 0)return -1;}
00890 else if(strcmp(str,"NFCE") == 0){if(R_ReadFaces(ObjectID,CHUNKsize,2) < 0)return -1;}
00891 else if(strcmp(str,"FTEX") == 0){if(R_ReadFaceMapping(ObjectID,CHUNKsize) < 0)return -1;}
00892 else if(strcmp(str,"AXIS") == 0){if(R_ReadAxis(ObjectID,CHUNKsize) < 0)return -1;}
00893 else if(strcmp(str,"IMAP") == 0)R_ReadImaps(ObjectID,CHUNKsize,frame,FileName,str,FALSE);
00894 else if(strcmp(str,"IMA2") == 0)R_ReadImaps(ObjectID,CHUNKsize,frame,FileName,str,TRUE);
00895 else if(strcmp(str,"EMAP") == 0)LoadEmbededImageMaps(ObjectID,CHUNKsize,FileName);
00896 else if(strcmp(str,"MTL1") == 0)R_ReadMaterial(1,ObjectID,CHUNKsize);
00897 else if(strcmp(str,"MTL2") == 0)R_ReadMaterial(2,ObjectID,CHUNKsize);
00898 else if(strcmp(str,"SK04") == 0 && robo == YES)Skids=RenderReadSkeleton(CHUNKsize,4,&Skeleton,&nsk);
00899 else if(strcmp(str,"SK03") == 0 && robo == YES)Skids=RenderReadSkeleton(CHUNKsize,3,&Skeleton,&nsk);
00900 else if(strcmp(str,"SK02") == 0 && robo == YES)Skids=RenderReadSkeleton(CHUNKsize,2,&Skeleton,&nsk);
00901 else if(strcmp(str,"SK01") == 0 && robo == YES)Skids=RenderReadSkeleton(CHUNKsize,1,&Skeleton,&nsk);
00902 else if(strcmp(str,"SKEL") == 0 && robo == YES)Skids=RenderReadSkeleton(CHUNKsize,0,&Skeleton,&nsk);
00903 else if(strcmp(str,"NURB") == 0){
00904 if(RenderReadNurbs(ObjectID,CHUNKsize) < 0)return -1;
00905 MeshNurbsSurfaces(ObjectID);
00906 }
00907 else if(strcmp(str,"UNIT") == 0){
00908 long dummy;
00909 char dummys[16];
00910 R_getl(&dummy); ruler_length=(double)dummy;
00911 ReadFile(fp,dummys,8,&dwRead,NULL);
00912 R_getl(&dummy); R_getl(&dummy); R_getl(&dummy);
00913 R_getl(&dummy); R_getl(&dummy); R_getl(&dummy);
00914 }
00916 else R_getchunk(CHUNKsize);
00917 goto loop;
00918 end:
00919 CloseHandle(fp);
00920 CompleteImageMapLoading(ObjectID,FileName);
00921 Object[ObjectID].Skeleton=Skeleton;
00922 Object[ObjectID].Skids=Skids;
00923 Object[ObjectID].NoSkeleton=nsk;
00924 return 1;
00925 }
00926
00927 void R_getchunk(long clen){
00928 SetFilePointer(fp,clen,NULL,FILE_CURRENT);
00929 }
00930
00931 static short R_ReadAxis(long ObjectID, long clen){
00932 long j;
00933 R_getl(&j); Object[ObjectID].Centre[0]=j;
00934 R_getl(&j); Object[ObjectID].Centre[1]=j;
00935 R_getl(&j); Object[ObjectID].Centre[2]=j;
00936 R_getl(&j); Object[ObjectID].Abase.bo[0]=j;
00937 R_getl(&j); Object[ObjectID].Abase.bo[1]=j;
00938 R_getl(&j); Object[ObjectID].Abase.bo[2]=j;
00939 R_getl(&j); Object[ObjectID].Abase.bu[0]=j;
00940 R_getl(&j); Object[ObjectID].Abase.bu[1]=j;
00941 R_getl(&j); Object[ObjectID].Abase.bu[2]=j;
00942 R_getl(&j); Object[ObjectID].Abase.bv[0]=j;
00943 R_getl(&j); Object[ObjectID].Abase.bv[1]=j;
00944 R_getl(&j); Object[ObjectID].Abase.bv[2]=j;
00945 VECCOPY(Object[ObjectID].Abase.bo,Object[ObjectID].Abase.boin)
00946 VECCOPY(Object[ObjectID].Abase.bu,Object[ObjectID].Abase.buin)
00947 VECCOPY(Object[ObjectID].Abase.bv,Object[ObjectID].Abase.bvin)
00948 return 0;
00949 }
00950
00952
00953 #define EPSILON 1.0e-6
00954
00955 void InvertRotationMatrix(double T[4][4], double t[4][4]){
00956 int i,j;
00957 double a[3][3];
00958 double det;
00959 R_null_transform(t);
00960 for(i=0;i<3;i++)for(j=0;j<3;j++)a[i][j]=T[i][j];
00961 det=a[0][0]*(a[1][1]*a[2][2] - a[2][1]*a[1][2])
00962 -a[0][1]*(a[1][0]*a[2][2] - a[2][0]*a[1][2])
00963 +a[0][2]*(a[1][0]*a[2][1] - a[2][0]*a[1][1]);
00964 if(fabs(det) < 1.e-10)return;
00965 det = 1.0/det;
00966 t[0][0] = +(a[1][1]*a[2][2] - a[2][1]*a[1][2])*det;
00967 t[1][0] = -(a[1][0]*a[2][2] - a[2][0]*a[1][2])*det;
00968 t[2][0] = +(a[1][0]*a[2][1] - a[2][0]*a[1][1])*det;
00969 t[0][1] = -(a[0][1]*a[2][2] - a[2][1]*a[0][2])*det;
00970 t[1][1] = +(a[0][0]*a[2][2] - a[2][0]*a[0][2])*det;
00971 t[2][1] = -(a[0][0]*a[2][1] - a[2][0]*a[0][1])*det;
00972 t[0][2] = +(a[0][1]*a[1][2] - a[1][1]*a[0][2])*det;
00973 t[1][2] = -(a[0][0]*a[1][2] - a[1][0]*a[0][2])*det;
00974 t[2][2] = +(a[0][0]*a[1][1] - a[1][0]*a[0][1])*det;
00975 }
00976
00977 #ifdef _SUNSTYLE
00978 #else
00979 static void MatrixToQuaternion(double m[4][4], quaternion q){
00980 #endif
00981 double w4,x2;
00982 q[0]=0.25*(1.0+m[0][0]+m[1][1]+m[2][2]);
00983 if(q[0] > EPSILON){
00984 q[0]=sqrt(q[0]);
00985 w4=1.0/(4.0*q[0]);
00986 q[1]=(m[1][2]-m[2][1])*w4;
00987 q[2]=(m[2][0]-m[0][2])*w4;
00988 q[3]=(m[0][1]-m[1][0])*w4;
00989 }
00990 else{
00991 q[0]=0.0;
00992 q[1]= -0.5*(m[1][1]+m[2][2]);
00993 if(q[1] > EPSILON){
00994 q[1]=sqrt(q[1]);
00995 x2=1.0/(2.0*q[1]);
00996 q[2]=m[0][1]*x2;
00997 q[3]=m[0][2]*x2;
00998 }
00999 else{
01000 q[1]=0.0;
01001 q[2]=0.5*(1.0-m[2][2]);
01002 if(q[2] > EPSILON){
01003 q[2]=sqrt(q[2]);
01004 q[3]=m[1][2]/(2.0*q[2]);
01005 }
01006 else{
01007 q[2]=0.0;
01008 q[3]=1.0;
01009 }
01010 }
01011 }
01012 return;
01013 }
01014
01015 static void QuaternionToMatrix(quaternion q, double m[4][4]){
01016 double w,x,y,z,x2,y2,z2;
01017 w=q[0]; x=q[1]; y=q[2]; z=q[3]; x2=x*x; y2=y*y; z2=z*z;
01018 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;
01019 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;
01020 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;
01021 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;
01022 return;
01023 }
01024
01025 static void Slerp(double mr, quaternion q1, quaternion q2, quaternion q){
01026 double sum,beta1,beta2,theta;
01027 sum=q1[0]*q2[0]+q1[1]*q2[1]+q1[2]*q2[2]+q1[3]*q2[3];
01028 if(sum < 0.0)sum=0.0;
01029 if(sum > 1.0)sum=1.0;
01030 theta=acos(sum);
01031 if(theta < EPSILON){ beta1=1.0-mr; beta2=mr;}
01032 else{
01033 beta1=sin((1.0-mr)*theta)/sin(theta);
01034 beta2=sin(mr*theta)/sin(theta);
01035 }
01036 q[0]=beta1*q1[0]+beta2*q2[0];
01037 q[1]=beta1*q1[1]+beta2*q2[1];
01038 q[2]=beta1*q1[2]+beta2*q2[2];
01039 q[3]=beta1*q1[3]+beta2*q2[3];
01040 }
01041
01042 static int nSkeleton;
01043 static skel *Skeleton;
01044
01045 static void ApplyTransformToChildren(int id, double T[4][4]){
01046 static double x,y,z;
01047 static double sst[4][4],t1[4][4],t2[4][4];
01048 int i;
01049 for(i=1;i<nSkeleton;i++){
01050 if(Skeleton[i].id == id){
01051 R_tram(t1,-(Skeleton+id)->p[0],-(Skeleton+id)->p[1],-(Skeleton+id)->p[2]);
01052 R_m4by4((Skeleton+i)->Q,t1,t2);
01053 R_tram(t1, (Skeleton+id)->p[0], (Skeleton+id)->p[1], (Skeleton+id)->p[2]);
01054 R_m4by4(t1,t2,sst);
01055 R_m4by4(T,sst,Skeleton[i].T);
01056 ApplyTransformToChildren(i,Skeleton[i].T);
01057 }
01058 }
01059 return;
01060 }
01061
01062 static void InterpolateRobot(double mr, long n, skel *sk1, skel *sk2){
01063 int i;
01064 quaternion q,q1,q2;
01065 nSkeleton=n;
01066 Skeleton=sk1;
01067 if(mr < 1.0){
01068
01069
01070 quaternion Qi={1.0,0.0,0.0,0.0};
01071 double Q[4][4],Ri[4][4];
01072 for(i=0;i<nSkeleton;i++){
01073 InvertRotationMatrix((sk2+i)->R,Ri);
01074 R_m4by4((Skeleton+i)->R,Ri,Q);
01075 MatrixToQuaternion(Q,q2);
01076 Slerp(mr,Qi,q2,q);
01077 QuaternionToMatrix(q,Q);
01078 R_m4by4(Q,(sk2+i)->R,(Skeleton+i)->Q);
01079 }
01080 }
01081 else{
01082 for(i=0;i<nSkeleton;i++)R_c4to4((Skeleton+i)->R,(Skeleton+i)->Q);
01083 }
01084 ApplyTransformToChildren(0,Skeleton[0].T);
01085 return;
01086 }
01087
01088 void RenderTransformToRobot(long O,
01089 long *Skid, skel *Skel, double mr,
01090 char *robo_f1, char *robo_f2){
01091 long i,j,n1=0,n2=0;
01092 FILE *frobot;
01093 skel *sk1=NULL,*sk2=NULL;
01094 vertex *v;
01095 double x1,y1,z1;
01096 if((frobot = fopen(robo_f1,"r")) != NULL){
01097 fscanf(frobot,"%ld\n",&n1);
01098 if(n1 > 0){
01099 if((sk1=Skel) == NULL)goto FINISHED;
01100 for(i=0;i<n1;i++){
01101 R_null_transform(sk1->R);
01102 R_null_transform(sk1->Q);
01103 R_null_transform(sk1->T);
01104 for(j=0;j<4;j++)fscanf(frobot,GET_MATX,
01105 &sk1[i].R[j][0], &sk1[i].R[j][1],
01106 &sk1[i].R[j][2], &sk1[i].R[j][3]);
01107 }
01108 }
01109 fclose(frobot);
01110 }
01111 if((frobot = fopen(robo_f2,"r")) != NULL){
01112 fscanf(frobot,"%ld\n",&n2);
01113 if(n2 > 0){
01114 if((sk2 = (skel *)X__Malloc(n2*(long)sizeof(skel))) == NULL)
01115 goto FINISHED;
01116 for(i=0;i<n2;i++){
01117 R_null_transform(sk2->R);
01118 R_null_transform(sk2->Q);
01119 R_null_transform(sk2->T);
01120 for(j=0;j<4;j++)fscanf(frobot,GET_MATX,
01121 &sk2[i].R[j][0], &sk2[i].R[j][1],
01122 &sk2[i].R[j][2], &sk2[i].R[j][3]);
01123 }
01124 }
01125 fclose(frobot);
01126 }
01127 if(n1 != n2 || n1 == 0 || n2 == 0)goto FINISHED;
01128 InterpolateRobot(mr,n1,sk1,sk2);
01129 v=Object[O].Vbase;
01130 for(i=0;i<Object[O].NoVertices;i++){
01131 R_m4by1(sk1[Skid[i]].T,v[i].p[0],v[i].p[1],v[i].p[2],&x1,&y1,&z1);
01132 v[i].p[0]=x1;
01133 v[i].p[1]=y1;
01134 v[i].p[2]=z1;
01135 }
01136 FINISHED:
01137 if(sk2 != NULL)X__Free(sk2);
01138 return;
01139 }
01140
01141 static double GetBoneRelativeDistance(vector v, vector s, vector sp, vector d, double len, double *l, vector r){
01142 vector dp,q;
01143 double ll;
01144 VECSUB((double)v,(double)s,dp)
01145 ll=DOT(dp,d);
01146 if(ll < 0){
01147 *l=0.0;
01148
01149 VECSUB((double)v,(double)s,r)
01150 }
01151 else if(ll > len){
01152 *l=1.0;
01153
01154 VECSUB((double)v,(double)sp,r)
01155 }
01156 else{
01157 *l=ll/len;
01158 VECSUM((double)s,ll*d,q)
01159 VECSUB((double)v,q,r)
01160 }
01161 return sqrt(DOT(r,r));
01162 }
01163
01164 static void ApplyParentDeform(skel *s, skel *sp, vector p, vertex *v){
01165 double dist,lab,h,h1;
01166 vector d,r;
01167 VECSUB(sp->p,s->p,d)
01168 VECSCALE(1.0/s->bLength,d,d);
01169 dist=GetBoneRelativeDistance(v->p,s->p,sp->p,d,s->bLength,&lab,r);
01170 h=1.0-lab;
01171 if(h < 0.0 || h > 1.0){
01172 if(dist > s->wrange)h=0.0;
01173 else h=(dist/s->wrange)*s->weight;
01174 }
01175 else h=h*h*s->weight;
01176 h1=1.0-h;
01177 VECSUM(h*p,h1*(v->p),v->pskp)
01178 v->bskp=TRUE;
01179 }
01180 static void ApplyChildDeform(skel *s, skel *sp, vector p, vertex *v){
01181 double dist,lab,h,h1;
01182 vector d,r;
01183 VECSUB(sp->p,s->p,d)
01184 VECSCALE(1.0/s->bLength,d,d);
01185 dist=GetBoneRelativeDistance(v->p,s->p,sp->p,d,s->bLength,&lab,r);
01186 h=lab;
01187 if(h < 0.0 || h > 1.0){
01188 if(dist > s->wrange*ruler_length)h=0.0;
01189 else h=(dist/(s->wrange*ruler_length))*s->weight;
01190 }
01191 else h=h*h*s->weight;
01192 h1=1.0-h;
01193 VECSUM(h*p,h1*(v->p),v->pskc)
01194 v->bskc=TRUE;
01195 }
01196
01197
01198 void RenderRubberBones(long O, int nSk, long *Skid, skel *Skeleton){
01199
01200
01201 int i,j,pid,ppid;
01202 double x,y,z;
01203 double Q[4][4],Qi[4][4],t1[4][4],t2[4][4];
01204 vector p;
01205 vertex *v;
01206
01207 for(i=1;i<nSk;i++){
01208 VECSUB((Skeleton+((Skeleton+i)->id))->p,(Skeleton+i)->p,p)
01209 (Skeleton+i)->bLength=sqrt(DOT(p,p));
01210 R_m4by1((Skeleton+i)->T,(Skeleton+i)->p[0],(Skeleton+i)->p[1],(Skeleton+i)->p[2],&x,&y,&z);
01211 (Skeleton+i)->p[0]=x; (Skeleton+i)->p[1]=y; (Skeleton+i)->p[2]=z;
01212 Skeleton->weight=min(1.0,Skeleton->weight);
01213 }
01214 v=Object[O].Vbase;
01215 for(j=0;j<Object[O].NoVertices;j++)v[j].bskc=v[j].bskp=FALSE;
01216
01217 for(i=1;i<nSk;i++){
01218 pid=Skeleton[i].id;
01219 R_c4to4(Skeleton[i].Q,Q);
01220 for(j=0;j<3;j++)Q[3][j]=Q[j][3]=0.0; Q[3][3]=1.0;
01221 InvertRotationMatrix(Q,Qi);
01222 R_tram(t1,-(Skeleton+pid)->p[0],-(Skeleton+pid)->p[1],-(Skeleton+pid)->p[2]);
01223 R_m4by4(Q,t1,t2);
01224 R_tram(t1, (Skeleton+pid)->p[0], (Skeleton+pid)->p[1], (Skeleton+pid)->p[2]);
01225 R_m4by4(t1,t2,Q);
01226 R_tram(t1,-(Skeleton+pid)->p[0],-(Skeleton+pid)->p[1],-(Skeleton+pid)->p[2]);
01227 R_m4by4(Qi,t1,t2);
01228 R_tram(t1, (Skeleton+pid)->p[0], (Skeleton+pid)->p[1], (Skeleton+pid)->p[2]);
01229 R_m4by4(t1,t2,Qi);
01230
01231
01232
01233 for(j=0;j<Object[O].NoVertices;j++){
01234 if(Skid[j] == pid){
01235 ppid=(Skeleton+pid)->id;
01236 R_m4by1(Q,v[j].p[0],v[j].p[1],v[j].p[2],&p[0],&p[1],&p[2]);
01237 ApplyParentDeform((Skeleton+pid),(Skeleton+ppid),p,(v+j));
01238 }
01239 else if(Skid[j] == i){
01240 R_m4by1(Qi,v[j].p[0],v[j].p[1],v[j].p[2],&p[0],&p[1],&p[2]);
01241 ApplyChildDeform((Skeleton+i),(Skeleton+pid),p,(v+j));
01242 }
01243 }
01244 }
01245
01246 for(i=0;i<Object[O].NoVertices;i++){
01247 if(Skid[i] > 0) {
01248 if(v[i].bskp && v[i].bskc){
01249 v[i].p[0]=0.5*(v[i].pskp[0]+v[i].pskc[0]);
01250 v[i].p[1]=0.5*(v[i].pskp[1]+v[i].pskc[1]);
01251 v[i].p[2]=0.5*(v[i].pskp[2]+v[i].pskc[2]);
01252 }
01253 else if(v[i].bskc)VECCOPY(v[i].pskc,v[i].p)
01254 else if(v[i].bskp)VECCOPY(v[i].pskp,v[i].p)
01255 }
01256 }
01257 for(i=1;i<nSk;i++){
01258 VECCOPY((Skeleton+i)->pcopy,(Skeleton+i)->p)
01259 }
01260 return;
01261 }