2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
5 This file is part of GtkRadiant.
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 void *SafeMalloc(size_t n, char *desc);
49 void AnimCompressInit(int nframes,int nVerts,int CompressedFrameSize)
53 MatHeight=CompressedFrameSize;
54 CFrameSize=CompressedFrameSize;
55 matrix=(float *)SafeMalloc(MatWidth*MatHeight*sizeof(float), "AnimCompressInit");
56 best=(float *)SafeMalloc(MatWidth*MatHeight*sizeof(float), "AnimCompressInit");
57 delta=(float *)SafeMalloc(MatWidth*MatHeight*sizeof(float), "AnimCompressInit");
58 comp=(float *)SafeMalloc(CFrameSize*nFrames*sizeof(float), "AnimCompressInit");
59 tcomp=(float *)SafeMalloc(CFrameSize*nFrames*sizeof(float), "AnimCompressInit");
60 bestcomp=(float *)SafeMalloc(CFrameSize*nFrames*sizeof(float), "AnimCompressInit");
61 base=(float *)SafeMalloc(MatWidth*sizeof(float), "AnimCompressInit");
62 frames=(float *)SafeMalloc(MatWidth*nFrames*sizeof(float), "AnimCompressInit");
65 void AnimSetFrame(int frame,int index,float x,float y,float z)
67 frames[frame*MatWidth+index*3]=x;
68 frames[frame*MatWidth+index*3+1]=y;
69 frames[frame*MatWidth+index*3+2]=z;
79 #define F_RANDOM (((float)rand())/(float)RAND_MAX)
81 extern void DOsvd(float *a,float *res,float *comp,float *values,int nframes,int framesize,int compressedsize);
83 void AnimCompressDoit()
93 for (k=0;k<MatWidth;k++)
95 for (j=0;j<nFrames;j++)
96 for (k=0;k<MatWidth;k++)
97 base[k]+=frames[j*MatWidth+k];
98 tmp=1.0f/(float)nFrames;
99 for (k=0;k<MatWidth;k++)
101 for (j=0;j<nFrames;j++)
102 for (k=0;k<MatWidth;k++)
103 frames[j*MatWidth+k]-=base[k];
105 ans=(float *)SafeMalloc(sizeof(float)*MatWidth, "AnimCompressDoit");
106 rescale=(float *)SafeMalloc(sizeof(float)*CFrameSize, "AnimCompressDoit");
107 DOsvd(frames,best,bestcomp,rescale,nFrames,MatWidth,MatHeight);
109 for (l=0;l<CFrameSize;l++)
111 for (l=0;l<CFrameSize;l++)
112 printf("%3.1f ",100.0f*rescale[l]/avedev);
114 for (j=0;j<nFrames;j++)
116 for (l=0;l<CFrameSize;l++)
118 bestcomp[j*CFrameSize+l]=0.0;
119 for (k=0;k<MatWidth;k++)
120 bestcomp[j*CFrameSize+l]+=best[l*MatWidth+k]*frames[j*MatWidth+k];
126 for (j=0;j<nFrames;j++)
128 for (k=0;k<MatWidth;k++)
131 for (l=0;l<CFrameSize;l++)
132 ans[k]+=best[l*MatWidth+k]*bestcomp[j*CFrameSize+l];
133 ans[k]-=frames[j*MatWidth+k];
134 tmp=(float)fabs(ans[k]);
141 avedev/=(float)numave;
142 printf("%f Max Deviation (inches) %f Ave Dev. (inches)\n",maxdev,avedev);
143 printf("%d bytes original size\n",MatWidth*nFrames);
144 printf("%d bytes of overhead\n",MatWidth*MatHeight);
145 printf("%d bytes/frame * %d frames = %d bytes\n",CFrameSize,nFrames,CFrameSize*nFrames);
146 compression=(float)(MatWidth*MatHeight+CFrameSize*nFrames+MatWidth);
147 compression/=(float)(MatWidth*nFrames);
148 printf("Overall compression = %f %%\n",100.0f-100.0f*compression);
149 compression=(float)(CFrameSize);
150 compression/=(float)(MatWidth);
151 printf("frame size compression = %f %%\n",100.0f-100.0f*compression);
156 void AnimCompressToBytes(float *trans,float *scale,char *mat,char *ccomp,unsigned char *cbase,float *cscale,float *coffset,float *bmin,float *bmax)
175 for (k=0;k<MatWidth;k+=3)
177 if (base[k]>scale[0])
179 if (base[k]<trans[0])
182 if (base[k+1]>scale[1])
184 if (base[k+1]<trans[1])
187 if (base[k+2]>scale[2])
189 if (base[k+2]<trans[2])
199 for (k=0;k<MatWidth;k+=3)
201 t=(base[k]-trans[0])/scale[0];
206 cbase[k]=(unsigned char)t;
208 t=(base[k+1]-trans[1])/scale[1];
213 cbase[k+1]=(unsigned char)t;
215 t=(base[k+2]-trans[2])/scale[2];
220 cbase[k+2]=(unsigned char)t;
222 for (l=0;l<MatHeight;l++)
225 for (k=0;k<MatWidth;k++)
227 if (fabs(best[l*MatWidth+k])>mx)
228 mx=(float)fabs(best[l*MatWidth+k]);
235 for (j=0;j<nFrames;j++)
237 bestcomp[j*MatHeight+l]*=mx;
238 if (bestcomp[j*MatHeight+l]>cscale[l])
239 cscale[l]=bestcomp[j*MatHeight+l];
240 if (bestcomp[j*MatHeight+l]<coffset[l])
241 coffset[l]=bestcomp[j*MatHeight+l];
243 cscale[l]-=coffset[l];
246 for (j=0;j<nFrames;j++)
248 tmp=254.0f*(bestcomp[j*MatHeight+l]-coffset[l])/cscale[l]-127.0f;
253 ccomp[j*MatHeight+l]=(char)floor(tmp+0.5);
255 coffset[l]+=cscale[l]*127.0f/254.0f;
262 for (j=0;j<nFrames;j++)
263 ccomp[j*MatHeight+l]=0;
266 for (k=0;k<MatWidth;k++)
268 tmp=best[l*MatWidth+k]*mx;
273 mat[k*MatHeight+l]=(char)floor(tmp+0.5);
280 for (j=0;j<nFrames;j++)
281 ccomp[j*MatHeight+l]=0;
282 for (k=0;k<MatWidth;k++)
283 mat[k*MatHeight+l]=0;
295 ans=(float *)SafeMalloc(sizeof(float)*MatWidth, "AnimCompressToBytes");
296 for (j=0;j<nFrames;j++)
298 for (k=0;k<MatWidth;k++)
301 for (l=0;l<CFrameSize;l++)
302 ans[k]+=(float)(mat[l+k*MatHeight])*((float)(ccomp[j*CFrameSize+l])*cscale[l]+coffset[l]);
303 ans[k]+=(float)(cbase[k])*scale[k%3]+trans[k%3];
304 tmp=(float)fabs(ans[k]-frames[j*MatWidth+k]-base[k]);
310 if (bmin[k%3]>ans[k])
312 if (bmax[k%3]<ans[k])
316 avedev/=(float)numave;
317 printf("%f Max Deviation (inches) %f Ave Dev. (inches)\n",maxdev,avedev);
321 void AnimCompressGetMatrix(float *mat)
324 for (k=0;k<MatWidth;k++)
325 for (l=0;l<MatHeight;l++)
326 mat[k*MatHeight+l]=best[l*MatWidth+k];
329 void AnimCompressGetFrames(float *mat)
331 memcpy(mat,bestcomp,CFrameSize*nFrames*sizeof(float));
334 void AnimCompressGetBase(int i,float *x,float *y,float *z)
341 void AnimCompressEnd()