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