-/*\r
-Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
-For a list of contributors, see the accompanying CONTRIBUTORS file.\r
-\r
-This file is part of GtkRadiant.\r
-\r
-GtkRadiant is free software; you can redistribute it and/or modify\r
-it under the terms of the GNU General Public License as published by\r
-the Free Software Foundation; either version 2 of the License, or\r
-(at your option) any later version.\r
-\r
-GtkRadiant is distributed in the hope that it will be useful,\r
-but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
-GNU General Public License for more details.\r
-\r
-You should have received a copy of the GNU General Public License\r
-along with GtkRadiant; if not, write to the Free Software\r
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\r
-*/\r
-\r
-\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-#include <math.h>\r
-#include <memory.h>\r
-#include "animcomp.h"\r
-\r
-\r
-void *SafeMalloc(size_t n, char *desc);\r
-\r
-\r
-\r
-float *matrix;\r
-float *delta;\r
-float *best;\r
-float *comp;\r
-float *tcomp;\r
-float *bestcomp;\r
-float *frames;\r
-float *base;\r
-\r
-int MatWidth;\r
-int MatHeight;\r
-int CFrameSize;\r
-int nFrames;\r
-\r
-\r
-void AnimCompressInit(int nframes,int nVerts,int CompressedFrameSize)\r
-{\r
- nFrames=nframes;\r
- MatWidth=nVerts*3;\r
- MatHeight=CompressedFrameSize;\r
- CFrameSize=CompressedFrameSize;\r
- matrix=(float *)SafeMalloc(MatWidth*MatHeight*sizeof(float), "AnimCompressInit");\r
- best=(float *)SafeMalloc(MatWidth*MatHeight*sizeof(float), "AnimCompressInit");\r
- delta=(float *)SafeMalloc(MatWidth*MatHeight*sizeof(float), "AnimCompressInit");\r
- comp=(float *)SafeMalloc(CFrameSize*nFrames*sizeof(float), "AnimCompressInit");\r
- tcomp=(float *)SafeMalloc(CFrameSize*nFrames*sizeof(float), "AnimCompressInit");\r
- bestcomp=(float *)SafeMalloc(CFrameSize*nFrames*sizeof(float), "AnimCompressInit");\r
- base=(float *)SafeMalloc(MatWidth*sizeof(float), "AnimCompressInit");\r
- frames=(float *)SafeMalloc(MatWidth*nFrames*sizeof(float), "AnimCompressInit");\r
-}\r
-\r
-void AnimSetFrame(int frame,int index,float x,float y,float z)\r
-{\r
- frames[frame*MatWidth+index*3]=x;\r
- frames[frame*MatWidth+index*3+1]=y;\r
- frames[frame*MatWidth+index*3+2]=z;\r
-}\r
-\r
-typedef struct \r
-{\r
- int index;\r
- float val;\r
-} SORTP;\r
-\r
-\r
-#define F_RANDOM (((float)rand())/(float)RAND_MAX)\r
-\r
-extern void DOsvd(float *a,float *res,float *comp,float *values,int nframes,int framesize,int compressedsize);\r
-\r
-void AnimCompressDoit()\r
-{\r
- float compression;\r
- float *rescale;\r
- float *ans;\r
- float maxdev;\r
- float avedev;\r
- float tmp;\r
- int j,k,l,numave;\r
-\r
- for (k=0;k<MatWidth;k++)\r
- base[k]=0.0f;\r
- for (j=0;j<nFrames;j++)\r
- for (k=0;k<MatWidth;k++)\r
- base[k]+=frames[j*MatWidth+k];\r
- tmp=1.0f/(float)nFrames;\r
- for (k=0;k<MatWidth;k++)\r
- base[k]*=tmp;\r
- for (j=0;j<nFrames;j++)\r
- for (k=0;k<MatWidth;k++)\r
- frames[j*MatWidth+k]-=base[k];\r
-\r
- ans=(float *)SafeMalloc(sizeof(float)*MatWidth, "AnimCompressDoit");\r
- rescale=(float *)SafeMalloc(sizeof(float)*CFrameSize, "AnimCompressDoit");\r
- DOsvd(frames,best,bestcomp,rescale,nFrames,MatWidth,MatHeight);\r
- avedev=0.0;\r
- for (l=0;l<CFrameSize;l++)\r
- avedev+=rescale[l];\r
- for (l=0;l<CFrameSize;l++)\r
- printf("%3.1f ",100.0f*rescale[l]/avedev);\r
- printf("\n");\r
- for (j=0;j<nFrames;j++)\r
- {\r
- for (l=0;l<CFrameSize;l++)\r
- {\r
- bestcomp[j*CFrameSize+l]=0.0;\r
- for (k=0;k<MatWidth;k++)\r
- bestcomp[j*CFrameSize+l]+=best[l*MatWidth+k]*frames[j*MatWidth+k];\r
- }\r
- }\r
- numave=0;\r
- avedev=0.0;\r
- maxdev=0.0;\r
- for (j=0;j<nFrames;j++)\r
- {\r
- for (k=0;k<MatWidth;k++)\r
- {\r
- ans[k]=0.0;\r
- for (l=0;l<CFrameSize;l++)\r
- ans[k]+=best[l*MatWidth+k]*bestcomp[j*CFrameSize+l];\r
- ans[k]-=frames[j*MatWidth+k];\r
- tmp=(float)fabs(ans[k]);\r
- if (tmp>maxdev)\r
- maxdev=tmp;\r
- avedev+=tmp;\r
- numave++;\r
- }\r
- }\r
- avedev/=(float)numave;\r
-printf("%f Max Deviation (inches) %f Ave Dev. (inches)\n",maxdev,avedev);\r
-printf("%d bytes original size\n",MatWidth*nFrames);\r
-printf("%d bytes of overhead\n",MatWidth*MatHeight);\r
-printf("%d bytes/frame * %d frames = %d bytes\n",CFrameSize,nFrames,CFrameSize*nFrames);\r
- compression=(float)(MatWidth*MatHeight+CFrameSize*nFrames+MatWidth);\r
- compression/=(float)(MatWidth*nFrames);\r
-printf("Overall compression = %f %%\n",100.0f-100.0f*compression);\r
- compression=(float)(CFrameSize);\r
- compression/=(float)(MatWidth);\r
-printf("frame size compression = %f %%\n",100.0f-100.0f*compression);\r
- free(rescale);\r
- free(ans);\r
-}\r
-\r
-void AnimCompressToBytes(float *trans,float *scale,char *mat,char *ccomp,unsigned char *cbase,float *cscale,float *coffset,float *bmin,float *bmax)\r
-{\r
- int k,l,nv,j;\r
- float maxdev;\r
- float avedev;\r
- float tmp;\r
- int numave;\r
- float t,mx;\r
- float *ans;\r
-\r
-\r
- nv=MatWidth/3;\r
-\r
- trans[0]=1E30f;\r
- scale[0]=-1E30f;\r
- trans[1]=1E30f;\r
- scale[1]=-1E30f;\r
- trans[2]=1E30f;\r
- scale[2]=-1E30f;\r
- for (k=0;k<MatWidth;k+=3)\r
- {\r
- if (base[k]>scale[0])\r
- scale[0]=base[k];\r
- if (base[k]<trans[0])\r
- trans[0]=base[k];\r
-\r
- if (base[k+1]>scale[1])\r
- scale[1]=base[k+1];\r
- if (base[k+1]<trans[1])\r
- trans[1]=base[k+1];\r
-\r
- if (base[k+2]>scale[2])\r
- scale[2]=base[k+2];\r
- if (base[k+2]<trans[2])\r
- trans[2]=base[k+2];\r
- }\r
-\r
- scale[0]-=trans[0];\r
- scale[1]-=trans[1];\r
- scale[2]-=trans[2];\r
- scale[0]/=255.0f;\r
- scale[1]/=255.0f;\r
- scale[2]/=255.0f;\r
- for (k=0;k<MatWidth;k+=3)\r
- {\r
- t=(base[k]-trans[0])/scale[0];\r
- if (t<0.0f)\r
- t=0.0f;\r
- if (t>255.0f)\r
- t=255.0f;\r
- cbase[k]=(unsigned char)t;\r
-\r
- t=(base[k+1]-trans[1])/scale[1];\r
- if (t<0.0f)\r
- t=0.0f;\r
- if (t>255.0f)\r
- t=255.0f;\r
- cbase[k+1]=(unsigned char)t;\r
-\r
- t=(base[k+2]-trans[2])/scale[2];\r
- if (t<0.0f)\r
- t=0.0f;\r
- if (t>255.0f)\r
- t=255.0f;\r
- cbase[k+2]=(unsigned char)t;\r
- }\r
- for (l=0;l<MatHeight;l++)\r
- {\r
- mx=0.0;\r
- for (k=0;k<MatWidth;k++)\r
- {\r
- if (fabs(best[l*MatWidth+k])>mx)\r
- mx=(float)fabs(best[l*MatWidth+k]);\r
- }\r
- if (mx>1E-8)\r
- {\r
- mx/=127.0f;\r
- coffset[l]=1E30f;\r
- cscale[l]=-1E30f;\r
- for (j=0;j<nFrames;j++)\r
- {\r
- bestcomp[j*MatHeight+l]*=mx;\r
- if (bestcomp[j*MatHeight+l]>cscale[l])\r
- cscale[l]=bestcomp[j*MatHeight+l];\r
- if (bestcomp[j*MatHeight+l]<coffset[l])\r
- coffset[l]=bestcomp[j*MatHeight+l];\r
- }\r
- cscale[l]-=coffset[l];\r
- if (cscale[l]>1E-10)\r
- {\r
- for (j=0;j<nFrames;j++)\r
- {\r
- tmp=254.0f*(bestcomp[j*MatHeight+l]-coffset[l])/cscale[l]-127.0f;\r
- if (tmp>127.0f)\r
- tmp=127.0f;\r
- if (tmp<-127.0f)\r
- tmp=-127.0f;\r
- ccomp[j*MatHeight+l]=(char)floor(tmp+0.5);\r
- }\r
- coffset[l]+=cscale[l]*127.0f/254.0f;\r
- cscale[l]/=254.0f;\r
- }\r
- else\r
- {\r
- cscale[l]=1.0f;\r
- coffset[l]=0.0f;\r
- for (j=0;j<nFrames;j++)\r
- ccomp[j*MatHeight+l]=0;\r
- }\r
- mx=1.0f/mx;\r
- for (k=0;k<MatWidth;k++)\r
- {\r
- tmp=best[l*MatWidth+k]*mx;\r
- if (tmp>127.0f)\r
- tmp=127.0f;\r
- if (tmp<-127.0f)\r
- tmp=-127.0f;\r
- mat[k*MatHeight+l]=(char)floor(tmp+0.5);\r
- }\r
- }\r
- else\r
- {\r
- cscale[l]=1.0f;\r
- coffset[l]=0.0f;\r
- for (j=0;j<nFrames;j++)\r
- ccomp[j*MatHeight+l]=0;\r
- for (k=0;k<MatWidth;k++)\r
- mat[k*MatHeight+l]=0;\r
- }\r
- }\r
- bmin[0]=1E30f;\r
- bmin[1]=1E30f;\r
- bmin[2]=1E30f;\r
- bmax[0]=-1E30f;\r
- bmax[1]=-1E30f;\r
- bmax[2]=-1E30f;\r
- numave=0;\r
- avedev=0.0;\r
- maxdev=0.0;\r
- ans=(float *)SafeMalloc(sizeof(float)*MatWidth, "AnimCompressToBytes");\r
- for (j=0;j<nFrames;j++)\r
- {\r
- for (k=0;k<MatWidth;k++)\r
- {\r
- ans[k]=0.0;\r
- for (l=0;l<CFrameSize;l++)\r
- ans[k]+=(float)(mat[l+k*MatHeight])*((float)(ccomp[j*CFrameSize+l])*cscale[l]+coffset[l]);\r
- ans[k]+=(float)(cbase[k])*scale[k%3]+trans[k%3];\r
- tmp=(float)fabs(ans[k]-frames[j*MatWidth+k]-base[k]);\r
- if (tmp>maxdev)\r
- maxdev=tmp;\r
- avedev+=tmp;\r
- numave++;\r
-\r
- if (bmin[k%3]>ans[k])\r
- bmin[k%3]=ans[k];\r
- if (bmax[k%3]<ans[k])\r
- bmax[k%3]=ans[k];\r
- }\r
- }\r
- avedev/=(float)numave;\r
-printf("%f Max Deviation (inches) %f Ave Dev. (inches)\n",maxdev,avedev);\r
- free(ans);\r
-}\r
-\r
-void AnimCompressGetMatrix(float *mat)\r
-{\r
- int k,l;\r
- for (k=0;k<MatWidth;k++)\r
- for (l=0;l<MatHeight;l++)\r
- mat[k*MatHeight+l]=best[l*MatWidth+k];\r
-}\r
-\r
-void AnimCompressGetFrames(float *mat)\r
-{\r
- memcpy(mat,bestcomp,CFrameSize*nFrames*sizeof(float));\r
-}\r
-\r
-void AnimCompressGetBase(int i,float *x,float *y,float *z)\r
-{\r
- *x=base[i*3];\r
- *y=base[i*3+1];\r
- *z=base[i*3+2];\r
-}\r
-\r
-void AnimCompressEnd()\r
-{\r
- free(matrix);\r
- free(best);\r
- free(delta);\r
- free(comp);\r
- free(tcomp);\r
- free(bestcomp);\r
- free(base);\r
- free(frames);\r
-}\r
+/*
+Copyright (C) 1999-2007 id Software, Inc. and contributors.
+For a list of contributors, see the accompanying CONTRIBUTORS file.
+
+This file is part of GtkRadiant.
+
+GtkRadiant is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+GtkRadiant is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GtkRadiant; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <memory.h>
+#include "animcomp.h"
+
+
+void *SafeMalloc(size_t n, char *desc);
+
+
+
+float *matrix;
+float *delta;
+float *best;
+float *comp;
+float *tcomp;
+float *bestcomp;
+float *frames;
+float *base;
+
+int MatWidth;
+int MatHeight;
+int CFrameSize;
+int nFrames;
+
+
+void AnimCompressInit(int nframes,int nVerts,int CompressedFrameSize)
+{
+ nFrames=nframes;
+ MatWidth=nVerts*3;
+ MatHeight=CompressedFrameSize;
+ CFrameSize=CompressedFrameSize;
+ matrix=(float *)SafeMalloc(MatWidth*MatHeight*sizeof(float), "AnimCompressInit");
+ best=(float *)SafeMalloc(MatWidth*MatHeight*sizeof(float), "AnimCompressInit");
+ delta=(float *)SafeMalloc(MatWidth*MatHeight*sizeof(float), "AnimCompressInit");
+ comp=(float *)SafeMalloc(CFrameSize*nFrames*sizeof(float), "AnimCompressInit");
+ tcomp=(float *)SafeMalloc(CFrameSize*nFrames*sizeof(float), "AnimCompressInit");
+ bestcomp=(float *)SafeMalloc(CFrameSize*nFrames*sizeof(float), "AnimCompressInit");
+ base=(float *)SafeMalloc(MatWidth*sizeof(float), "AnimCompressInit");
+ frames=(float *)SafeMalloc(MatWidth*nFrames*sizeof(float), "AnimCompressInit");
+}
+
+void AnimSetFrame(int frame,int index,float x,float y,float z)
+{
+ frames[frame*MatWidth+index*3]=x;
+ frames[frame*MatWidth+index*3+1]=y;
+ frames[frame*MatWidth+index*3+2]=z;
+}
+
+typedef struct
+{
+ int index;
+ float val;
+} SORTP;
+
+
+#define F_RANDOM (((float)rand())/(float)RAND_MAX)
+
+extern void DOsvd(float *a,float *res,float *comp,float *values,int nframes,int framesize,int compressedsize);
+
+void AnimCompressDoit()
+{
+ float compression;
+ float *rescale;
+ float *ans;
+ float maxdev;
+ float avedev;
+ float tmp;
+ int j,k,l,numave;
+
+ for (k=0;k<MatWidth;k++)
+ base[k]=0.0f;
+ for (j=0;j<nFrames;j++)
+ for (k=0;k<MatWidth;k++)
+ base[k]+=frames[j*MatWidth+k];
+ tmp=1.0f/(float)nFrames;
+ for (k=0;k<MatWidth;k++)
+ base[k]*=tmp;
+ for (j=0;j<nFrames;j++)
+ for (k=0;k<MatWidth;k++)
+ frames[j*MatWidth+k]-=base[k];
+
+ ans=(float *)SafeMalloc(sizeof(float)*MatWidth, "AnimCompressDoit");
+ rescale=(float *)SafeMalloc(sizeof(float)*CFrameSize, "AnimCompressDoit");
+ DOsvd(frames,best,bestcomp,rescale,nFrames,MatWidth,MatHeight);
+ avedev=0.0;
+ for (l=0;l<CFrameSize;l++)
+ avedev+=rescale[l];
+ for (l=0;l<CFrameSize;l++)
+ printf("%3.1f ",100.0f*rescale[l]/avedev);
+ printf("\n");
+ for (j=0;j<nFrames;j++)
+ {
+ for (l=0;l<CFrameSize;l++)
+ {
+ bestcomp[j*CFrameSize+l]=0.0;
+ for (k=0;k<MatWidth;k++)
+ bestcomp[j*CFrameSize+l]+=best[l*MatWidth+k]*frames[j*MatWidth+k];
+ }
+ }
+ numave=0;
+ avedev=0.0;
+ maxdev=0.0;
+ for (j=0;j<nFrames;j++)
+ {
+ for (k=0;k<MatWidth;k++)
+ {
+ ans[k]=0.0;
+ for (l=0;l<CFrameSize;l++)
+ ans[k]+=best[l*MatWidth+k]*bestcomp[j*CFrameSize+l];
+ ans[k]-=frames[j*MatWidth+k];
+ tmp=(float)fabs(ans[k]);
+ if (tmp>maxdev)
+ maxdev=tmp;
+ avedev+=tmp;
+ numave++;
+ }
+ }
+ avedev/=(float)numave;
+printf("%f Max Deviation (inches) %f Ave Dev. (inches)\n",maxdev,avedev);
+printf("%d bytes original size\n",MatWidth*nFrames);
+printf("%d bytes of overhead\n",MatWidth*MatHeight);
+printf("%d bytes/frame * %d frames = %d bytes\n",CFrameSize,nFrames,CFrameSize*nFrames);
+ compression=(float)(MatWidth*MatHeight+CFrameSize*nFrames+MatWidth);
+ compression/=(float)(MatWidth*nFrames);
+printf("Overall compression = %f %%\n",100.0f-100.0f*compression);
+ compression=(float)(CFrameSize);
+ compression/=(float)(MatWidth);
+printf("frame size compression = %f %%\n",100.0f-100.0f*compression);
+ free(rescale);
+ free(ans);
+}
+
+void AnimCompressToBytes(float *trans,float *scale,char *mat,char *ccomp,unsigned char *cbase,float *cscale,float *coffset,float *bmin,float *bmax)
+{
+ int k,l,nv,j;
+ float maxdev;
+ float avedev;
+ float tmp;
+ int numave;
+ float t,mx;
+ float *ans;
+
+
+ nv=MatWidth/3;
+
+ trans[0]=1E30f;
+ scale[0]=-1E30f;
+ trans[1]=1E30f;
+ scale[1]=-1E30f;
+ trans[2]=1E30f;
+ scale[2]=-1E30f;
+ for (k=0;k<MatWidth;k+=3)
+ {
+ if (base[k]>scale[0])
+ scale[0]=base[k];
+ if (base[k]<trans[0])
+ trans[0]=base[k];
+
+ if (base[k+1]>scale[1])
+ scale[1]=base[k+1];
+ if (base[k+1]<trans[1])
+ trans[1]=base[k+1];
+
+ if (base[k+2]>scale[2])
+ scale[2]=base[k+2];
+ if (base[k+2]<trans[2])
+ trans[2]=base[k+2];
+ }
+
+ scale[0]-=trans[0];
+ scale[1]-=trans[1];
+ scale[2]-=trans[2];
+ scale[0]/=255.0f;
+ scale[1]/=255.0f;
+ scale[2]/=255.0f;
+ for (k=0;k<MatWidth;k+=3)
+ {
+ t=(base[k]-trans[0])/scale[0];
+ if (t<0.0f)
+ t=0.0f;
+ if (t>255.0f)
+ t=255.0f;
+ cbase[k]=(unsigned char)t;
+
+ t=(base[k+1]-trans[1])/scale[1];
+ if (t<0.0f)
+ t=0.0f;
+ if (t>255.0f)
+ t=255.0f;
+ cbase[k+1]=(unsigned char)t;
+
+ t=(base[k+2]-trans[2])/scale[2];
+ if (t<0.0f)
+ t=0.0f;
+ if (t>255.0f)
+ t=255.0f;
+ cbase[k+2]=(unsigned char)t;
+ }
+ for (l=0;l<MatHeight;l++)
+ {
+ mx=0.0;
+ for (k=0;k<MatWidth;k++)
+ {
+ if (fabs(best[l*MatWidth+k])>mx)
+ mx=(float)fabs(best[l*MatWidth+k]);
+ }
+ if (mx>1E-8)
+ {
+ mx/=127.0f;
+ coffset[l]=1E30f;
+ cscale[l]=-1E30f;
+ for (j=0;j<nFrames;j++)
+ {
+ bestcomp[j*MatHeight+l]*=mx;
+ if (bestcomp[j*MatHeight+l]>cscale[l])
+ cscale[l]=bestcomp[j*MatHeight+l];
+ if (bestcomp[j*MatHeight+l]<coffset[l])
+ coffset[l]=bestcomp[j*MatHeight+l];
+ }
+ cscale[l]-=coffset[l];
+ if (cscale[l]>1E-10)
+ {
+ for (j=0;j<nFrames;j++)
+ {
+ tmp=254.0f*(bestcomp[j*MatHeight+l]-coffset[l])/cscale[l]-127.0f;
+ if (tmp>127.0f)
+ tmp=127.0f;
+ if (tmp<-127.0f)
+ tmp=-127.0f;
+ ccomp[j*MatHeight+l]=(char)floor(tmp+0.5);
+ }
+ coffset[l]+=cscale[l]*127.0f/254.0f;
+ cscale[l]/=254.0f;
+ }
+ else
+ {
+ cscale[l]=1.0f;
+ coffset[l]=0.0f;
+ for (j=0;j<nFrames;j++)
+ ccomp[j*MatHeight+l]=0;
+ }
+ mx=1.0f/mx;
+ for (k=0;k<MatWidth;k++)
+ {
+ tmp=best[l*MatWidth+k]*mx;
+ if (tmp>127.0f)
+ tmp=127.0f;
+ if (tmp<-127.0f)
+ tmp=-127.0f;
+ mat[k*MatHeight+l]=(char)floor(tmp+0.5);
+ }
+ }
+ else
+ {
+ cscale[l]=1.0f;
+ coffset[l]=0.0f;
+ for (j=0;j<nFrames;j++)
+ ccomp[j*MatHeight+l]=0;
+ for (k=0;k<MatWidth;k++)
+ mat[k*MatHeight+l]=0;
+ }
+ }
+ bmin[0]=1E30f;
+ bmin[1]=1E30f;
+ bmin[2]=1E30f;
+ bmax[0]=-1E30f;
+ bmax[1]=-1E30f;
+ bmax[2]=-1E30f;
+ numave=0;
+ avedev=0.0;
+ maxdev=0.0;
+ ans=(float *)SafeMalloc(sizeof(float)*MatWidth, "AnimCompressToBytes");
+ for (j=0;j<nFrames;j++)
+ {
+ for (k=0;k<MatWidth;k++)
+ {
+ ans[k]=0.0;
+ for (l=0;l<CFrameSize;l++)
+ ans[k]+=(float)(mat[l+k*MatHeight])*((float)(ccomp[j*CFrameSize+l])*cscale[l]+coffset[l]);
+ ans[k]+=(float)(cbase[k])*scale[k%3]+trans[k%3];
+ tmp=(float)fabs(ans[k]-frames[j*MatWidth+k]-base[k]);
+ if (tmp>maxdev)
+ maxdev=tmp;
+ avedev+=tmp;
+ numave++;
+
+ if (bmin[k%3]>ans[k])
+ bmin[k%3]=ans[k];
+ if (bmax[k%3]<ans[k])
+ bmax[k%3]=ans[k];
+ }
+ }
+ avedev/=(float)numave;
+printf("%f Max Deviation (inches) %f Ave Dev. (inches)\n",maxdev,avedev);
+ free(ans);
+}
+
+void AnimCompressGetMatrix(float *mat)
+{
+ int k,l;
+ for (k=0;k<MatWidth;k++)
+ for (l=0;l<MatHeight;l++)
+ mat[k*MatHeight+l]=best[l*MatWidth+k];
+}
+
+void AnimCompressGetFrames(float *mat)
+{
+ memcpy(mat,bestcomp,CFrameSize*nFrames*sizeof(float));
+}
+
+void AnimCompressGetBase(int i,float *x,float *y,float *z)
+{
+ *x=base[i*3];
+ *y=base[i*3+1];
+ *z=base[i*3+2];
+}
+
+void AnimCompressEnd()
+{
+ free(matrix);
+ free(best);
+ free(delta);
+ free(comp);
+ free(tcomp);
+ free(bestcomp);
+ free(base);
+ free(frames);
+}