JD2022-TU1/main/extern/Camcam/Tools/HandTracking.cpp

3530 lines
112 KiB
C++
Raw Blame History

#include "Scene.h"
void Contour(DrawInterface* DI, INPUT_IO** ID_MEDIA, int MediaDest, int MaskSrc)
{
checkDestSize(ID_MEDIA[MediaDest]->Image, ID_MEDIA[MaskSrc]->Image);
s32 * dest = ID_MEDIA[MediaDest]->Image.BASE;
s32 * src = ID_MEDIA[MaskSrc]->Image.BASE;
static s32 * tmp;
if(tmp == NULL) tmp = (s32*) CC_malloc(ID_MEDIA[MaskSrc]->Image.SX*ID_MEDIA[MaskSrc]->Image.SY*sizeof(s32));
memcpy(tmp, ID_MEDIA[MaskSrc]->Image.BASE, ID_MEDIA[MaskSrc]->Image.SX*ID_MEDIA[MaskSrc]->Image.SY*sizeof(s32));
int PITCH = ID_MEDIA[MediaDest]->Image.PITCH;
int vx[8]; vx[0]=0; vx[1]=-1; vx[2]=-1; vx[3]=-1; vx[4]=0; vx[5]=1; vx[6]=1; vx[7]=1;
int vy[8]; vy[0]=-1; vy[1]=-1; vy[2]=0; vy[3]=1; vy[4]=1; vy[5]=1; vy[6]=0; vy[7]=-1;
int nbVoisins;
int nbVoisinsPossibles;
for(int py=0; py<ID_MEDIA[MediaDest]->Image.SY; py++)
{
for(int px=0; px<ID_MEDIA[MediaDest]->Image.SX; px++)
{
nbVoisins = 0;
nbVoisinsPossibles = 0;
if(*(src+px+py*PITCH))
{
for(int v=0; v<8; v++)
{
if(px+vx[v]>=0 && px+vx[v]<ID_MEDIA[MediaDest]->Image.SX && py+vy[v]>=0 && py+vy[v]<ID_MEDIA[MediaDest]->Image.SY)
{
nbVoisinsPossibles++;
if(*(src+px+vx[v]+(py+vy[v])*PITCH))
{
nbVoisins++;
}
}
}
if(nbVoisinsPossibles == nbVoisins) *(tmp+px+py*PITCH) = 0;
}
}
}
memcpy(ID_MEDIA[MediaDest]->Image.BASE, tmp, ID_MEDIA[MaskSrc]->Image.SX*ID_MEDIA[MaskSrc]->Image.SY*sizeof(s32));
for(int py=1; py<ID_MEDIA[MediaDest]->Image.SY-1; py++)
{
for(int px=1; px<ID_MEDIA[MediaDest]->Image.SX-1; px++)
{
if(*(dest+px+py*PITCH))
{
for(int v=0; v<8; v+=2)
{
if(*(dest+px+vx[v]+(py+vy[v])*PITCH) && *(dest+px+vx[(v+2)%8]+(py+vy[(v+2)%8])*PITCH) && (!(*(dest+px+vx[(v+5)%8]+(py+vy[(v+5)%8])*PITCH))))
{
*(dest+px+py*PITCH) = 0;
break;
}
}
}
}
}
for(int py=ID_MEDIA[MediaDest]->Image.SY-2; py>0; py--)
{
for(int px=1; px<ID_MEDIA[MediaDest]->Image.SX-1; px++)
{
if(*(dest+px+py*PITCH))
{
for(int v=0; v<8; v+=2)
{
if(*(dest+px+vx[v]+(py+vy[v])*PITCH) && *(dest+px+vx[(v+2)%8]+(py+vy[(v+2)%8])*PITCH) && (!(*(dest+px+vx[(v+5)%8]+(py+vy[(v+5)%8])*PITCH))))
{
*(dest+px+py*PITCH) = 0;
break;
}
}
}
}
}
for(int py=0; py<ID_MEDIA[MediaDest]->Image.SY; py++)
{
for(int px=0; px<ID_MEDIA[MediaDest]->Image.SX; px++)
{
nbVoisins = 0;
nbVoisinsPossibles = 0;
if(*(dest+px+py*PITCH)==-1)
{
for(int v=0; v<8; v++)
{
if(px+vx[v]>=0 && px+vx[v]<ID_MEDIA[MediaDest]->Image.SX && py+vy[v]>=0 && py+vy[v]<ID_MEDIA[MediaDest]->Image.SY)
{
nbVoisinsPossibles++;
if(*(dest+px+vx[v]+(py+vy[v])*PITCH)==-1)
nbVoisins++;
}
}
if(nbVoisinsPossibles==8 && nbVoisins<2) *(dest+px+py*PITCH) = 0;
//suppression des barbules <20> partir de ce point
bool remainingNeighbour;
int x = px;
int y = py;
do
{
remainingNeighbour = false;
nbVoisins = 0;
nbVoisinsPossibles = 0;
int next;
for(int v=0; v<8; v++)
{
if(x+vx[v]>=0 && x+vx[v]<ID_MEDIA[MediaDest]->Image.SX && y+vy[v]>=0 && y+vy[v]<ID_MEDIA[MediaDest]->Image.SY)
{
nbVoisinsPossibles++;
if(*(dest+x+vx[v]+(y+vy[v])*PITCH)==-1)
{
nbVoisins++;
next = v;
}
}
}
if(nbVoisinsPossibles==8 && nbVoisins==1)
{
*(dest+x+y*PITCH) = 0;
remainingNeighbour = true;
x = x + vx[next];
y = y + vy[next];
}
} while(remainingNeighbour);
}
}
}
if(ID_MEDIA[MediaDest]->ulAssociatedTextureIndex != -1)
DI->UpdateTexture_BM_2_HW(ID_MEDIA[MediaDest]->ulAssociatedTextureIndex);
}
void PropagateMask(DrawInterface* DI, INPUT_IO** ID_MEDIA, int MediaDest, int Mask1, int Mask2)
{
if(ID_MEDIA[Mask2]->Image.SX == ID_MEDIA[Mask1]->Image.SX
&& ID_MEDIA[Mask2]->Image.SY == ID_MEDIA[Mask1]->Image.SY)
{
bool srcChanged = checkDestSize(ID_MEDIA[MediaDest]->Image, ID_MEDIA[Mask1]->Image);
MAP & SOURCEMAP1 = ID_MEDIA[Mask1]->Image;
MAP & SOURCEMAP2 = ID_MEDIA[Mask2]->Image;
MAP & DESTMAP = ID_MEDIA[MediaDest]->Image;
static WORKINGSPACE* WSPC = WSPC_CreateWspc(&(ID_MEDIA[MediaDest]->Image));
if(WSPC->HANDWORK[0]==NULL || srcChanged)
{
CC_free(WSPC->HANDWORK[0]);
WSPC->HANDWORK[0] = (s32*)CC_malloc(SOURCEMAP1.SX*SOURCEMAP1.SY*sizeof(s32));
}
if(WSPC->HANDWORK[1]==NULL || srcChanged)
{
CC_free(WSPC->HANDWORK[1]);
WSPC->HANDWORK[1] = (s32*)CC_malloc(SOURCEMAP1.SX*SOURCEMAP1.SY*sizeof(s32));
}
if(WSPC->HANDWORK[2]==NULL || srcChanged)
{
CC_free(WSPC->HANDWORK[2]);
WSPC->HANDWORK[2] = (s32*)CC_malloc(SOURCEMAP1.SX*SOURCEMAP1.SY*sizeof(s32));
}
if(WSPC->HANDWORK[3]==NULL || srcChanged)
{
CC_free(WSPC->HANDWORK[3]);
WSPC->HANDWORK[3] = (s32*)CC_malloc(SOURCEMAP1.SX*SOURCEMAP1.SY*sizeof(s32));
}
memset(WSPC->HANDWORK[0], 0, SOURCEMAP1.SX*SOURCEMAP1.SY*sizeof(s32));
memset(WSPC->HANDWORK[1], 0, SOURCEMAP1.SX*SOURCEMAP1.SY*sizeof(s32));
memset(WSPC->HANDWORK[2], 0, SOURCEMAP1.SX*SOURCEMAP1.SY*sizeof(s32));
memset(WSPC->HANDWORK[3], 0, SOURCEMAP1.SX*SOURCEMAP1.SY*sizeof(s32));
s32* init = WSPC->HANDWORK[3];
memcpy(init, SOURCEMAP1.BASE, ID_MEDIA[Mask1]->Image.SX*ID_MEDIA[Mask1]->Image.SY*sizeof(s32));
s32* visited = WSPC->HANDWORK[0];
//inversion du mask dest
for(int px=0; px<SOURCEMAP1.SX; px++)
for(int py=0; py<SOURCEMAP1.SY; py++)
(*(visited + px + py*SOURCEMAP2.PITCH))= ~(*(SOURCEMAP2.BASE + px + py*SOURCEMAP2.PITCH));
s32* dest = DESTMAP.BASE;
memcpy(dest, init, ID_MEDIA[Mask1]->Image.SX*ID_MEDIA[Mask1]->Image.SY*sizeof(s32));
for(int px=0; px<SOURCEMAP1.SX; px++)
for(int py=0; py<SOURCEMAP1.SY; py++)
{
if(*(init + px + py*SOURCEMAP2.PITCH)==-1)
spreadPx(visited, dest, px, py, SOURCEMAP1.PITCH, SOURCEMAP1.SY, SOURCEMAP1.SX, WSPC->HANDWORK[2], WSPC->HANDWORK[1]);
}
if(ID_MEDIA[MediaDest]->ulAssociatedTextureIndex != -1)
DI->UpdateTexture_BM_2_HW(ID_MEDIA[MediaDest]->ulAssociatedTextureIndex);
}
}
void SkinMask3(DrawInterface* DI, INPUT_IO** ID_MEDIA, int MediaDest, int MediaSrc, char* ColorRGB, int* DeltaYInf_DeltaYSup_DeltaCbInf_DeltaCbSup_DeltaCrInf_DeltaCrSup)
{
int YMin = 0;
int YMax = 255;
int CbMin = 104;
int CbMax = 131;
int CrMin = 134;
int CrMax = 161;
int rgb = makeRGB(150, 150, 20);
int RGB[3];
memset(RGB, 0, sizeof(RGB));
if (strlen(ColorRGB)==6)
{
RGB[0] = (IsHex(*(ColorRGB + 0))-1)*16 + (IsHex(*(ColorRGB + 1))-1);
RGB[1] = (IsHex(*(ColorRGB + 2))-1)*16 + (IsHex(*(ColorRGB + 3))-1);
RGB[2] = (IsHex(*(ColorRGB + 4))-1)*16 + (IsHex(*(ColorRGB + 5))-1);
rgb = makeRGB(RGB[0], RGB[1], RGB[2]);
if (DeltaYInf_DeltaYSup_DeltaCbInf_DeltaCbSup_DeltaCrInf_DeltaCrSup[0]!=-1)
{
YMin = getY(rgb)-DeltaYInf_DeltaYSup_DeltaCbInf_DeltaCbSup_DeltaCrInf_DeltaCrSup[0];
YMax = getY(rgb)+DeltaYInf_DeltaYSup_DeltaCbInf_DeltaCbSup_DeltaCrInf_DeltaCrSup[1];
CbMin = getCb(rgb)-DeltaYInf_DeltaYSup_DeltaCbInf_DeltaCbSup_DeltaCrInf_DeltaCrSup[2];
CbMax = getCb(rgb)+DeltaYInf_DeltaYSup_DeltaCbInf_DeltaCbSup_DeltaCrInf_DeltaCrSup[3];
CrMin = getCr(rgb)-DeltaYInf_DeltaYSup_DeltaCbInf_DeltaCbSup_DeltaCrInf_DeltaCrSup[4];
CrMax = getCr(rgb)+DeltaYInf_DeltaYSup_DeltaCbInf_DeltaCbSup_DeltaCrInf_DeltaCrSup[5];
}
}
checkDestSize(ID_MEDIA[MediaDest]->Image, ID_MEDIA[MediaSrc]->Image);
s32 * imgSource = (s32*)CC_malloc(ID_MEDIA[MediaSrc]->Image.SX*ID_MEDIA[MediaSrc]->Image.SY*sizeof(s32));
memcpy(imgSource, ID_MEDIA[MediaSrc]->Image.BASE, ID_MEDIA[MediaSrc]->Image.SX*ID_MEDIA[MediaSrc]->Image.SY*sizeof(s32));
filterImgRVB(ID_MEDIA[MediaDest]->Image.BASE, ID_MEDIA[MediaSrc]->Image.BASE, ID_MEDIA[MediaSrc]->Image.PITCH, ID_MEDIA[MediaSrc]->Image.SY, ID_MEDIA[MediaSrc]->Image.SX);
memcpy(ID_MEDIA[MediaSrc]->Image.BASE, ID_MEDIA[MediaDest]->Image.BASE, ID_MEDIA[MediaSrc]->Image.SX*ID_MEDIA[MediaSrc]->Image.SY*sizeof(s32));
showSkin(ID_MEDIA[MediaDest]->Image, ID_MEDIA[MediaSrc]->Image, YMin, YMax, CbMin, CbMax, CrMin, CrMax);
memcpy(ID_MEDIA[MediaSrc]->Image.BASE, imgSource, ID_MEDIA[MediaSrc]->Image.SX*ID_MEDIA[MediaSrc]->Image.SY*sizeof(s32));
CC_free(imgSource);
imgSource = 0;
if(ID_MEDIA[MediaDest]->ulAssociatedTextureIndex != -1)
DI->UpdateTexture_BM_2_HW(ID_MEDIA[MediaDest]->ulAssociatedTextureIndex);
}
void TranslateSkinColor(DrawInterface* DI, INPUT_IO** ID_MEDIA, int mediaDst, int MaskSrc, int maskSrc, char* ColorRGBSrc1, char* ColorRGBSrc2, char* ColorRGBDst1, char* ColorRGBDst2)
{
int RGBSrc1[3];
int RGBSrc2[3];
int RGBDst1[3];
int RGBDst2[3];
checkDestSize(ID_MEDIA[mediaDst]->Image, ID_MEDIA[MaskSrc]->Image);
s32 * dest = ID_MEDIA[mediaDst]->Image.BASE;
s32 * mask = ID_MEDIA[maskSrc]->Image.BASE;
s32 * src = ID_MEDIA[MaskSrc]->Image.BASE;
int PITCH = ID_MEDIA[mediaDst]->Image.PITCH;
int SX = ID_MEDIA[MaskSrc]->Image.SX;
int SY = ID_MEDIA[MaskSrc]->Image.SY;
//debugScr(1);
if(strlen(ColorRGBSrc1)==6)
if(strlen(ColorRGBSrc2)==6)
if(strlen(ColorRGBDst1)==6)
if(strlen(ColorRGBDst2)==6)
{
//debugScr(2);
RGBSrc1[0] = (IsHex(*(ColorRGBSrc1 + 0))-1)*16 + (IsHex(*(ColorRGBSrc1 + 1))-1);
RGBSrc1[1] = (IsHex(*(ColorRGBSrc1 + 2))-1)*16 + (IsHex(*(ColorRGBSrc1 + 3))-1);
RGBSrc1[2] = (IsHex(*(ColorRGBSrc1 + 4))-1)*16 + (IsHex(*(ColorRGBSrc1 + 5))-1);
int color1Src = makeRGB(RGBSrc1[0], RGBSrc1[1], RGBSrc1[2]);
RGBSrc2[0] = (IsHex(*(ColorRGBSrc2 + 0))-1)*16 + (IsHex(*(ColorRGBSrc2 + 1))-1);
RGBSrc2[1] = (IsHex(*(ColorRGBSrc2 + 2))-1)*16 + (IsHex(*(ColorRGBSrc2 + 3))-1);
RGBSrc2[2] = (IsHex(*(ColorRGBSrc2 + 4))-1)*16 + (IsHex(*(ColorRGBSrc2 + 5))-1);
int color2Src = makeRGB(RGBSrc2[0], RGBSrc2[1], RGBSrc2[2]);
RGBDst1[0] = (IsHex(*(ColorRGBDst1 + 0))-1)*16 + (IsHex(*(ColorRGBDst1 + 1))-1);
RGBDst1[1] = (IsHex(*(ColorRGBDst1 + 2))-1)*16 + (IsHex(*(ColorRGBDst1 + 3))-1);
RGBDst1[2] = (IsHex(*(ColorRGBDst1 + 4))-1)*16 + (IsHex(*(ColorRGBDst1 + 5))-1);
int color1Dst = makeRGB(RGBDst1[0], RGBDst1[1], RGBDst1[2]);
RGBDst2[0] = (IsHex(*(ColorRGBDst2 + 0))-1)*16 + (IsHex(*(ColorRGBDst2 + 1))-1);
RGBDst2[1] = (IsHex(*(ColorRGBDst2 + 2))-1)*16 + (IsHex(*(ColorRGBDst2 + 3))-1);
RGBDst2[2] = (IsHex(*(ColorRGBDst2 + 4))-1)*16 + (IsHex(*(ColorRGBDst2 + 5))-1);
int color2Dst = makeRGB(RGBDst2[0], RGBDst2[1], RGBDst2[2]);
int color1SrcR = getR(color1Src);
int color1SrcV = getV(color1Src);
int color1SrcB = getB(color1Src);
int color2SrcR = getR(color2Src);
int color2SrcV = getV(color2Src);
int color2SrcB = getB(color2Src);
int color1DstR = getR(color1Dst);
int color1DstV = getV(color1Dst);
int color1DstB = getB(color1Dst);
int color2DstR = getR(color2Dst);
int color2DstV = getV(color2Dst);
int color2DstB = getB(color2Dst);
if(color1SrcR!=color2SrcR && color1SrcV!=color2SrcV && color1SrcB!=color2SrcB)
{
//debugScr(3);
float coeffDirR = (float)(color1DstR-color2DstR)/(float)(color1SrcR-color2SrcR);
float ordOrigR = color2DstR-coeffDirR*color2SrcR;
float coeffDirV = (float)(color1DstV-color2DstV)/(float)(color1SrcV-color2SrcV);
float ordOrigV = color2DstV-coeffDirV*color2SrcV;
float coeffDirB = (float)(color1DstB-color2DstB)/(float)(color1SrcB-color2SrcB);
float ordOrigB = color2DstB-coeffDirB*color2SrcB;
//translation of the pixels of image destination skin by an affine fonction here :
int pixel;
int newR;
int newV;
int newB;
float alpha;
filterImgRVB(mask, mask, PITCH, SY, SX);
filterImgRVB(mask, mask, PITCH, SY, SX);
filterImgRVB(mask, mask, PITCH, SY, SX);
for(int py=0; py<SY; py++)
{
for(int px=0; px<SX; px++)
{
pixel = *(src+px+py*PITCH);
newR = (int)(coeffDirR*getR(pixel)+ordOrigR);
newV = (int)(coeffDirV*getV(pixel)+ordOrigV);
newB = (int)(coeffDirB*getB(pixel)+ordOrigB);
alpha = (float)(((*(mask+px+py*PITCH))>>16) & 0xff)/255;
newR = (int)(alpha*newR + (1-alpha)*getR(pixel));
newV = (int)(alpha*newV + (1-alpha)*getV(pixel));
newB = (int)(alpha*newB + (1-alpha)*getB(pixel));
if(newR<0) newR = 0;
if(newR>255) newR = 255;
if(newV<0) newV = 0;
if(newV>255) newV = 255;
if(newB<0) newB = 0;
if(newB>255) newB = 255;
*(dest+px+py*PITCH) = makeRGB(newR, newV, newB);
}
}
if(ID_MEDIA[mediaDst]->ulAssociatedTextureIndex != -1)
DI->UpdateTexture_BM_2_HW(ID_MEDIA[mediaDst]->ulAssociatedTextureIndex);
}
}
}
void LocalHistograms(DrawInterface* DI, INPUT_IO** ID_MEDIA, char* returnStr, int MediaDest, int MediaSrc, int* XY, int Size)
{
s32 * sourceCopie = (s32*)CC_malloc(ID_MEDIA[MediaSrc]->Image.SX*ID_MEDIA[MediaSrc]->Image.SY*sizeof(int));
memcpy(sourceCopie, ID_MEDIA[MediaSrc]->Image.BASE, ID_MEDIA[MediaSrc]->Image.SX*ID_MEDIA[MediaSrc]->Image.SY*sizeof(int));
for(int px=XY[0]-Size/2; px<XY[0]+Size/2; px++)
{
*(ID_MEDIA[MediaSrc]->Image.BASE + px +
(ID_MEDIA[MediaSrc]->Image.SY-(XY[1]+Size/2-1)-1)*ID_MEDIA[MediaSrc]->Image.PITCH) = 255<<16;
*(ID_MEDIA[MediaSrc]->Image.BASE + px +
(ID_MEDIA[MediaSrc]->Image.SY-(XY[1]-Size/2)-1)*ID_MEDIA[MediaSrc]->Image.PITCH) = 255<<16;
}
for(int py=XY[1]-Size/2; py<XY[1]+Size/2; py++)
{
*(ID_MEDIA[MediaSrc]->Image.BASE + XY[0]-Size/2 +
(ID_MEDIA[MediaSrc]->Image.SY-py-1)*ID_MEDIA[MediaSrc]->Image.PITCH) = 255<<16;
*(ID_MEDIA[MediaSrc]->Image.BASE + XY[0]+Size/2-1 +
(ID_MEDIA[MediaSrc]->Image.SY-py-1)*ID_MEDIA[MediaSrc]->Image.PITCH) = 255<<16;
}
if(ID_MEDIA[MediaSrc]->ulAssociatedTextureIndex != -1)
DI->UpdateTexture_BM_2_HW(ID_MEDIA[MediaSrc]->ulAssociatedTextureIndex);
int Y[256];
int Cb[256];
int Cr[256];
int pixel;
int maxY = 0;
int maxCb = 0;
int maxCr = 0;
memset(Y, 0, 256*sizeof(int));
memset(Cb, 0, 256*sizeof(int));
memset(Cr, 0, 256*sizeof(int));
memset(ID_MEDIA[MediaDest]->Image.BASE, 0, ID_MEDIA[MediaDest]->Image.SX*ID_MEDIA[MediaDest]->Image.SY*sizeof(int));
for(int px=XY[0]-Size/2; px<XY[0]+Size/2; px++)
{
for(int py=XY[1]-Size/2; py<XY[1]+Size/2; py++)
{
pixel = *(sourceCopie + px +
(ID_MEDIA[MediaSrc]->Image.SY-py-1)*ID_MEDIA[MediaSrc]->Image.PITCH);
Y[getY(pixel)]++;
Cb[getCb(pixel)]++;
Cr[getCr(pixel)]++;
if(Y[getY(pixel)]>maxY) maxY = Y[getY(pixel)];
if(Cb[getCb(pixel)]>maxCb) maxCb = Cb[getCb(pixel)];
if(Cr[getCr(pixel)]>maxCr) maxCr = Cr[getCr(pixel)];
}
}
int infY; int supY; int infCb; int supCb; int infCr; int supCr; int picY; int picCb; int picCr;
infY=supY=infCb=supCb=infCr=supCr=picY=picCb=picCr=0;
for(int niv=0; niv<256; niv++)
{
if(infY==0 && Y[niv]!=0) infY=niv;
if(Y[niv]!=0) supY=niv;
if(Y[niv]>Y[picY]) picY=niv;
if(infCb==0 && Cb[niv]!=0) infCb=niv;
if(Cb[niv]!=0) supCb=niv;
if(Cb[niv]>Cb[picCb]) picCb=niv;
if(infCr==0 && Cr[niv]!=0) infCr=niv;
if(Cr[niv]!=0) supCr=niv;
if(Cr[niv]>Cr[picY]) picCr=niv;
for(int h = 0; h<Y[niv]*90/maxY; h++)
{
*(ID_MEDIA[MediaDest]->Image.BASE + niv +
h*ID_MEDIA[MediaDest]->Image.PITCH) = makeRGB(200, 200, 0);
}
for(int h = 0; h<Cb[niv]*90/maxCb; h++)
{
*(ID_MEDIA[MediaDest]->Image.BASE + niv +
(h + 100)*ID_MEDIA[MediaDest]->Image.PITCH) = makeRGB(0, 150, 150);
}
for(int h = 0; h<Cr[niv]*90/maxCr; h++)
{
*(ID_MEDIA[MediaDest]->Image.BASE + niv +
(h+ 200)*ID_MEDIA[MediaDest]->Image.PITCH) = makeRGB(150, 0, 0);
}
}
if(ID_MEDIA[MediaDest]->ulAssociatedTextureIndex != -1)
DI->UpdateTexture_BM_2_HW(ID_MEDIA[MediaDest]->ulAssociatedTextureIndex);
memcpy(ID_MEDIA[MediaSrc]->Image.BASE, sourceCopie, ID_MEDIA[MediaSrc]->Image.SX*ID_MEDIA[MediaSrc]->Image.SY*sizeof(int));
CC_free(sourceCopie);
sourceCopie = NULL;
sprintf(returnStr, "Y=[%i %i %i] Cb=[%i %i %i] Cr=[%i %i %i]", infY, picY, supY, infCb, picCb, supCb, infCr, picCr, supCr);
}
bool checkDestSize(s32* dest, int* destSX, int* destSY, int* destPITCH, int* srcSX, int* srcSY, int* srcPITCH)
{
if(*destSX != *srcSX || *destSY != *srcSY || *destPITCH != *srcPITCH)
{
*destSX = *srcSX;
*destSY = *srcSY;
*destPITCH = *srcPITCH;
if(dest!=NULL) CC_free(dest);
dest = (s32*)CC_malloc((*srcSX)*(*srcSY)*sizeof(s32));
return true;
}
return false;
}
bool checkDestSize(s32* dest, int* destSX, int* destSY, int* destPITCH, int srcSX, int srcSY, int srcPITCH)
{
return checkDestSize(
dest,
destSX,
destSY,
destPITCH,
&srcSX,
&srcSY,
&srcPITCH
);
}
bool checkDestSize(MAP& dest, int srcSX, int srcSY, int srcPITCH)
{
return checkDestSize(
dest.BASE,
(int*)&(dest.SX),
(int*)&(dest.SY),
(int*)&(dest.PITCH),
&srcSX,
&srcSY,
&srcPITCH
);
}
bool checkDestSize(MAP& dest, MAP& src)
{
return checkDestSize(
dest.BASE,
(int*)&(dest.SX),
(int*)&(dest.SY),
(int*)&(dest.PITCH),
src.SX,
src.SY,
src.PITCH
);
}
void normalizeRgbImg(MAP& img)
{
if(img.BASE==NULL) return;
int hi=0,lo=255;
for(int x=0; x<img.SX; x++)
{
for(int y=0; y<img.SY; y++)
{
int pixelValue = *(img.BASE + x + y*img.PITCH);
int redValue = getR(pixelValue);
int greenValue = getV(pixelValue);
int blueValue = getB(pixelValue);
if (redValue > hi) hi = redValue;
if (greenValue > hi) hi = greenValue;
if (blueValue > hi) hi = blueValue;
if (redValue < lo) lo = redValue;
if (greenValue < lo) lo = greenValue;
if (blueValue < lo) lo = blueValue;
}
}
if(hi!=lo)
{
for(int x=0; x<img.SX; x++)
{
for(int y=0; y<img.SY; y++)
{
int pixelValue = *(img.BASE + x + y*img.PITCH);
*(img.BASE + x + y*img.PITCH) = makeRGB((255 * (getR(pixelValue) - lo))/(hi-lo),
(255 * (getV(pixelValue) - lo))/(hi-lo),
(255 * (getB(pixelValue) - lo))/(hi-lo));
}
}
}
}
void getMvtVectorsMap(MAP& mvtMap, MAP& srcMap, int critere, int blocSize, int windowSize, int blur)
{
//v<>rification de la validit<69> des param<61>tres
if(critere<=0 || critere>3 || windowSize <=0 || blocSize <=0 || blur<0 || blur>2)
return;
//simplification de variables
int sx = srcMap.SX;
int sy = srcMap.SY;
int baseSize = sx*sy*sizeof(s32);
//initialisations
//-> cr<63>ation des Maps utiles
static MAP tmpMap = {NULL,NULL,0,0,0};
static MAP srcMapBlurred = {NULL,NULL,0,0,0};
static MAP prvMapBlurred = {NULL,NULL,0,0,0};
//-> v<>rification du changement de tailles des Maps et r<>allocation <20>ventuelle de celles-ci
if(baseSize != mvtMap.SX*mvtMap.SY*sizeof(s32))
{
CC_free(tmpMap.BASE);
tmpMap.BASE = NULL;
}
//-> initialisation des Maps utiles
if (tmpMap.BASE == NULL)
{
CC_free(mvtMap.BASE);
CC_free(tmpMap.BASE);
CC_free(srcMapBlurred.BASE);
CC_free(prvMapBlurred.BASE);
mvtMap = tmpMap = srcMapBlurred = prvMapBlurred = srcMap;
mvtMap.BASE = (s32*)CC_malloc(baseSize);
tmpMap.BASE = (s32*)CC_malloc(baseSize);
srcMapBlurred.BASE = (s32*)CC_malloc(baseSize);
prvMapBlurred.BASE = (s32*)CC_malloc(baseSize);
}
//r<>cup<75>ration des vecteurs mouvement
else
{
//-> blur des Maps src et prv
if(blur)
{
if(blur==1)
{
filterImgRVB(srcMapBlurred, srcMap, tmpMap);//donne une image en RVB <20> partir d'une en RVB
}
else
{
COPY_BW(&srcMap, &srcMapBlurred);
LF_GaussianFilter(&srcMapBlurred, &srcMapBlurred, &tmpMap, 1, 3);//donne une image en BW <20> partir d'une en BW
}
}
//TODO : calcul d'erreur diff<66>rent selon si on travaille sur une image blur<75>e en niveaux de gris ou en couleur
//TODO : demander pour meilleur filtre pour image RGB de webcam dans Pandore <20> Fourey
//TODO : explorer le code de Gimp pour trouver le meilleur d<>bruiteur RGB
else memcpy(srcMapBlurred.BASE, srcMap.BASE, baseSize);
//-> d<>finition du vecteur d<>placement <20> trouver
int vx, vy;
//-> mise <20> z<>ro de la Map des vecteurs Mvt
memset(mvtMap.BASE, 0, baseSize);
memcpy(mvtMap.BASE, srcMap.BASE, baseSize); // <- TO DELETE
//-> recherche des blocs correspondants aux blocs de l'image courante de la source dans son image pr<70>c<EFBFBD>dente
// par parcours des blocs de l'image source courante
for(int i=0; i<sx; i+=blocSize)
{
for(int j=0; j<sy; j+=blocSize)
{
//d<>claration des variables utiles pour l'erreur
int error, errorMax, errorMin;
//calcul de errorMax selon le crit<69>re
switch(critere)
{
case 1: //pour le crit<69>re SSD
errorMax = (256*256)*3*(blocSize*blocSize)+1;
break;
case 2: //pour le crit<69>re SAD
errorMax = (256)*3*(blocSize*blocSize)+1;
break;
case 3: //pour le crit<69>re (min+max)/2
errorMax = (256)*3*(blocSize*blocSize)+1;
break;
}
errorMin = errorMax;
//recherche dans une fen<65>tre du bloc correspondant au bloc courant
vx = vy = windowSize+1;
for(int dx=-windowSize/2; dx<windowSize/2; dx+=windowSize/2/6)
{
for(int dy=-windowSize/2; dy<windowSize/2; dy+=windowSize/2/6)
{
//v<>rification de la pr<70>sence de coordonn<6E>es <20> l'int<6E>rieur des dimensions de l'image
if(hold(i+dx, j+dy, sx, sy) && hold(i+dx+blocSize-1, j+dy+blocSize-1, sx, sy))
{
//calcul de l'erreur sur le bloc test<73> pour un crit<69>re donn<6E>
error = 0;
int currentPixel, previousPixel;
switch(critere)
{
case 1: //utilisation du crit<69>re SSD
for(int px=0; px<blocSize; px++)
{
for(int py=0; py<blocSize; py++)
{
//r<>cup<75>ration des pixels <20> comparer
currentPixel = *(prvMapBlurred.BASE + (i+px) + (j+py)*prvMapBlurred.PITCH);
previousPixel = *(srcMapBlurred.BASE + (i+dx+px) + (j+dy+py)*srcMapBlurred.PITCH);
//calcul de l'erreur
error += (getR(currentPixel) - getR(previousPixel))
* (getR(currentPixel) - getR(previousPixel))
+ (getV(currentPixel) - getV(previousPixel))
* (getV(currentPixel) - getV(previousPixel))
+ (getB(currentPixel) - getB(previousPixel))
* (getB(currentPixel) - getB(previousPixel));
}
}
break;
case 2: //utilisation du crit<69>re SAD
for(int px=0; px<blocSize; px++)
{
for(int py=0; py<blocSize; py++)
{
//r<>cup<75>ration des pixels <20> comparer
currentPixel = *(prvMapBlurred.BASE + (i+px) + (j+py)*prvMapBlurred.PITCH);
previousPixel = *(srcMapBlurred.BASE + (i+dx+px) + (j+dy+py)*srcMapBlurred.PITCH);
//calcul de l'erreur
error += abs(getR(currentPixel) - getR(previousPixel))
+ abs(getV(currentPixel) - getV(previousPixel))
+ abs(getB(currentPixel) - getB(previousPixel));
}
}
break;
case 3: //utilisation du crit<69>re (min+max)/2
int sumPixelC,sumPixelP;
int minRC, minVC, minBC, maxRC, maxVC, maxBC;
int minRP, minVP, minBP, maxRP, maxVP, maxBP;
minRC = minVC = minBC = maxRC = maxVC = maxBC = 256;
minRP = minVP = minBP = maxRP = maxVP = maxBP = 256;
for(int px=0; px<blocSize; px++)
{
for(int py=0; py<blocSize; py++)
{
//r<>cup<75>ration des pixels <20> comparer
currentPixel = *(prvMapBlurred.BASE + (i+px) + (j+py)*prvMapBlurred.PITCH);
previousPixel = *(srcMapBlurred.BASE + (i+dx+px) + (j+dy+py)*srcMapBlurred.PITCH);
//calcul de l'erreur
sumPixelC = getR(currentPixel) + getV(currentPixel)+ getB(currentPixel);
sumPixelP = getR(previousPixel) + getV(previousPixel) + getB(previousPixel);
if((sumPixelC>maxRC+maxVC+maxBC))
{
maxRC = getR(currentPixel);
maxVC = getV(currentPixel);
maxBC = getB(currentPixel);
}
if((sumPixelC<minRC+minVC+minBC))
{
minRC = getR(currentPixel);
minVC = getV(currentPixel);
minBC = getB(currentPixel);
}
if((sumPixelP>maxRP+maxVP+maxBP))
{
maxRP = getR(previousPixel);
maxVP = getV(previousPixel);
maxBP = getB(previousPixel);
}
if((sumPixelP<minRP+minVP+minBP))
{
minRP = getR(previousPixel);
minVP = getV(previousPixel);
minBP = getB(previousPixel);
}
}
}
int moyR = ((minRC+maxRC) - (minRP+maxRP))/2;
int moyV = ((minVC+maxVC) - (minVP+maxVP))/2;
int moyB = ((minBC+maxBC) - (minBP+maxBP))/2;
error = abs(moyR+moyV+moyB);
break;
}
//m<>morisation du vecteur d<>placement obtenu dans mvtMap si l'erreur est plus petite
if(error<errorMin || (error==errorMin && dx*dx+dy*dy<vx*vx+vy*vy))
{
vx = dx;
vy = dy;
errorMin = error;
}
}
}
}
//<2F>criture du vecteur mouvement obtenu dans mvtMap
if(vx != windowSize+1)
drawLine(mvtMap.BASE, i+blocSize/2,
i+blocSize/2+vx, j+blocSize/2,
j+blocSize/2+vy, mvtMap.PITCH,
makeRGB(100+155*errorMin/errorMax, 0, 0));
else
drawLine(mvtMap.BASE, i+blocSize/2, i+blocSize/2, j+blocSize/2, j+blocSize/2, mvtMap.PITCH, 0xff0000);
}
}
}
//sauvegarde de la Map source en Map pr<70>c<EFBFBD>dente pour le passage suivant dans la fonction
memcpy(prvMapBlurred.BASE, srcMapBlurred.BASE, baseSize);
}
void showMvt(WORKINGSPACE* WSPC, MAP &DESTMAP, MAP &SOURCEMAP, int SADDeltaPerPx, int blockSize)
{
if(WSPC->PREVIOUSMAP == NULL || WSPC->PREVIOUSMAP->PITCH!=SOURCEMAP.PITCH) WSPC->bFirstFrame = 1;
if(WSPC->bFirstFrame)
{
WSPC->HANDWORK[0] = (s32*)ZeroAlloc(SOURCEMAP.SY*SOURCEMAP.SX*sizeof(s32)); //tmp
WSPC->HANDWORK[1] = (s32*)ZeroAlloc(SOURCEMAP.SY*SOURCEMAP.SX*sizeof(s32)); //copie de source.base
WSPC->HANDWORK[2] = (s32*)ZeroAlloc(SOURCEMAP.SY*SOURCEMAP.SX*sizeof(s32)); //tmp pour filtre
WSPC->HANDWORK[3] = (s32*)ZeroAlloc(SOURCEMAP.SY*SOURCEMAP.SX*sizeof(s32)); //tmp pour filtre
WSPC->PREVIOUSMAP = (MAP*)ZeroAlloc(sizeof(SOURCEMAP));
WSPC->PREVIOUSMAP->BASE = (s32*)ZeroAlloc(SOURCEMAP.SY*SOURCEMAP.SX*sizeof(s32));
WSPC->PREVIOUSMAP->SX = SOURCEMAP.SX;
WSPC->PREVIOUSMAP->SY = SOURCEMAP.SY;
WSPC->PREVIOUSMAP->PITCH = SOURCEMAP.PITCH;
}
int Height = WSPC->PREVIOUSMAP->SY;
int Width = WSPC->PREVIOUSMAP->SX;
int PITCH = WSPC->PREVIOUSMAP->PITCH;
memcpy(WSPC->HANDWORK[0], SOURCEMAP.BASE, Height*Width*sizeof(s32));
memcpy(WSPC->HANDWORK[1], SOURCEMAP.BASE, Height*Width*sizeof(s32));
memset(DESTMAP.BASE, 0, Height*Width*sizeof(s32));
if(!WSPC->bFirstFrame)
{
int tbloc = blockSize;
int blocH = tbloc;
int blocW = tbloc;
int SAD;
int seuilSAD;
int px, py;
int k,l;
s32 * imC = WSPC->HANDWORK[1];
s32 * imP = WSPC->PREVIOUSMAP->BASE;
s32 * imCg = WSPC->HANDWORK[2];
s32 * imPg = WSPC->HANDWORK[3];
//passage en niveau de gris
for(px=0;px<Width;px++)
for(py=0;py<Height;py++)
*(imCg + px + py*PITCH) = getY(*(imC + px + py*PITCH));
for(px=0;px<Width;px++)
for(py=0;py<Height;py++)
*(imPg + px + py*PITCH) = getY(*(imP + px + py*PITCH));
//estimation du mvt
for(k=0;k<Height;k=k+tbloc)
{
blocW = tbloc;
for(l=0;l<Width;l=l+tbloc)
{
SAD = 0;
if(k==(Height/tbloc)*tbloc) blocH = Height - (Height/tbloc)*tbloc;
if(l==(Width/tbloc)*tbloc) blocW = Width - (Width/tbloc)*tbloc;
seuilSAD = blocH*blocW*SADDeltaPerPx;
for(py=k;py<blocH+k; py++)
for(px=l;px<blocW+l; px++)
SAD += abs(*(imPg + px + py*PITCH) - *(imCg + px +py*PITCH));
for(py=k;py<blocH+k; py++)
for(px=l;px<blocW+l; px++)
{
if (SAD > seuilSAD) //si bloc mobile
*(DESTMAP.BASE + px + py*PITCH) = -1;
}
}
}
}
WSPC->bFirstFrame = 0;
memcpy(WSPC->PREVIOUSMAP->BASE, WSPC->HANDWORK[0], Height*Width*sizeof(s32));
}
void estimMvt(s32 * im1, s32 * im2, s32 * imd, int PITCH, int Height, int Width)
{
int tbloc = 8;
int dmax = 8;
int px, py, qx, qy;
int u,v,umin,vmin,k,l;
int Xbloc,Ybloc,SADmin;
int SAD;
Ybloc = Height / tbloc ; //Nombre de bloc suivant Y
Xbloc = Width / tbloc ; //Nombre de bloc suivant X
for(k=0;k<Height-tbloc;k=k+tbloc)
for(l=0;l<Width-tbloc;l=l+tbloc)
{
//D<>claration du SAD min
SADmin= tbloc*tbloc*255;
//printf("Coordonnees bloc :%d, %d\n", l, k);
//Calcul du SAD
// u et v vecteurs deplacement
for (u=-dmax ; u<=dmax ; u++)
for (v=-dmax ; v<=dmax ; v++)
{
SAD = 0;
if ((k+v)>-1 && (k+v+tbloc)<Height && (l+u)>-1 && (l+u+tbloc)<Width)
{
for(py=k;py<tbloc+k; py++)
for(px=l;px<tbloc+l; px++)
SAD += abs(getY(*(im2 + px+u +(py+v)*PITCH)) - getY(*(im1 + px +(py)*PITCH)));
//Tester si la SAD est min => recup de u et v
if (SAD < SADmin)
{
SADmin=SAD;
umin = u ;
vmin = v;
}
}
}
px = l;
py = k;
qx= px+umin;
qy= py+vmin;
drawLine(imd, px+tbloc/2, qx+tbloc/2, py+tbloc/2, qy+tbloc/2, PITCH, 255);
}
}
void estimMvtRap(s32 * im1, s32 * im2, s32 * imd, int PITCH, int Height, int Width)
{
int tbloc = 16;
int dmax = 10;
int SEUIL = 3;
int px, py, qx, qy;
int u,v,k,l;
int umin=0,vmin=0,umin2=0,vmin2=0;
int Xbloc,Ybloc,SADmin;
int SAD;
Ybloc = Height / tbloc ; //Nombre de bloc suivant Y
Xbloc = Width / tbloc ; //Nombre de bloc suivant X
for(k=0;k<Height-tbloc;k=k+tbloc)
for(l=0;l<Width-tbloc;l=l+tbloc)
{
SADmin = 0;
for(py=k;py<tbloc+k; py++)
for(px=l;px<tbloc+l; px++)
{
SADmin += abs(getY(*(im2 + px + py*PITCH)) - getY(*(im1 + px +py*PITCH)));
}
umin = vmin = 0;
for (u=-dmax ; u<=dmax ; u+=dmax)
for (v=-dmax ; v<=dmax ; v+=dmax)
{
SAD=0;
if ((k+v)>-1 && (k+v+tbloc)<Height && (l+u)>-1 && (l+u+tbloc)<Width)
{
for(py=k;py<tbloc+k; py++)
for(px=l;px<tbloc+l; px++)
{
SAD += abs(getY(*(im2 + px+u +(py+v)*PITCH)) - getY(*(im1 + px +(py)*PITCH)));
}
//Tester si la SAD est min => recup de u et v
if (SADmin-SAD > SADmin/SEUIL)
{
SADmin=SAD;
umin = u ;
vmin = v;
}
}
}
umin2 = vmin2 = 0;
for (u=-dmax/2 ; u<=dmax/2 ; u+=dmax/2)
for (v=-dmax/2 ; v<=dmax/2 ; v+=dmax/2)
{
SAD=0;
if ((k+vmin+v)>-1 && (k+vmin+v+tbloc)<Height && (l+umin+u)>-1 && (l+umin+u+tbloc)<Width)
{
for(py=k;py<tbloc+k; py++)
for(px=l;px<tbloc+l; px++)
{
SAD += abs(getY(*(im2 + px+umin+u +(py+vmin+v)*PITCH)) - getY(*(im1 + px +(py)*PITCH)));
}
//Tester si la SAD est min => recup de u et v
if (SADmin-SAD > SADmin/SEUIL)
{
SADmin=SAD;
umin2 = u ;
vmin2 = v;
}
}
}
px = l;
py = k;
qx= px+umin+umin2;
qy= py+vmin+vmin2;
drawLine(imd, px+tbloc/2, qx+tbloc/2, py+tbloc/2, qy+tbloc/2, PITCH, 255);
//*(imd + px + py*PITCH) = 0xff0000;
//*(imd + px + tbloc + py*PITCH) = 0xff0000;
/*
if(px==qx && py==qy)
{
for(py=k;py<tbloc+k; py++)
for(px=l;px<tbloc+l; px++)
{
*(imd + px + py*PITCH) = 0;
}
}
//*/
}
}
void estimMvtRap2(WORKINGSPACE* WSPC, MAP &SOURCEMAP)
{
s32 * imC = WSPC->HANDWORK[0];
s32 * imP = WSPC->PREVIOUSMAP->BASE;
s32 * imD = SOURCEMAP.BASE;
s32 * belongToHand = WSPC->HANDWORK[1];
s32 * imRef = WSPC->HANDWORK[2];
int PITCH = SOURCEMAP.PITCH;
int Height = SOURCEMAP.SY;
int Width = SOURCEMAP.SX;
int tbloc = 8;
int CbMin = 104;
int CbMax = 131;
int CrMin = 134;
int CrMax = 161;
int SADDeltaPerPx = 10;
int SADRefDeltaPerPx = 10;
double PropMinOfSkinColorPx = (double)20/100.0;
int blocH = tbloc;
int blocW = tbloc;
int SAD, nbSkinPx, SADRef;
int seuilSAD, seuilSADRef;
int nbSkinColorPxMin;
int px, py;
int k,l;
s32* imCg = WSPC->HANDWORK[3];
s32* imPg = WSPC->HANDWORK[4];
s32* imRefg = WSPC->HANDWORK[5];
filterImg(imCg, imC, PITCH, Height, Width);
filterImg(imPg, imP, PITCH, Height, Width);
filterImg(imRefg, imRef, PITCH, Height, Width);
for(k=0;k<Height;k=k+tbloc)
{
for(l=0;l<Width;l=l+tbloc)
{
SADRef = SAD = nbSkinPx = 0;
if(k==(Height/tbloc)*tbloc) blocH = Height - (Height/tbloc)*tbloc;
if(l==(Width/tbloc)*tbloc) blocW = Width - (Width/tbloc)*tbloc;
seuilSAD = blocH*blocW*SADDeltaPerPx;
seuilSADRef = blocH*blocW*SADRefDeltaPerPx;
nbSkinColorPxMin = (int)((float)(blocH*blocW)*PropMinOfSkinColorPx);
for(py=k;py<blocH+k; py++)
for(px=l;px<blocW+l; px++)
{
//*
SAD += abs(*(imPg + px + py*PITCH) - *(imCg + px +py*PITCH));
if(isOfSkinColor(*(imC + px + py*PITCH), 0, 255, CbMin, CbMax, CrMin, CrMax)) nbSkinPx++;
SADRef += abs(*(imRefg + px + py*PITCH) - *(imCg + px +py*PITCH));
//*/
}
for(py=k;py<blocH+k; py++)
for(px=l;px<blocW+l; px++)
{
/*
int coul = (SADRef)<<16; //en rouge
if(SADRef < seuilSADRef) coul = SADRef; //en bleu
*(imD + px + py*PITCH) = coul;
//*/
/*
int coul = (SAD)<<16;
if(SAD < seuilSAD) coul = SAD;
*(imD + px + py*PITCH) = coul;
//*/
//*
if (SAD > seuilSAD) //si bloc mobile
{
if(nbSkinPx>nbSkinColorPxMin && SADRef > seuilSADRef) //si un bloc avec couleur de peau
*(belongToHand + px + py*PITCH) = 1; //alors c'est un bloc avec peau
else
*(belongToHand + px + py*PITCH) = 0; //sinon c'est un bloc sans peau
}
else
{
if(*(belongToHand + px + py*PITCH)==1 && SADRef < seuilSADRef) //si c'est un bloc du fond qui a <20>t<EFBFBD> mobile
*(belongToHand + px + py*PITCH) = 0;
}
if(*(belongToHand + px + py*PITCH)==1 && (isOfSkinColor(*(imC + px + py*PITCH), 0, 255, CbMin, CbMax, CrMin, CrMax))) //si c'est un bloc avec peau
*(imD + px + py*PITCH) |= 255<<8; //on l'affiche en vert
//*/
}
}
}
//spreadPx(imD, Width/2, Height/2, PITCH, Height, Width);
//MC_GC2(imC, PITCH, Width, Height);
//memcpy(imD, imC, Width*Height*sizeof(s32));
/*
char * maxS = (char *)ZeroAlloc(10*sizeof(char));
sprintf(maxS, "%d", max);
DRawTEXT_Soft_B((unsigned char*)maxS, (unsigned int*)imD, 10, 50, PITCH , Height , 255<<8);
//*/
}
void trackMouth(s32 * dest, s32 * reverse, s32 * imgReverseRef, bool rebuildRefPatches, float maxTolerancePercentage, int* posPtsRef, int sx, int sy, int pitch)
{
//param<61>tres
int pointRefColor = 0xff8800;
int pointRefColor2 = 0x0000ff;
int meshColor = 0x00ff00;
int patchSideSize = 8;
int researchWindowSize = 40;
int boxColor[4] = {0x00ffff, 0x00ff00, 0xff0000, 0xff00ff};
//tableau pour la m<>morisation des positions des points de r<>f<EFBFBD>rence initiaux
static int initRefPtsPos[8];
static int lastPosPts[8];
//si une MAP est manquante, on quitte la fonction
if(dest==NULL || reverse==NULL || imgReverseRef==NULL || posPtsRef==NULL)
return;
//copie du reverse dans le media destination
memcpy(dest, reverse, sx*sy*sizeof(s32));
//sauvegarde des MAPs de reverse d'origine avant leur blur
static s32* mapTmp = (s32*)CC_malloc(sx*sy*sizeof(s32));
static s32* mapTmp2 = (s32*)CC_malloc(sx*sy*sizeof(s32));
memcpy(mapTmp, reverse, sx*sy*sizeof(s32));
memcpy(mapTmp2, imgReverseRef, sx*sy*sizeof(s32));
//TODO : enlever filtrage ???
filterImgRVB(reverse, reverse, pitch, sy, sx);
filterImgRVB(imgReverseRef, imgReverseRef, pitch, sy, sx);
static bool patchNotCreated = true;
static s32* patchComp = (s32*)CC_malloc(patchSideSize*patchSideSize*sizeof(s32));
static u8* compPtsRef = (u8*)CC_malloc(4*3*8*sizeof(u8));
//cr<63>ation des signatures des points de r<>f<EFBFBD>rence
if(patchNotCreated || rebuildRefPatches)
{
memset(patchComp, 0, patchSideSize*patchSideSize*sizeof(s32));
memset(compPtsRef, 0, 4*3*8*sizeof(u8));
memcpy(initRefPtsPos, posPtsRef, 8*sizeof(int));
memcpy(lastPosPts, posPtsRef, 8*sizeof(int));
patchNotCreated = false;
s32 compValue;
int pxToCompare;
int dx;
int dy;
int dx2;
int dy2;
int indComp = patchSideSize*patchSideSize;
srand(time(NULL));
while(indComp--)
{
compValue = (rand()%256)*(rand()%256)*(rand()%256);
*(patchComp + indComp) = compValue;
for(int i=0; i<4; i++)
{
dx = indComp/8;
dy = indComp%8;
dx2 = indComp/8 + (((((i+3)%4)*4)%8)-8) * (int)(((i+3)%4)!=0);
dy2 = indComp%8 + (((i*4)%8)-8) * (int)(i!=0);
pxToCompare = *(imgReverseRef + (posPtsRef[2*i]+dx2) + (posPtsRef[2*i+1]+dy2)*pitch);
//comparaison des 3 composantes RGB aux valeurs du patch
*(compPtsRef + patchSideSize*0 + dx +patchSideSize*3*i) |= ((u8)(((u32)(getR(pxToCompare) - getR(compValue)))>>31))<<dy;
*(compPtsRef + patchSideSize*1 + dx +patchSideSize*3*i) |= ((u8)(((u32)(getV(pxToCompare) - getV(compValue)))>>31))<<dy;
*(compPtsRef + patchSideSize*2 + dx +patchSideSize*3*i) |= ((u8)(((u32)(getB(pxToCompare) - getB(compValue)))>>31))<<dy;
}
}
}
//comparaison des boites inscrites dans la fen<65>tre de recherche aux boites de r<>f<EFBFBD>rence
//initialisations
int px[4];
int py[4];
int errorMin[4];
int size = researchWindowSize/2;
int bestx[4];
int besty[4];
for(int i=0; i<4; i++)
{
//positions pr<70>c<EFBFBD>dentes des boites des points track<63>s
px[i] = posPtsRef[2*i] + (((((i+3)%4)*4)%8)-8) * (int)(((i+3)%4)!=0);
py[i] = posPtsRef[2*i+1] + (((i*4)%8)-8) * (int)(i!=0);
//autre version
/*
px[i] = lastPosPts[2*i] + (((((i+3)%4)*4)%8)-8) * (int)(((i+3)%4)!=0);
py[i] = lastPosPts[2*i+1] + (((i*4)%8)-8) * (int)(i!=0);
*/
//initialisation des erreurs minimales
errorMin[i] = patchSideSize*patchSideSize*3+1;
//meilleures nouvelles positions des boites pour les points track<63>s
bestx[i] = px[i];
besty[i] = py[i];
/*/
//dessin des fenetres de recherche autour des posPtsRef
//if(hold(px[i]+size, py[i]+size, sx, sy) && hold(px[i]-size, py[i]-size, sx, sy))
{
drawLine(dest, px[i]+size, px[i]-size, py[i]-size, py[i]-size, pitch, boxColor[i]);
drawLine(dest, px[i]+size, px[i]+size, py[i]-size, py[i]+size, pitch, boxColor[i]);
drawLine(dest, px[i]+size, px[i]-size, py[i]+size, py[i]+size, pitch, boxColor[i]);
drawLine(dest, px[i]-size, px[i]-size, py[i]+size, py[i]-size, pitch, boxColor[i]);
}
//*/
}
//traitement
int pxToCompare;
int compValue;
int dx;
int dy;
u8* signature = (u8*)CC_malloc(3*8*sizeof(u8));
double signeDiff;
int toAdd;
for(int i=0; i<4; i++)
{
for(int y=py[i]-size; y<py[i]+size-patchSideSize; y++)
{
for(int x=px[i]-size; x<px[i]+size-patchSideSize; x++)
{
if(hold(x, y, sx, sy) && hold(x+patchSideSize, y+patchSideSize, sx, sy))
{
//cr<63>ation de la signature du patch
memset(signature, 0, 3*8*sizeof(u8));
int indComp = patchSideSize*patchSideSize;
while(indComp--)
{
dx = indComp/8;
dy = indComp%8;
pxToCompare = *(reverse + (x+dx) + (y+dy)*pitch);
compValue = *(patchComp + indComp);
//comparaison des 3 composantes RGB aux valeurs du patch
*(signature + patchSideSize*0 + dx) |= ((u8)(((u32)(getR(pxToCompare) - getR(compValue)))>>31))<<dy;
*(signature + patchSideSize*1 + dx) |= ((u8)(((u32)(getV(pxToCompare) - getV(compValue)))>>31))<<dy;
*(signature + patchSideSize*2 + dx) |= ((u8)(((u32)(getB(pxToCompare) - getB(compValue)))>>31))<<dy;
}
//recherche du patch d'erreur minimum pour les 4 points de r<>f<EFBFBD>rence
int error = 0;
for(dx=0; dx<8; dx++)
{
error += GetBitNumber((u32)((*(compPtsRef + patchSideSize*0 + dx +patchSideSize*3*i))^(*(signature + patchSideSize*0 + dx))))+
GetBitNumber((u32)((*(compPtsRef + patchSideSize*1 + dx +patchSideSize*3*i))^(*(signature + patchSideSize*1 + dx))))+
GetBitNumber((u32)((*(compPtsRef + patchSideSize*2 + dx +patchSideSize*3*i))^(*(signature + patchSideSize*2 + dx))));
}
//r<>cup<75>rer le bon patch selon son error
if( (error<=patchSideSize*patchSideSize*maxTolerancePercentage) &&
((error<errorMin[i]) ||
(error==errorMin[i] && ((x-px[i])*(x-px[i])+(y-py[i])*(y-py[i])) <
((bestx[i]-px[i])*(bestx[i]-px[i])+(besty[i]-py[i])*(besty[i]-py[i])))) )
{
//emp<6D>cher les inversions de position entre les points gauche et droite, et haut et bas
if(i%2==0)
{
toAdd = (((((i+2)%4)*4)%8)-8) * (int)(((i+2)%4)!=0)
- (((i*4)%8)-8) * (int)(i!=0);
signeDiff = (y-py[(i+2)%4])/(i-((i+2)%4));
}
else
{
toAdd = (((((((i+2)%4)+3)%4)*4)%8)-8) * (int)(((((i+2)%4)+3)%4)!=0)
- (((((i+3)%4)*4)%8)-8) * (int)(((i+3)%4)!=0);
signeDiff = (x-px[(i+2)%4])/(i-((i+2)%4));
}
if(signeDiff+toAdd<0)
{
bestx[i] = x;
besty[i] = y;
errorMin[i] = error;
posPtsRef[2*i] = x - (((((i+3)%4)*4)%8)-8) * (int)(((i+3)%4)!=0);
posPtsRef[2*i+1] = y - (((i*4)%8)-8) * (int)(i!=0);
}
}
}
}
}
}
CC_free(signature);
signature = 0;
//affichage des 4 boites de r<>f<EFBFBD>rence servant <20> la comparaison
for(int i=0; i<4; i++)
{
if(errorMin[i]>patchSideSize*patchSideSize*maxTolerancePercentage)
{
boxColor[i] = 0xffff00;
posPtsRef[2*i] = lastPosPts[2*i];
posPtsRef[2*i+1] = lastPosPts[2*i+1];
}
int dx = (((((i+3)%4)*4)%8)-8) * (int)(((i+3)%4)!=0);
int dy = (((i*4)%8)-8) * (int)(i!=0);
if(hold(posPtsRef[2*i]+dx, posPtsRef[2*i+1]+dy, sx, sy))
{
drawLine(dest, posPtsRef[2*i]+dx, posPtsRef[2*i]+dx+8, posPtsRef[2*i+1]+dy+8, posPtsRef[2*i+1]+dy+8, pitch, boxColor[i]);
drawLine(dest, posPtsRef[2*i]+dx, posPtsRef[2*i]+dx, posPtsRef[2*i+1]+dy+8, posPtsRef[2*i+1]+dy, pitch, boxColor[i]);
drawLine(dest, posPtsRef[2*i]+dx, posPtsRef[2*i]+dx+8, posPtsRef[2*i+1]+dy, posPtsRef[2*i+1]+dy, pitch, boxColor[i]);
drawLine(dest, posPtsRef[2*i]+dx+8, posPtsRef[2*i]+dx+8, posPtsRef[2*i+1]+dy, posPtsRef[2*i+1]+dy+8, pitch, boxColor[i]);
}
}
{
/*
//affichage des meshes de la bouche
int mouthWidth = 4;
int coul = meshColor;
int xa, xb, ya, yb;
int hx = posPtsRef[0];
int hy = posPtsRef[1];
int rx = posPtsRef[2];
int ry = posPtsRef[3];
int bx = posPtsRef[4];
int by = posPtsRef[5];
int lx = posPtsRef[6];
int ly = posPtsRef[7];
xa = lx; xb = lx - mouthWidth; ya = ly; yb = ly;
if(hold(xa,ya,sx,sy) && hold(xb,yb,sx,sy))
drawLine(dest, xa, xb, ya, yb, pitch, coul);
xa = rx; xb = rx + mouthWidth; ya = ry; yb = ry;
if(hold(xa,ya,sx,sy) && hold(xb,yb,sx,sy))
drawLine(dest, xa, xb, ya, yb, pitch, coul);
xa = hx; xb = hx; ya = hy; yb = hy + mouthWidth;
if(hold(xa,ya,sx,sy) && hold(xb,yb,sx,sy))
drawLine(dest, xa, xb, ya, yb, pitch, coul);
xa = bx; xb = bx; ya = by; yb = by - mouthWidth;
if(hold(xa,ya,sx,sy) && hold(xb,yb,sx,sy))
drawLine(dest, xa, xb, ya, yb, pitch, coul);
xa = bx; xb = bx+(rx-bx)*2/3; ya = by - mouthWidth; yb = by - mouthWidth;
if(hold(xa,ya,sx,sy) && hold(xb,yb,sx,sy))
drawLine(dest, xa, xb, ya, yb, pitch, coul);
xa = rx + mouthWidth; xb = bx+(rx-bx)*2/3; ya = ry; yb = by - mouthWidth;
if(hold(xa,ya,sx,sy) && hold(xb,yb,sx,sy))
drawLine(dest, xa, xb, ya, yb, pitch, coul);
xa = bx; xb = bx+(lx-bx)*2/3; ya = by - mouthWidth; yb = by - mouthWidth;
if(hold(xa,ya,sx,sy) && hold(xb,yb,sx,sy))
drawLine(dest, xa, xb, ya, yb, pitch, coul);
xa = lx - mouthWidth; xb = bx+(lx-bx)*2/3; ya = ly; yb = by - mouthWidth;
if(hold(xa,ya,sx,sy) && hold(xb,yb,sx,sy))
drawLine(dest, xa, xb, ya, yb, pitch, coul);
xa = hx; xb = hx+(rx-hx)*1/3; ya = hy + mouthWidth; yb = hy + mouthWidth;
if(hold(xa,ya,sx,sy) && hold(xb,yb,sx,sy))
drawLine(dest, xa, xb, ya, yb, pitch, coul);
xa = rx + mouthWidth; xb = hx+(rx-hx)*1/3; ya = ry; yb = hy + mouthWidth;
if(hold(xa,ya,sx,sy) && hold(xb,yb,sx,sy))
drawLine(dest, xa, xb, ya, yb, pitch, coul);
xa = hx; xb = hx+(lx-hx)*1/3; ya = hy + mouthWidth; yb = hy + mouthWidth;
if(hold(xa,ya,sx,sy) && hold(xb,yb,sx,sy))
drawLine(dest, xa, xb, ya, yb, pitch, coul);
xa = lx - mouthWidth; xb = hx+(lx-hx)*1/3; ya = ly; yb = hy + mouthWidth;
if(hold(xa,ya,sx,sy) && hold(xb,yb,sx,sy))
drawLine(dest, xa, xb, ya, yb, pitch, coul);
*/
}
{
/*
//affichage des lignes entre les points de contraintes
for(int i=0; i<4; i++)
{
drawLine(dest, posPtsRef[(2*i)%8], posPtsRef[(2*i+2)%8], posPtsRef[(2*i+1)%8], posPtsRef[(2*i+2+1)%8], pitch, meshColor);
}
*/
}
//affichage d'une croix sur les points de contraintes
for(int i=0; i<4; i++)
{
*(dest + posPtsRef[2*i] + posPtsRef[2*i+1]*pitch) = pointRefColor;
*(dest + posPtsRef[2*i]-1 + posPtsRef[2*i+1]*pitch) = pointRefColor;
*(dest + posPtsRef[2*i]+1 + posPtsRef[2*i+1]*pitch) = pointRefColor;
*(dest + posPtsRef[2*i] + (posPtsRef[2*i+1]-1)*pitch) = pointRefColor;
*(dest + posPtsRef[2*i] + (posPtsRef[2*i+1]+1)*pitch) = pointRefColor;
}
//affichage d'une croix sur les points de contraintes de r<>f<EFBFBD>rence
for(int i=0; i<4; i++)
{
*(dest + initRefPtsPos[2*i] + initRefPtsPos[2*i+1]*pitch) = pointRefColor2;
*(dest + initRefPtsPos[2*i]-1 + initRefPtsPos[2*i+1]*pitch) = boxColor[i];
*(dest + initRefPtsPos[2*i]+1 + initRefPtsPos[2*i+1]*pitch) = boxColor[i];
*(dest + initRefPtsPos[2*i] + (initRefPtsPos[2*i+1]-1)*pitch) = boxColor[i];
*(dest + initRefPtsPos[2*i] + (initRefPtsPos[2*i+1]+1)*pitch) = boxColor[i];
}
//memorisation des dernieres positions des points
memcpy(lastPosPts, posPtsRef, 8*sizeof(int));
//restitution des Maps de reverse d'origine
memcpy(reverse, mapTmp, sx*sy*sizeof(s32));
memcpy(imgReverseRef, mapTmp2, sx*sy*sizeof(s32));
}
void showFingerPuppet(MATRIX camMatrix, float camFocale, SmallScene * SmSc, s32 * dest, s32 * reverse, s32 * mask, s32 * src, int SX, int SY, int PITCH, bool sizeChanged)
{
static s32* XStack = (s32*)CC_malloc(SY*SX*sizeof(s32));
static s32* YStack = (s32*)CC_malloc(SY*SX*sizeof(s32));
static s32* visited = (s32*)CC_malloc(SY*SX*sizeof(s32));
if(sizeChanged)
{
CC_free(XStack);
CC_free(YStack);
CC_free(visited);
XStack = (s32*)CC_malloc(SY*SX*sizeof(s32));
YStack = (s32*)CC_malloc(SY*SX*sizeof(s32));
visited = (s32*)CC_malloc(SY*SX*sizeof(s32));
}
memcpy(dest, mask, SX*SY*sizeof(s32));
/* Change WebCam Position Matrix */
MATRIX mFi;
char OBJECT2[] = "PLANE01.OBJ";
UnicID OBJECT = SmSc->ObjectNameDico.IsExist(OBJECT2);
if (OBJECT != -1)
{
int ObjID = SmSc->ObjectNameDico.mpst_Dico[OBJECT].AssociatedValue;
u32 Father = SmSc->ObjectsPtrs[ObjID]->FatherIndex;
//zoom
SmSc->ObjectsPtrs[ObjID]->GlobalMatrix.T.y = SmSc->ObjectsPtrs[ObjID]->OriginalGlobalMatrix.T.y - 0.250;
//etirement vertical
SmSc->ObjectsPtrs[ObjID]->GlobalMatrix.J.Normalize();
SmSc->ObjectsPtrs[ObjID]->GlobalMatrix.J *= 1.12;
SmSc->ObjectsPtrs[ObjID]->GlobalMatrix.I.Normalize();
SmSc->ObjectsPtrs[ObjID]->GlobalMatrix.I *= 0.99;
SmSc->ObjectsPtrs[Father]->GlobalMatrix.Inverse(mFi);
SmSc->ObjectsPtrs[ObjID]->LocalMatrix = SmSc->ObjectsPtrs[ObjID]->GlobalMatrix;
SmSc->ObjectsPtrs[ObjID]->LocalMatrix *= mFi;
}
//r<>cup<75>ration de la position de l'index
bool finger;
int maxLength = 40;
int maxWidth = 60;
int xFingerPos = -1;
int yFingerPos = -1;
int angleFinger = 0;
float coeffDir;
s32 * potentialFingersPosX = (s32*)CC_malloc(SX*SY*sizeof(s32));
s32 * potentialFingersPosY = (s32*)CC_malloc(SX*SY*sizeof(s32));
memset(potentialFingersPosX, 0, SX*SY*sizeof(s32));
memset(potentialFingersPosY, 0, SX*SY*sizeof(s32));
int nbPotentialFingersFound = 0;
for(int angle = 20; angle <= 180-20; angle+=3)
{
coeffDir = tan(angle*3.14/180.0);
for(int py=0; py<SY; py+=10)
{
for(int px=0; px<SX; px++)
{
int x = px;
int y = py;
float length = 0;
finger = true;
while(finger && length < maxLength)
{
if(x-maxWidth/2>=0 && x+maxWidth/2<SX && y>=0 && y<SY)
{
if(*(mask+x+maxWidth/2+y*PITCH)!=0) finger = false;
if(*(mask+x-maxWidth/2+y*PITCH)!=0) finger = false;
if(*(mask+x+maxWidth/16+y*PITCH)==0) finger = false;
if(*(mask+x+y*PITCH)==0) finger = false;
if(*(mask+x-maxWidth/16+y*PITCH)==0) finger = false;
}
else finger = false;
if(angle>45 && angle<180-45)
{
y += 3;
x = px + (int)((float)(y-py)/coeffDir);
length = sqrt((double)((float)(y-py)/coeffDir*(float)(y-py)/coeffDir+(y-py)*(y-py)));
}
else
{
if(coeffDir>0) x += 3;
else x -= 3;
y = py + (int)((float)(x-px)*coeffDir);
length = sqrt((double)((float)(x-px)*coeffDir*(float)(x-px)*coeffDir+(x-px)*(x-px)));
}
}
if(finger)
{
potentialFingersPosX[nbPotentialFingersFound] = px;
potentialFingersPosY[nbPotentialFingersFound] = py;
nbPotentialFingersFound++;
}
}
}
}
//camFocale = 1;
float headPosx = (camMatrix.T.x * camFocale)/camMatrix.T.z;
float headPosy = (camMatrix.T.y * camFocale)/camMatrix.T.z;
//d<>termination du doigt potentiel le plus gros
static s32* workBuffer1 = (s32*)CC_malloc(SY*SX*sizeof(s32));
static s32* workBuffer2 = (s32*)CC_malloc(SY*SX*sizeof(s32));
static s32* workBuffer3 = (s32*)CC_malloc(SY*SX*sizeof(s32));
if(sizeChanged)
{
CC_free(workBuffer1);
CC_free(workBuffer2);
CC_free(workBuffer3);
workBuffer1 = (s32*)CC_malloc(SY*SX*sizeof(s32));
workBuffer2 = (s32*)CC_malloc(SY*SX*sizeof(s32));
workBuffer3 = (s32*)CC_malloc(SY*SX*sizeof(s32));
}
memset(workBuffer1, 0, SX*SY*sizeof(s32));
memset(workBuffer2, 0, SX*SY*sizeof(s32));
memset(workBuffer3, 0, SX*SY*sizeof(s32));
memset(visited, 0, SX*SY*sizeof(s32));
for(int px=0; px<SX; px++)
for(int py=0; py<SY; py++)
{
*(visited + px + py*PITCH) = 0xffffffff ^ (*(mask + px + py*PITCH));
}
int size;
int indPF = 0;
int maxSize = 0;
while(potentialFingersPosX[indPF]!=0 || potentialFingersPosY[indPF]!=0)
{
int px = potentialFingersPosX[indPF];
int py = potentialFingersPosY[indPF];
//calcul de la position du centre de gravit<69> de la forme
int debOfStack = 0;
int endOfStack = 0;
memset(visited, 0, SY*SX*sizeof(s32));
memset(YStack, 0, SY*SX*sizeof(s32));
memset(XStack, 0, SY*SX*sizeof(s32));
*XStack = px;
*YStack = py;
int gravityCenterTempX = 0;
int gravityCenterTempY = 0;
int nbPixels = 0;
while(endOfStack>=debOfStack)
{
gravityCenterTempX += *(XStack+debOfStack);
gravityCenterTempY += *(YStack+debOfStack);
*(visited + *(XStack+debOfStack) + (*(YStack+debOfStack))*PITCH) = -1;
for(int x = -1; x < 2; x++)
for(int y = -1; y < 2; y++)
{
if(abs(x*y)!=1 && *(XStack+debOfStack)+x>=0 && *(YStack+debOfStack)+y>=0 && *(XStack+debOfStack)+x<SX && *(YStack+debOfStack)+y<SY)
{
if(*(visited + *(XStack+debOfStack) + x + (*(YStack+debOfStack) + y)*PITCH) != -1)
{
if(*(mask + *(XStack+debOfStack) + x + (*(YStack+debOfStack) + y)*PITCH) == -1)
{
*(visited + *(XStack+debOfStack) + x + (*(YStack+debOfStack) + y)*PITCH) = -1;
endOfStack++;
*(XStack+endOfStack) = *(XStack+debOfStack) + x;
*(YStack+endOfStack) = *(YStack+debOfStack) + y;
}
}
}
}
debOfStack++;
nbPixels = debOfStack;
}
gravityCenterTempX = gravityCenterTempX/nbPixels;
gravityCenterTempY = gravityCenterTempY/nbPixels;
if(abs((((float)gravityCenterTempX/352.0-(headPosx+1)/2)+1)/2)>0.2)
{
if(*(visited + px + py*PITCH)==-1)
{
size = spreadPx(visited, visited, px, py, PITCH, SY, SX, XStack, YStack);
if(size >= maxSize)
{
xFingerPos = px;
yFingerPos = py;
maxSize = size;
}
}
}
indPF++;
}
//r<>cup<75>ration du point le plus haut dans la forme s<>lectionn<6E>e
memset(workBuffer3, 0, SX*SY*sizeof(s32));
memset(visited, 0, SX*SY*sizeof(s32));
for(int px=0; px<SX; px++)
for(int py=0; py<SY; py++)
*(visited + px + py*PITCH) = 0xffffffff ^ (*(mask + px + py*PITCH));
spreadPx(visited, workBuffer3, xFingerPos, yFingerPos, PITCH, SY, SX, XStack, YStack);
xFingerPos = -1;
yFingerPos = -1;
angleFinger = 0;
for(int angle = 20; angle <= 180-20; angle+=3)
{
coeffDir = tan(angle*3.14/180.0);
for(int py=0; py<SY; py+=5)
{
for(int px=0; px<SX; px++)
{
int x = px;
int y = py;
float length = 0;
finger = true;
while(finger && length < maxLength)
{
if(x-maxWidth/2>=0 && x+maxWidth/2<SX && y>=0 && y<SY)
{
if(*(workBuffer3+x+maxWidth/2+y*PITCH)!=0) finger = false;
if(*(workBuffer3+x-maxWidth/2+y*PITCH)!=0) finger = false;
if(*(workBuffer3+x+maxWidth/16+y*PITCH)==0) finger = false;
if(*(workBuffer3+x+y*PITCH)==0) finger = false;
if(*(workBuffer3+x-maxWidth/16+y*PITCH)==0) finger = false;
}
else finger = false;
if(angle>45 && angle<180-45)
{
y += 3;
x = px + (int)((float)(y-py)/coeffDir);
length = sqrt((double)((float)(y-py)/coeffDir*(float)(y-py)/coeffDir+(y-py)*(y-py)));
}
else
{
if(coeffDir>0) x += 3;
else x -= 3;
y = py + (int)((float)(x-px)*coeffDir);
length = sqrt((double)((float)(x-px)*coeffDir*(float)(x-px)*coeffDir+(x-px)*(x-px)));
}
}
//R<>cup<75>ration de la forme de couleur de peau la plus haute qui match
if(finger && y > yFingerPos + maxLength*sin((double)angleFinger*3.14/180.0))
{
xFingerPos = px;
yFingerPos = py;
angleFinger = angle;
}
}
}
}
//placement initiale du reverse dans la fenetre
{
MATRIX mFi;
int ObjID;
/* Modify Globalmatrix of the headmask */
char OBJECT[] = "TETE_DEFAUT.OBJ";
UnicID ObjectREF;
ObjectREF = SmSc->ObjectNameDico.IsExist(OBJECT);
if (ObjectREF != -1)
{
ObjID = SmSc->ObjectNameDico.mpst_Dico[ObjectREF].AssociatedValue;
u32 Father = SmSc->ObjectsPtrs[ObjID]->FatherIndex;
//restitution de la t<>te d'origine
SmSc->ObjectsPtrs[ObjID]->GlobalMatrix = SmSc->ObjectsPtrs[ObjID]->OriginalGlobalMatrix;
//r<>duction de la t<>te
SmSc->ObjectsPtrs[ObjID]->GlobalMatrix *= 0.7;
//positionnement de la t<>te au bout du doigt
float posX = -0.3;
float posY = -0.3;
SmSc->ObjectsPtrs[ObjID]->GlobalMatrix.T.x += 0.8*posX;
SmSc->ObjectsPtrs[ObjID]->GlobalMatrix.T.z += 0.5*posY+0.09;
SmSc->ObjectsPtrs[Father]->GlobalMatrix.Inverse(mFi);
SmSc->ObjectsPtrs[ObjID]->LocalMatrix = SmSc->ObjectsPtrs[ObjID]->GlobalMatrix;
SmSc->ObjectsPtrs[ObjID]->LocalMatrix *= mFi;
}
}
//si une extr<74>mit<69> de doigt a <20>t<EFBFBD> rep<65>r<EFBFBD> et que le tracker est actif
if(yFingerPos != -1 && camMatrix.T.x!=0 && camMatrix.T.y!=0)
{
/*
//affichage des d<>limitations qui ont permi la d<>tection du doigt
for(int i=-3; i<4; i++)
for(int j=-3; j<4; j++)
if(xFingerPos+i>=0 && xFingerPos+i<SX && yFingerPos+j>=0 && yFingerPos+j<SY)
*(dest+xFingerPos+i+(yFingerPos+j)*PITCH) = 255; //carr<72> bleu <20> la pos du doigt
//*/
//am<61>lioration de la position et de l'angle obtenue
int fingerPixelWidth = 10000;
int testWidth;
int xa;
int xb;
int ya;
int yb;
int x1;
int y1;
int angleFingerPerp;
for(int angle=91; angle<180+90; angle++)
{
testWidth = 0;
int angleRec = angle;
if(angle>180) angle -= 180;
float coeffDir = tan((angle)*3.14/180.0);
int x = xFingerPos;
int y = yFingerPos;
while((x>=0 && y>=0 && x<SX && y<SY) && *(mask+x+y*PITCH)==-1)
{
if(!(angle>45 && angle<180-45))
{
if(coeffDir>0) x--;
else x++;
y = yFingerPos + (int)((float)(x-xFingerPos)*coeffDir);
}
else
{
y++;
x = xFingerPos + (int)((float)(y-yFingerPos)/coeffDir);
}
}
x1 = x;
y1 = y;
if(!(angle>45 && angle<180-45))
testWidth += (int)sqrt((float)(x-xFingerPos)*coeffDir*(float)(x-xFingerPos)*coeffDir+(x-xFingerPos)*(x-xFingerPos));
else
testWidth += (int)sqrt((float)(y-yFingerPos)/coeffDir*(float)(y-yFingerPos)/coeffDir+(y-yFingerPos)*(y-yFingerPos));
x = xFingerPos;
y = yFingerPos;
while((x>=0 && y>=0 && x<SX && y<SY) && *(mask+x+y*PITCH)==-1)
{
if(!(angle>45 && angle<180-45))
{
if(coeffDir>0) x++;
else x--;
y = yFingerPos + (int)((float)(x-xFingerPos)*coeffDir);
}
else
{
y--;
x = xFingerPos + (int)((float)(y-yFingerPos)/coeffDir);
}
}
if(!(angle>45 && angle<180-45))
testWidth += (int)sqrt((float)(x-xFingerPos)*coeffDir*(float)(x-xFingerPos)*coeffDir+(x-xFingerPos)*(x-xFingerPos));
else
testWidth += (int)sqrt((float)(y-yFingerPos)/coeffDir*(float)(y-yFingerPos)/coeffDir+(y-yFingerPos)*(y-yFingerPos));
if(testWidth < fingerPixelWidth)
{
xa = x1;
ya = y1;
xb = x;
yb = y;
fingerPixelWidth = testWidth;
angleFinger = angle + 90;
if(angleFinger>180) angleFinger -= 180;
angleFingerPerp = angle;
}
angle = angleRec;
}
xFingerPos = (xa+xb)/2;
yFingerPos = (ya+yb)/2;
//affichage de l'angle obtenu
/*
int x = xFingerPos;
int y = yFingerPos;
coeffDir = tan((angleFinger)*3.14/180.0);
while(x>=0 && y>=0 && x<SX && y<SY)
{
if(!(angleFinger>45 && angleFinger<180-45))
{
if(coeffDir>0) x++;
else x--;
y = yFingerPos + (int)((float)(x-xFingerPos)*coeffDir);
}
else
{
y++;
x = xFingerPos + (int)((float)(y-yFingerPos)/coeffDir);
}
//if(x>=0 && y>=0 && x<SX && y<SY) *(dest+x+y*PITCH) = 255<<16 | 128<<8;
}
x = xFingerPos;
y = yFingerPos;
coeffDir = tan((angleFinger)*3.14/180.0);
while(x>=0 && y>=0 && x<SX && y<SY)
{
if(!(angleFinger>45 && angleFinger<180-45))
{
if(coeffDir>0) x--;
else x++;
y = yFingerPos + (int)((float)(x-xFingerPos)*coeffDir);
}
else
{
y--;
x = xFingerPos + (int)((float)(y-yFingerPos)/coeffDir);
}
//if(x>=0 && y>=0 && x<SX && y<SY) *(dest+x+y*PITCH) = 255<<16 | 128<<8;
}
*/
/*
for(int i=-3; i<4; i++)
for(int j=-3; j<4; j++)
if(xFingerPos+i>=0 && xFingerPos+i<SX && yFingerPos+j>=0 && yFingerPos+j<SY)
*(dest+xFingerPos+i+(yFingerPos+j)*PITCH) = 255<<3;
*/
//r<>cup<75>ration de l'angle r<>el <20> partir de l'angle approximatif
//s<>paration du bout du doigt
coeffDir = tan((angleFingerPerp)*3.14/180.0);
int x = xFingerPos;
int y = yFingerPos;
while((x>=0 && y>=0 && x<SX && y<SY) && *(mask+x+y*PITCH)==-1)
{
if(x>=0 && y>=0 && x<SX && y<SY) *(mask+x+y*PITCH) = 0;
if(!(angleFingerPerp>45 && angleFingerPerp<180-45))
{
if(coeffDir>0) x--;
else x++;
y = yFingerPos + (int)((float)(x-xFingerPos)*coeffDir);
}
else
{
y++;
x = xFingerPos + (int)((float)(y-yFingerPos)/coeffDir);
}
}
x = xFingerPos;
y = yFingerPos;
while(((x>=0 && y>=0 && x<SX && y<SY) && *(mask+x+y*PITCH)==-1) || (y==yFingerPos && x==xFingerPos))
{
if(x>=0 && y>=0 && x<SX && y<SY) *(mask+x+y*PITCH) = 0;
if(!(angleFingerPerp>45 && angleFingerPerp<180-45))
{
if(coeffDir>0) x++;
else x--;
y = yFingerPos + (int)((float)(x-xFingerPos)*coeffDir);
}
else
{
y--;
x = xFingerPos + (int)((float)(y-yFingerPos)/coeffDir);
}
}
//calcul du centre de gravit<69> et de l'angle r<>el
//-> calcul du point de d<>part de la propagation avec recentrage du FingerPos
coeffDir = tan((angleFinger)*3.14/180.0);
yFingerPos = yFingerPos++;
xFingerPos = xFingerPos + (int)(1.0/coeffDir);
if(xFingerPos>=0 && yFingerPos>=0 && xFingerPos<SX && yFingerPos<SY)
{
//*(dest + gravityCenterX + gravityCenterY*PITCH) = 255<<16;
int debOfStack = 0;
int endOfStack = 0;
memset(XStack, 0, SY*SX*sizeof(s32));
memset(YStack, 0, SY*SX*sizeof(s32));
memset(visited, 0, SY*SX*sizeof(s32));
*XStack = xFingerPos;
*YStack = yFingerPos;
int gravityCenterX = 0;
int gravityCenterY = 0;
int nbPixels = 0;
while(endOfStack>=debOfStack)
{
gravityCenterX += *(XStack+debOfStack);
gravityCenterY += *(YStack+debOfStack);
*(visited + *(XStack+debOfStack) + (*(YStack+debOfStack))*PITCH) =-1;
for(int x = -1; x < 2; x++)
for(int y = -1; y < 2; y++)
{
if(abs(x*y)!=1 && *(XStack+debOfStack)+x>=0 && *(YStack+debOfStack)+y>=0 && *(XStack+debOfStack)+x<SX && *(YStack+debOfStack)+y<SY)
{
if(*(visited + *(XStack+debOfStack) + x + (*(YStack+debOfStack) + y)*PITCH) != -1)
{
if(*(mask + *(XStack+debOfStack) + x + (*(YStack+debOfStack) + y)*PITCH) == -1)
{
*(dest + *(XStack+debOfStack) + x + (*(YStack+debOfStack) + y)*PITCH) = 255;
*(visited + *(XStack+debOfStack) + x + (*(YStack+debOfStack) + y)*PITCH) = -1;
endOfStack++;
*(XStack+endOfStack) = *(XStack+debOfStack) + x;
*(YStack+endOfStack) = *(YStack+debOfStack) + y;
}
}
}
}
debOfStack++;
nbPixels = debOfStack;
}
gravityCenterX = gravityCenterX/nbPixels;
gravityCenterY = gravityCenterY/nbPixels;
//-> calcul de l'angle du bout du doigt avec l'horizontal
debOfStack = 0;
endOfStack = 0;
memset(XStack, 0, SY*SX*sizeof(s32));
memset(YStack, 0, SY*SX*sizeof(s32));
memset(visited, 0, SY*SX*sizeof(s32));
*XStack = xFingerPos;
*YStack = yFingerPos;
int sumXY = 0;
int sumXX = 0;
int sumYY = 0;
while(endOfStack>=debOfStack)
{
sumXY += 2*(*(XStack+debOfStack)-gravityCenterX)*(*(YStack+debOfStack)-gravityCenterY);
sumXX += (gravityCenterX-*(XStack+debOfStack))*(gravityCenterX-*(XStack+debOfStack));
sumYY += (gravityCenterY-*(YStack+debOfStack))*(gravityCenterY-*(YStack+debOfStack));
*(visited + *(XStack+debOfStack) + (*(YStack+debOfStack))*PITCH) =-1;
for(int x = -1; x < 2; x++)
for(int y = -1; y < 2; y++)
{
if(abs(x*y)!=1 && *(XStack+debOfStack)+x>=0 && *(YStack+debOfStack)+y>=0 && *(XStack+debOfStack)+x<SX && *(YStack+debOfStack)+y<SY)
{
if(*(visited + *(XStack+debOfStack) + x + (*(YStack+debOfStack) + y)*PITCH) != -1)
{
if(*(mask + *(XStack+debOfStack) + x + (*(YStack+debOfStack) + y)*PITCH) == -1)
{
*(dest + *(XStack+debOfStack) + x + (*(YStack+debOfStack) + y)*PITCH) = 255;
*(visited + *(XStack+debOfStack) + x + (*(YStack+debOfStack) + y)*PITCH) = -1;
endOfStack++;
*(XStack+endOfStack) = *(XStack+debOfStack) + x;
*(YStack+endOfStack) = *(YStack+debOfStack) + y;
}
}
}
}
debOfStack++;
}
if(sumXX!=sumYY) //si angle de la forme est calculable
{
double delta = (double)sumXY/(double)(sumXX-sumYY);
double alpha = (atan(delta)/2+(PI/180*(45-45*((abs(sumXX-sumYY))/(sumXX-sumYY)))))*180.0/PI;
while(alpha<0 || alpha>=180)
{
if(alpha<0) alpha+=180;
if(alpha>=180) alpha-=180;
}
char * angleText = (char *)ZeroAlloc(2*sizeof(char));
sprintf(angleText, "%.2f<EFBFBD>", (float)alpha);
DRawTEXT_Soft_B((unsigned char*)angleText, (unsigned int*)dest, 10, 25, PITCH, SY, 255<<8);
//d<>termination de la position de l'extremit<69> du doigt
x = xFingerPos;
y = yFingerPos;
int xFingerExtremity;
int yFingerExtremity;
bool takeExtremity = true;
coeffDir = tan((alpha)*3.14/180.0);
while(x>=0 && y>=0 && x<SX && y<SY)
{
if(!(alpha>45 && alpha<180-45))
{
if(coeffDir>0) x++;
else x--;
y = yFingerPos + (int)((float)(x-xFingerPos)*coeffDir);
}
else
{
y++;
x = xFingerPos + (int)((float)(y-yFingerPos)/coeffDir);
}
if(takeExtremity && *(mask+x+y*PITCH) != -1)
{
xFingerExtremity = x;
yFingerExtremity = y;
takeExtremity = false;
}
*(dest+x+y*PITCH) = 255<<8;
}
x = xFingerPos;
y = yFingerPos;
while(x>=0 && y>=0 && x<SX && y<SY)
{
if(!(alpha>45 && alpha<180-45))
{
if(coeffDir>0) x--;
else x++;
y = yFingerPos + (int)((float)(x-xFingerPos)*coeffDir);
}
else
{
y--;
x = xFingerPos + (int)((float)(y-yFingerPos)/coeffDir);
}
*(dest+x+y*PITCH) = 255<<8;
}
for(int i=-3; i<4; i++)
for(int j=-3; j<4; j++)
if(xFingerExtremity+i>=0 && xFingerExtremity+i<SX && yFingerExtremity+j>=0 && yFingerExtremity+j<SY)
*(dest+xFingerExtremity+i+(yFingerExtremity+j)*PITCH) = 255<<16;
//r<>cup<75>ration du visage dans le reverse
int fingerPixelLength = fingerPixelWidth*3/5; //longueur de la t<>te <20> ins<6E>rer
//plaquage du visage du reverse sur le doigt
MATRIX mFi;
int ObjID;
/* Modify Globalmatrix of the headmask */
char OBJECT[] = "TETE_DEFAUT.OBJ";
UnicID ObjectREF;
ObjectREF = SmSc->ObjectNameDico.IsExist(OBJECT);
if (ObjectREF != -1)
{
ObjID = SmSc->ObjectNameDico.mpst_Dico[ObjectREF].AssociatedValue;
u32 Father = SmSc->ObjectsPtrs[ObjID]->FatherIndex;
//restitution de la t<>te d'origine
SmSc->ObjectsPtrs[ObjID]->GlobalMatrix = SmSc->ObjectsPtrs[ObjID]->OriginalGlobalMatrix;
//rotation de la t<>te
SmSc->ObjectsPtrs[ObjID]->GlobalMatrix.RotateAround_J((90-alpha)*3.14/180.0);
//r<>duction de la t<>te
SmSc->ObjectsPtrs[ObjID]->GlobalMatrix *= 0.7;
//positionnement de la t<>te au bout du doigt
float posX = ((float)(xFingerExtremity+(4/14*352)*cos(alpha*3.14/180.0))-352/2)/352.0;
float posY = ((float)(yFingerExtremity+(4/10*288)*sin(alpha*3.14/180.0))-288/2)/288.0;
SmSc->ObjectsPtrs[ObjID]->GlobalMatrix.T.x += 0.8*posX;
SmSc->ObjectsPtrs[ObjID]->GlobalMatrix.T.z += 0.5*posY+0.09;
SmSc->ObjectsPtrs[Father]->GlobalMatrix.Inverse(mFi);
SmSc->ObjectsPtrs[ObjID]->LocalMatrix = SmSc->ObjectsPtrs[ObjID]->GlobalMatrix;
SmSc->ObjectsPtrs[ObjID]->LocalMatrix *= mFi;
}
//to do : gestion du zoom avec la molette de la souris
static zoomIndex = 0;
short Mask = 32768;
if (GetKeyState(VK_SUBTRACT) & Mask)
{
zoomIndex += 10;
}
else if (GetKeyState(VK_ADD) & Mask)
{
zoomIndex -= 10;
}
if(zoomIndex<0) zoomIndex = 0;
}
}
}
}
s32 getRGBFromYCbCr(s32 Y, s32 Cb, s32 Cr)
{
int R = (298 * (Y - 16) + 409 * (Cr - 128) + 128) >> 8;
int G = (298 * (Y - 16) - 100 * (Cb - 128) - 208 * (Cr - 128) + 128) >> 8;
int B = (298 * (Y - 16) + 516 * (Cb - 128) + 128) >> 8;
if(R<0) R=0;
if(G<0) G=0;
if(B<0) B=0;
if(R>255) R=255;
if(G>255) G=255;
if(B>255) B=255;
return makeRGB(R,G,B);
}
void debugScr(float val)
{
val;
return;
}
void getExtremities(s32 * src, s32 * dest, int PITCH, int sizeOfMap, int SX, int SY)
{
static s32 * OriginalSrc;
if(OriginalSrc == NULL) OriginalSrc = (s32*) CC_malloc(sizeOfMap);
memcpy(OriginalSrc, src, sizeOfMap);
//memcpy(dest, src, ID_MEDIA[MediaIndexSrc]->Image.SX*ID_MEDIA[MediaIndexSrc]->Image.SY*sizeof(s32));
memset(src, 0, sizeOfMap);
int vx[8]; vx[0]=0; vx[1]=-1; vx[2]=-1; vx[3]=-1; vx[4]=0; vx[5]=1; vx[6]=1; vx[7]=1;
int vy[8]; vy[0]=-1; vy[1]=-1; vy[2]=0; vy[3]=1; vy[4]=1; vy[5]=1; vy[6]=0; vy[7]=-1;
int indPixel;
int indPixelDirecteur[8];
int indLastOppositePoint[8];
int nbPoints;
int color[4]; color[0] = 255<<8; color[1] = 255<<0 | 255<<8;
color[2] = 255<<16 | 255<<8; color[3] = 255<<16 | 255<<0;
int nbExtremities;
static s32 * indPixelsMedians;
if(indPixelsMedians == NULL) indPixelsMedians = (s32*) CC_malloc(sizeOfMap);
static s32 * coulMedians;
if(coulMedians == NULL) coulMedians = (s32*) CC_malloc(sizeOfMap);
static s32 * coulPoints;
if(coulPoints == NULL) coulPoints = (s32*) CC_malloc(sizeOfMap);
static s32 * Pixels1X;
if(Pixels1X == NULL) Pixels1X = (s32*) CC_malloc(sizeOfMap);
static s32 * Pixels1Y;
if(Pixels1Y == NULL) Pixels1Y = (s32*) CC_malloc(sizeOfMap);
static s32 * Pixels2X;
if(Pixels2X == NULL) Pixels2X = (s32*) CC_malloc(sizeOfMap);
static s32 * Pixels2Y;
if(Pixels2Y == NULL) Pixels2Y = (s32*) CC_malloc(sizeOfMap);
static s32 * tmp;
if(tmp == NULL) tmp = (s32*) CC_malloc(sizeOfMap);
memset(tmp, 0, sizeOfMap);
static s32 * tmp2;
if(tmp2 == NULL) tmp2 = (s32*) CC_malloc(sizeOfMap);
memset(tmp2, 0, sizeOfMap);
int inc = 1;
int wayChanged = false;
int py;
int px;
unsigned int data[10];
float indexLength = 0;
memset(data, 0xffff, 10*sizeof(int));
data[4] = 0;
for(py=0; py<SY && py>-1; py+=inc)
{
for(px=0; px<SX && px>-1; px++)
{
if(*(OriginalSrc+px+py*PITCH)==-1 && *(tmp+px+py*PITCH)==0)
{
int nbVoisins = 0;
int nbVoisinsTried = 0;
*(tmp2+px+py*PITCH) = -1;
for(int v=0; v<8; v++)
{
if(px+vx[v]>=0 && px+vx[v]<SX && py+vy[v]>=0 && py+vy[v]<SY)
if(*(OriginalSrc+px+vx[v]+(py+vy[v])*PITCH)==-1)
{
nbVoisins++;
if(*(tmp2+px+vx[v]+(py+vy[v])*PITCH)==-1)
nbVoisinsTried++;
}
}
if(nbVoisins==1 || (nbVoisins==2 && nbVoisinsTried==2))
{
indPixel = 0;
nbPoints = 0;
nbExtremities = 0;
for(int v=0; v<8; v++)
indPixelDirecteur[v] = -2;
memset(indLastOppositePoint, 0, 8*sizeof(int));
memset(indPixelsMedians, -1, sizeOfMap);
memset(coulMedians, -1, sizeOfMap);
memset(coulPoints, -1, sizeOfMap);
memset(Pixels1X, -1, sizeOfMap);
memset(Pixels2X, -1, sizeOfMap);
memset(Pixels1Y, -1, sizeOfMap);
memset(Pixels2Y, -1, sizeOfMap);
//recherche des extr<74>mit<69>s
int x = px;
int y = py;
*(tmp+px+py*PITCH) = -1;
*(dest+px+py*PITCH) = -1;
bool remainingNeighbour;
do
{
remainingNeighbour = false;
for(int v=0; v<8; v++)
{
if(x+vx[v]>=0 && x+vx[v]<SX && y+vy[v]>=0 && y+vy[v]<SY)
{
if(*(OriginalSrc+x+vx[v]+(y+vy[v])*PITCH)==-1 && *(tmp+x+vx[v]+(y+vy[v])*PITCH)==0)
{
/*
for(int v2=0; v2<8; v2++)
if(x+vx[v2]>=0 && x+vx[v2]<SX && y+vy[v2]>=0 && y+vy[v2]<SY)
*(dest+x+vx[v2]+(y+vy[v2])*PITCH) = color[v%4];
//*/
indPixel++;
if(indPixelDirecteur[(v+4)%8]!=-1 && indPixelDirecteur[(v+4)%8]!=-2)
{
if((indPixel - indPixelDirecteur[(v+4)%8])<20)
{
indPixelsMedians[nbExtremities] = (indPixelDirecteur[(v+4)%8]+indPixel)/2;
coulMedians[nbExtremities] = 255<<16; //color[v%4];
nbExtremities++;
Pixels2X[indLastOppositePoint[(v+4)%8]] = x;
Pixels2Y[indLastOppositePoint[(v+4)%8]] = y;
coulPoints[indLastOppositePoint[(v+4)%8]] = v;
Pixels1X[nbPoints] = x;
Pixels1Y[nbPoints] = y;
indLastOppositePoint[v] = nbPoints;
nbPoints++;
}
indPixelDirecteur[(v+4)%8] = -1;
}
else if(indPixelDirecteur[v]==-2)
{
Pixels1X[nbPoints] = x;
Pixels1Y[nbPoints] = y;
indLastOppositePoint[v] = nbPoints;
nbPoints++;
/*
for(int v2=0; v2<8; v2++)
if(x+vx[v2]>=0 && x+vx[v2]<ID_MEDIA[MediaIndexDest]->Image.SX && y+vy[v2]>=0 && y+vy[v2]<ID_MEDIA[MediaIndexDest]->Image.SY)
*(dest+x+vx[v2]+(y+vy[v2])*PITCH) = color[v%4];
*/
}
//*
if(indPixelDirecteur[(v+4)%8]==-1 || indPixelDirecteur[(v+4)%8]==-2)
{
Pixels1X[indLastOppositePoint[v]] = x;
Pixels1Y[indLastOppositePoint[v]] = y;
}
//*/
indPixelDirecteur[v] = indPixel;
remainingNeighbour = true;
*(tmp+x+vx[v]+(y+vy[v])*PITCH) = -1;
*(dest+x+vx[v]+(y+vy[v])*PITCH) = -1;
x = x + vx[v];
y = y + vy[v];
v = 7;
}
}
}
} while(remainingNeighbour);
//affichage des extr<74>mit<69>s
for(int i=0; i<nbPoints; i++)
{
if(Pixels2X[i]!=-1 && Pixels1X[i]!=-1)
{
/*
int v = coulPoints[i];
for(int v2=0; v2<8; v2++)
if(Pixels2X[i]+vx[v2]>=0 && Pixels2X[i]+vx[v2]<SX && Pixels2Y[i]+vy[v2]>=0 && Pixels2Y[i]+vy[v2]<SY)
*(dest+Pixels2X[i]+vx[v2]+(Pixels2Y[i]+vy[v2])*PITCH) = color[v%4];
for(int v2=0; v2<8; v2++)
if(Pixels1X[i]+vx[v2]>=0 && Pixels1X[i]+vx[v2]<SX && Pixels1Y[i]+vy[v2]>=0 && Pixels1Y[i]+vy[v2]<SY)
*(dest+Pixels1X[i]+vx[v2]+(Pixels1Y[i]+vy[v2])*PITCH) = color[v%4];
drawLine(dest, Pixels1X[i], Pixels2X[i], Pixels1Y[i], Pixels2Y[i], PITCH, color[v%4]);
*/
}
}
/*
for(int i=-2; i<3; i++)
for(int j=-2; j<3; j++)
if(x+i>=0 && x+i<SX && y+j>=0 && y+j<SY)
*(dest+x+i+(y+j)*PITCH) = 128<<8 | 255<<16;
//*/
*(tmp+px+py*PITCH) = -2;
x = px;
y = py;
indPixel = 0;
do
{
remainingNeighbour = false;
for(int v=0; v<8; v++)
{
if(x+vx[v]>=0 && x+vx[v]<SX && y+vy[v]>=0 && y+vy[v]<SY)
{
if(*(OriginalSrc+x+vx[v]+(y+vy[v])*PITCH)==-1 && *(tmp+x+vx[v]+(y+vy[v])*PITCH)==-1)
{
indPixel++;
//*
for(int i=0; i<nbExtremities; i++)
if(indPixel==indPixelsMedians[i])
{
for(int v2=0; v2<8; v2++)
if(x+vx[v2]>=0 && x+vx[v2]<SX && y+vy[v2]>=0 && y+vy[v2]<SY)
*(dest+x+vx[v2]+(y+vy[v2])*PITCH) = coulMedians[i];
if(y+vy[v]<data[1])
{
data[0] = x+vx[v];
data[1] = y+vy[v];
}
}
if(data[0] == x+vx[v] && data[1] == y+vy[v])
{
indexLength = 0;
data[2] = 1;
}
//*/
remainingNeighbour = true;
*(tmp+x+vx[v]+(y+vy[v])*PITCH) = -2;
x = x + vx[v];
y = y + vy[v];
v = 7;
}
}
}
} while(remainingNeighbour);
}
}
if(py==SY-1 && px==SX-1 && wayChanged==false)
{
wayChanged = true;
inc = -1;
memset(tmp2, 0, sizeOfMap);
memset(tmp, 0, sizeOfMap);
py = SY;
}
}
}
int x = data[0];
int y = data[1];
for(int v2=-7; v2<8; v2++)
if(x+v2>=0 && x+v2<SX && y+v2>=0 && y+v2<SY)
{
*(dest+x+v2+(y+v2)*PITCH) = 255<<16 | 255<<8;
*(dest+x+v2+(y-v2)*PITCH) = 255<<16 | 255<<8;
}
*(tmp+x+y*PITCH) = -3;
indexLength = 0;
for(int v=1; v<4; v++)
{
if(x+vx[v]>=0 && x+vx[v]<SX && y+vy[v]>=0 && y+vy[v]<SY)
{
x = x + vx[v];
y = y + vy[v];
*(tmp+x+y*PITCH) = -3;
if(v%2==0) indexLength += 1;
else indexLength += sqrt(2.0);
}
}
//indPixel = 0;
int remainingNeighbour;
do
{
remainingNeighbour = false;
for(int v=0; v<8; v++)
{
if(x+vx[v]>=0 && x+vx[v]<SX && y+vy[v]>=0 && y+vy[v]<SY)
{
if(*(OriginalSrc+x+vx[v]+(y+vy[v])*PITCH)==-1 && *(tmp+x+vx[v]+(y+vy[v])*PITCH)!=-3)
{
//indPixel++;
if(v%2==0) indexLength += 1;
else indexLength += sqrt(2.0);
remainingNeighbour = true;
*(tmp+x+vx[v]+(y+vy[v])*PITCH) = -3;
if(v==2 && indexLength>20)
{
remainingNeighbour = false;
data[3] = x+vx[v];
data[4] = y+vy[v];
}
//*(dest+x+vx[v]+(y+vy[v])*PITCH) = 255;
x = x + vx[v];
y = y + vy[v];
v = 7;
}
}
}
} while(remainingNeighbour);
/*
x = data[3];
y = data[4];
for(int v2=-7; v2<8; v2++)
if(x+v2>=0 && x+v2<SX && y+v2>=0 && y+v2<SY)
{
*(dest+x+v2+(y+v2)*PITCH) = 255<<16;
*(dest+x+v2+(y-v2)*PITCH) = 255<<16;
}
*/
POINT pos;
GetCursorPos(&pos);
float a = 1024.0/(128-263);
float b = -263*a;
static int lastYPos = data[1];
static bool quicklyMoved = false;
if(abs((int)(data[1]-lastYPos))>15) quicklyMoved = true;
else
{
lastYPos = data[1];
SetCursorPos(data[0]*4-100, (int)(a*data[1]+b));
if(quicklyMoved)
{
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
Sleep(2);
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
quicklyMoved = false;
}
}
//indexLength = sqrt((float)((data[0]-data[3])*(data[0]-data[3]) + (data[1]-data[4])*(data[1]-data[4])));
//HWND Bureau = GetDesktopWindow();
//LPRECT ecran;
//GetWindowRect(Bureau, ecran);
}
bool isOfSkinColor(s32 pixel, int YMin, int YMax, int CbMin, int CbMax,int CrMin, int CrMax)
{
if(getY(pixel)>=YMin && getY(pixel)<=YMax)
if(getCb(pixel)>=CbMin && getCb(pixel)<=CbMax)
if(getCr(pixel)>=CrMin && getCr(pixel)<=CrMax)
return true;
return false;
}
void extendSkinColor(WORKINGSPACE* WSPC, MAP &DESTMAP, MAP &SOURCEMAP, int deltaOnColor, int YMin, int YMax, int CbMin, int CbMax, int CrMin, int CrMax)
{
if(WSPC->PREVIOUSMAP == NULL) WSPC->PREVIOUSMAP = (MAP*)ZeroAlloc(sizeof(SOURCEMAP));
bool srcChanged = (DESTMAP.SX != SOURCEMAP.SX || DESTMAP.SY != SOURCEMAP.SY);
if(WSPC->HANDWORK[0]==NULL || srcChanged) WSPC->HANDWORK[0] = (s32 *)CC_malloc(DESTMAP.SX*DESTMAP.SY*sizeof(s32));
if(WSPC->HANDWORK[1]==NULL || srcChanged) WSPC->HANDWORK[1] = (s32 *)CC_malloc(DESTMAP.SX*DESTMAP.SY*sizeof(s32));
if(WSPC->HANDWORK[2]==NULL || srcChanged) WSPC->HANDWORK[2] = (s32 *)CC_malloc(DESTMAP.SX*DESTMAP.SY*sizeof(s32));
memset(WSPC->HANDWORK[0], 0, DESTMAP.SX*DESTMAP.SY*sizeof(s32));
memset(WSPC->HANDWORK[1], 0, DESTMAP.SX*DESTMAP.SY*sizeof(s32));
memset(WSPC->HANDWORK[2], 0, DESTMAP.SX*DESTMAP.SY*sizeof(s32));
s32 * visited = WSPC->HANDWORK[0];
s32 * toVisit = DESTMAP.BASE;
int PITCH = DESTMAP.PITCH;
int Width = DESTMAP.SX;
int Height = DESTMAP.SY;
int pixel;
int voisin;
int debOfStack;
int endOfStack;
s32 * XStack = WSPC->HANDWORK[1];
s32 * YStack = WSPC->HANDWORK[2];
int nbPointsAdded = 0;
int nbPointsSkipped = 0;
int YMin2 = YMin;
int YMax2 = YMax;
int CbMin2 = CbMin;
int CbMax2 = CbMax;
int CrMin2 = CrMin;
int CrMax2 = CrMax;
for(unsigned int px = 0; px < DESTMAP.SX; px++)
for(unsigned int py = 0; py < DESTMAP.SY; py++)
{
debOfStack = 0;
endOfStack = 0;
*XStack = px;
*YStack = py;
/*
YMin = YMin2;
YMax = YMax2;
CbMin = CbMin2;
CbMax = CbMax2;
CrMin = CrMin2;
CrMax = CrMax2;
*/
while (endOfStack>=debOfStack)
{
if(*(toVisit + *(XStack+debOfStack) + (*(YStack+debOfStack))*PITCH)!=0)
{
*(visited + *(XStack+debOfStack) + (*(YStack+debOfStack))*PITCH) = -1;
if(*(toVisit + *(XStack+debOfStack) + (*(YStack+debOfStack))*PITCH)==-1)
{
pixel = *(SOURCEMAP.BASE + *(XStack+debOfStack) + (*(YStack+debOfStack))*PITCH);
for(int x = -1; x < 2; x++)
{
for(int y = -1; y < 2; y++)
{
if(*(XStack+debOfStack)+x>=0 && *(YStack+debOfStack)+y>=0 && *(XStack+debOfStack)+x<Width && *(YStack+debOfStack)+y<Height)
{
if(*(visited + *(XStack+debOfStack) + x + (*(YStack+debOfStack) + y)*PITCH)==0)
{
*(visited + *(XStack+debOfStack) + x + (*(YStack+debOfStack) + y)*PITCH) = -1;
voisin = *(SOURCEMAP.BASE + *(XStack+debOfStack) + x + (*(YStack+debOfStack) + y)*PITCH);
if(abs(getY(voisin)-getY(pixel))<3*deltaOnColor
&& abs(getCb(voisin)-getCb(pixel))<deltaOnColor
&& abs(getCr(voisin)-getCr(pixel))<deltaOnColor)
if((isOfSkinColor(voisin, YMin-deltaOnColor, YMax+deltaOnColor, CbMin, CbMax, CrMin, CrMax))
|| (isOfSkinColor(voisin, YMin, YMax, CbMin-deltaOnColor, CbMax+deltaOnColor, CrMin, CrMax))
|| (isOfSkinColor(voisin, YMin, YMax, CbMin, CbMax, CrMin-deltaOnColor, CrMax+deltaOnColor)))
{
*(toVisit + *(XStack+debOfStack) + x + (*(YStack+debOfStack) + y)*PITCH) = -1;
endOfStack++;
*(XStack+endOfStack) = *(XStack+debOfStack) + x;
*(YStack+endOfStack) = *(YStack+debOfStack) + y;
if(YMin>getY(voisin)) YMin = getY(voisin);
if(YMax<getY(voisin)) YMax = getY(voisin);
if(CbMin>getCb(voisin)) CbMin = getCb(voisin);
if(CbMax<getCb(voisin)) CbMax = getCb(voisin);
if(CrMin>getCr(voisin)) CrMin = getCr(voisin);
if(CrMax<getCr(voisin)) CrMax = getCr(voisin);
}
}
}
}
}
}
}
debOfStack++;
}
}
showSkin(DESTMAP, SOURCEMAP, YMin, YMax, CbMin, CbMax, CrMin, CrMax);
}
void showSkin(MAP &DESTMAP, MAP &SOURCEMAP, int YMin, int YMax, int CbMin, int CbMax, int CrMin, int CrMax)
{
int tmp;
if(YMin>YMax)
{
tmp = YMax;
YMax = YMin;
YMin = tmp;
}
if(CbMin>CbMax)
{
tmp = CbMax;
CbMax = CbMin;
CbMin = tmp;
}
if(CrMin>CrMax)
{
tmp = CrMax;
CrMax = CrMin;
CrMin = tmp;
}
int nbPx = 0;
for(unsigned int x = 0; x < SOURCEMAP.SX; x++)
for(unsigned int y = 0; y < SOURCEMAP.SY; y++)
{
if(isOfSkinColor(*(SOURCEMAP.BASE + x + y*SOURCEMAP.PITCH), YMin, YMax, CbMin, CbMax, CrMin, CrMax))
{
*(DESTMAP.BASE + x + y * DESTMAP.PITCH) = -1;
nbPx++;
}
else
*(DESTMAP.BASE + x + y * DESTMAP.PITCH) = 0;
}
}
void drawLine(s32* imd, int x1, int x2, int y1, int y2, int PITCH, int coul)
{
int i,j,max,min;
float pente;
if (y1!=y2)
pente=(float)(x1-x2)/(y1-y2);
else
pente=100000.0;
if ((pente<-1) || (pente>1))
{
if (x2<x1)
{
min=x2; max=x1;
}
else
{
min=x1; max=x2;
}
if (abs(max-min)>=1)
{
for (i=max;i>=min;i--)
{
j=(int)((i-x2)/pente +y2);
*(imd + i + j*PITCH) = coul;
}
}
else if(x1==x2)
{
*(imd + x1 + y1*PITCH) = coul;
}
}
else
{
if (y2<y1)
{
min=y2; max=y1;
}
else
{
min=y1; max=y2;
}
if (abs(max-min)>=1)
{
for (j=max;j>=min;j--)
{
i=(int)(pente*(j-y2)+x2);
*(imd + i + j*PITCH) = coul;
}
}
}
}
int spreadPx(s32 * visited, s32 * imDest, int px, int py, int PITCH, int Height, int Width, s32 * XStack, s32 * YStack)
{
int debOfStack = 0;
int endOfStack = 0;
*XStack = px;
*YStack = py;
while (endOfStack>=debOfStack)
{
*(imDest + *(XStack+debOfStack) + (*(YStack+debOfStack))*PITCH) =-1;
*(visited + *(XStack+debOfStack) + (*(YStack+debOfStack))*PITCH) =-1;
for(int x = -1; x < 2; x++)
for(int y = -1; y < 2; y++)
{
if(*(XStack+debOfStack)+x>=0 && *(YStack+debOfStack)+y>=0 && *(XStack+debOfStack)+x<Width && *(YStack+debOfStack)+y<Height)
{
if(*(visited + *(XStack+debOfStack) + x + (*(YStack+debOfStack) + y)*PITCH) != -1)
{
*(visited + *(XStack+debOfStack) + x + (*(YStack+debOfStack) + y)*PITCH) = -1;
endOfStack++;
*(XStack+endOfStack) = *(XStack+debOfStack) + x;
*(YStack+endOfStack) = *(YStack+debOfStack) + y;
}
}
}
debOfStack++;
}
return debOfStack;
}
int spreadPx4C(s32 * visited, s32 * imDest, int px, int py, int PITCH, int Height, int Width, s32 * XStack, s32 * YStack)
{
int debOfStack = 0;
int endOfStack = 0;
*XStack = px;
*YStack = py;
while (endOfStack>=debOfStack)
{
*(imDest + *(XStack+debOfStack) + (*(YStack+debOfStack))*PITCH) =-1;
*(visited + *(XStack+debOfStack) + (*(YStack+debOfStack))*PITCH) =-1;
for(int x = -1; x < 2; x++)
for(int y = -1; y < 2; y++)
{
if(!((x==-1 && y==-1) || (x==1 && y==1) || (x==1 && y==-1) || (x==-1 && y==1)))
{
if(*(XStack+debOfStack)+x>=0 && *(YStack+debOfStack)+y>=0 && *(XStack+debOfStack)+x<Width && *(YStack+debOfStack)+y<Height)
{
if(*(visited + *(XStack+debOfStack) + x + (*(YStack+debOfStack) + y)*PITCH) != -1)
{
*(visited + *(XStack+debOfStack) + x + (*(YStack+debOfStack) + y)*PITCH) = -1;
endOfStack++;
*(XStack+endOfStack) = *(XStack+debOfStack) + x;
*(YStack+endOfStack) = *(YStack+debOfStack) + y;
}
}
}
}
debOfStack++;
}
return debOfStack;
}
void getBiggestParts(WORKINGSPACE* WSPC, MAP &SOURCEMAP, int minimumSize)
{
if(WSPC->PREVIOUSMAP == NULL) WSPC->PREVIOUSMAP = (MAP*)ZeroAlloc(sizeof(SOURCEMAP));
bool srcChanged = (WSPC->PREVIOUSMAP->SX != SOURCEMAP.SX || WSPC->PREVIOUSMAP->SY != SOURCEMAP.SY);
if(WSPC->HANDWORK[4]==NULL || srcChanged) WSPC->HANDWORK[4] = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); //XStack
if(WSPC->HANDWORK[5]==NULL || srcChanged) WSPC->HANDWORK[5] = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); //YStack
if(WSPC->HANDWORK[6]==NULL || srcChanged) WSPC->HANDWORK[6] = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); //pixels visit<69>s
if(WSPC->HANDWORK[7]==NULL || srcChanged) WSPC->HANDWORK[7] = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); //XStack
if(WSPC->HANDWORK[8]==NULL || srcChanged) WSPC->HANDWORK[8] = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); //YStack
if(srcChanged)
{
WSPC->PREVIOUSMAP->SX = SOURCEMAP.SX;
WSPC->PREVIOUSMAP->SY = SOURCEMAP.SY;
}
s32 * src = SOURCEMAP.BASE;
s32 * PartInitPx = WSPC->HANDWORK[4];
s32 * PartInitPy = WSPC->HANDWORK[5];
s32 * visited = WSPC->HANDWORK[6];
s32 * XStack = WSPC->HANDWORK[7];
s32 * YStack = WSPC->HANDWORK[8];
//copie de l'inverse de src dans visited
for(int px=0; px<SOURCEMAP.SX; px++)
for(int py=0; py<SOURCEMAP.SY; py++)
{
*(visited + px + py*SOURCEMAP.PITCH) = 0xffffffff ^ (*(src + px + py*SOURCEMAP.PITCH));
}
memcpy(src, visited, SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32));
int nbParts = 0;
int size;
for(int px=0; px<SOURCEMAP.SX; px++)
for(int py=0; py<SOURCEMAP.SY; py++)
{
if(*(visited + px + py*SOURCEMAP.PITCH)==0)
{
size = spreadPx(visited, visited, px, py, SOURCEMAP.PITCH, SOURCEMAP.SY, SOURCEMAP.SX, XStack, YStack);
if(size >= minimumSize)
{
*(PartInitPx + nbParts) = px;
*(PartInitPy + nbParts) = py;
nbParts++;
}
}
}
memcpy(visited, src, SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32));
memset(src, 0, SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32));
for(int i=0; i<nbParts; i++)
spreadPx(visited, src, *(PartInitPx + i), *(PartInitPy + i), SOURCEMAP.PITCH, SOURCEMAP.SY, SOURCEMAP.SX, XStack, YStack);
}
void getHoles(WORKINGSPACE* WSPC, MAP &SOURCEMAP)
{
if(WSPC->PREVIOUSMAP == NULL) WSPC->PREVIOUSMAP = (MAP*)ZeroAlloc(sizeof(SOURCEMAP));
bool srcChanged = (WSPC->PREVIOUSMAP->SX != SOURCEMAP.SX || WSPC->PREVIOUSMAP->SY != SOURCEMAP.SY);
if(WSPC->HANDWORK[6]==NULL || srcChanged) WSPC->HANDWORK[6] = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); //pixels visit<69>s
if(WSPC->HANDWORK[7]==NULL || srcChanged) WSPC->HANDWORK[7] = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); //XStack
if(WSPC->HANDWORK[8]==NULL || srcChanged) WSPC->HANDWORK[8] = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); //YStack
if(srcChanged)
{
WSPC->PREVIOUSMAP->SX = SOURCEMAP.SX;
WSPC->PREVIOUSMAP->SY = SOURCEMAP.SY;
}
s32 * src = SOURCEMAP.BASE;
s32 * visited = WSPC->HANDWORK[6];
s32 * XStack = WSPC->HANDWORK[7];
s32 * YStack = WSPC->HANDWORK[8];
memcpy(visited, src, SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32));
memset(src, 0, SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32));
for(int px=0; px<SOURCEMAP.SX; px++)
{
int py = 0;
if(*(visited + px + py*SOURCEMAP.PITCH)==0)
spreadPx(visited, visited, px, py, SOURCEMAP.PITCH, SOURCEMAP.SY, SOURCEMAP.SX, XStack, YStack);
py = SOURCEMAP.SY-1;
if(*(visited + px + py*SOURCEMAP.PITCH)==0)
spreadPx(visited, visited, px, py, SOURCEMAP.PITCH, SOURCEMAP.SY, SOURCEMAP.SX, XStack, YStack);
}
for(int py=0; py<SOURCEMAP.SY; py++)
{
int px = 0;
if(*(visited + px + py*SOURCEMAP.PITCH)==0)
spreadPx(visited, visited, px, py, SOURCEMAP.PITCH, SOURCEMAP.SY, SOURCEMAP.SX, XStack, YStack);
px = SOURCEMAP.SX-1;
if(*(visited + px + py*SOURCEMAP.PITCH)==0)
spreadPx(visited, visited, px, py, SOURCEMAP.PITCH, SOURCEMAP.SY, SOURCEMAP.SX, XStack, YStack);
}
for(int px=0; px<SOURCEMAP.SX; px++)
for(int py=0; py<SOURCEMAP.SY; py++)
{
if(*(visited + px + py*SOURCEMAP.PITCH)==0)
{
if(!(px==0 || py==0 || px==(SOURCEMAP.SX-1) || py==(SOURCEMAP.SY-1)))
spreadPx(visited, src, px, py, SOURCEMAP.PITCH, SOURCEMAP.SY, SOURCEMAP.SX, XStack, YStack);
}
}
}
void fillHoles4C(WORKINGSPACE* WSPC, MAP &SOURCEMAP)
{
if(WSPC->PREVIOUSMAP == NULL) WSPC->PREVIOUSMAP = (MAP*)ZeroAlloc(sizeof(SOURCEMAP));
bool srcChanged = (WSPC->PREVIOUSMAP->SX != SOURCEMAP.SX || WSPC->PREVIOUSMAP->SY != SOURCEMAP.SY);
if(WSPC->HANDWORK[6]==NULL || srcChanged) WSPC->HANDWORK[6] = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); //pixels visit<69>s
if(WSPC->HANDWORK[7]==NULL || srcChanged) WSPC->HANDWORK[7] = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); //XStack
if(WSPC->HANDWORK[8]==NULL || srcChanged) WSPC->HANDWORK[8] = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); //YStack
if(srcChanged)
{
WSPC->PREVIOUSMAP->SX = SOURCEMAP.SX;
WSPC->PREVIOUSMAP->SY = SOURCEMAP.SY;
}
s32 * src = SOURCEMAP.BASE;
s32 * visited = WSPC->HANDWORK[6];
s32 * XStack = WSPC->HANDWORK[7];
s32 * YStack = WSPC->HANDWORK[8];
memcpy(visited, src, SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32));
for(int px=0; px<SOURCEMAP.SX; px++)
{
int py = 0;
if(*(visited + px + py*SOURCEMAP.PITCH)==0)
spreadPx4C(visited, visited, px, py, SOURCEMAP.PITCH, SOURCEMAP.SY, SOURCEMAP.SX, XStack, YStack);
py = SOURCEMAP.SY-1;
if(*(visited + px + py*SOURCEMAP.PITCH)==0)
spreadPx4C(visited, visited, px, py, SOURCEMAP.PITCH, SOURCEMAP.SY, SOURCEMAP.SX, XStack, YStack);
}
for(int py=0; py<SOURCEMAP.SY; py++)
{
int px = 0;
if(*(visited + px + py*SOURCEMAP.PITCH)==0)
spreadPx4C(visited, visited, px, py, SOURCEMAP.PITCH, SOURCEMAP.SY, SOURCEMAP.SX, XStack, YStack);
px = SOURCEMAP.SX-1;
if(*(visited + px + py*SOURCEMAP.PITCH)==0)
spreadPx4C(visited, visited, px, py, SOURCEMAP.PITCH, SOURCEMAP.SY, SOURCEMAP.SX, XStack, YStack);
}
for(int px=0; px<SOURCEMAP.SX; px++)
for(int py=0; py<SOURCEMAP.SY; py++)
{
if(*(visited + px + py*SOURCEMAP.PITCH)==0)
{
if(!(px==0 || py==0 || px==(SOURCEMAP.SX-1) || py==(SOURCEMAP.SY-1)))
spreadPx4C(visited, src, px, py, SOURCEMAP.PITCH, SOURCEMAP.SY, SOURCEMAP.SX, XStack, YStack);
}
}
}
void fillHoles(WORKINGSPACE* WSPC, MAP &SOURCEMAP)
{
if(WSPC->PREVIOUSMAP == NULL) WSPC->PREVIOUSMAP = (MAP*)ZeroAlloc(sizeof(SOURCEMAP));
bool srcChanged = (WSPC->PREVIOUSMAP->SX != SOURCEMAP.SX || WSPC->PREVIOUSMAP->SY != SOURCEMAP.SY);
if(WSPC->HANDWORK[6]==NULL || srcChanged) WSPC->HANDWORK[6] = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); //pixels visit<69>s
if(WSPC->HANDWORK[7]==NULL || srcChanged) WSPC->HANDWORK[7] = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); //XStack
if(WSPC->HANDWORK[8]==NULL || srcChanged) WSPC->HANDWORK[8] = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); //YStack
if(srcChanged)
{
WSPC->PREVIOUSMAP->SX = SOURCEMAP.SX;
WSPC->PREVIOUSMAP->SY = SOURCEMAP.SY;
}
s32 * src = SOURCEMAP.BASE;
s32 * visited = WSPC->HANDWORK[6];
s32 * XStack = WSPC->HANDWORK[7];
s32 * YStack = WSPC->HANDWORK[8];
memcpy(visited, src, SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32));
for(int px=0; px<SOURCEMAP.SX; px++)
{
int py = 0;
if(*(visited + px + py*SOURCEMAP.PITCH)==0)
spreadPx(visited, visited, px, py, SOURCEMAP.PITCH, SOURCEMAP.SY, SOURCEMAP.SX, XStack, YStack);
py = SOURCEMAP.SY-1;
if(*(visited + px + py*SOURCEMAP.PITCH)==0)
spreadPx(visited, visited, px, py, SOURCEMAP.PITCH, SOURCEMAP.SY, SOURCEMAP.SX, XStack, YStack);
}
for(int py=0; py<SOURCEMAP.SY; py++)
{
int px = 0;
if(*(visited + px + py*SOURCEMAP.PITCH)==0)
spreadPx(visited, visited, px, py, SOURCEMAP.PITCH, SOURCEMAP.SY, SOURCEMAP.SX, XStack, YStack);
px = SOURCEMAP.SX-1;
if(*(visited + px + py*SOURCEMAP.PITCH)==0)
spreadPx(visited, visited, px, py, SOURCEMAP.PITCH, SOURCEMAP.SY, SOURCEMAP.SX, XStack, YStack);
}
for(int px=0; px<SOURCEMAP.SX; px++)
for(int py=0; py<SOURCEMAP.SY; py++)
{
if(*(visited + px + py*SOURCEMAP.PITCH)==0)
{
if(!(px==0 || py==0 || px==(SOURCEMAP.SX-1) || py==(SOURCEMAP.SY-1)))
spreadPx(visited, src, px, py, SOURCEMAP.PITCH, SOURCEMAP.SY, SOURCEMAP.SX, XStack, YStack);
}
}
}
void handMouse(MAP &SOURCEMAP, DrawInterface * DI, unsigned int textureIndex)
{
static WORKINGSPACE * WSPC = WSPC_CreateWspc(&SOURCEMAP);
static WORKINGSPACE * WSPC2 = WSPC_CreateWspc(&SOURCEMAP);
static MAP MASKMAP = {NULL,NULL,0,0,0};
if (MASKMAP.BASE == NULL)
{
MASKMAP = SOURCEMAP;
MASKMAP.BASE = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32));
}
static s32* originalSrc = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32));
memcpy(originalSrc, SOURCEMAP.BASE, SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32));
static bool googleEarthMode = false;
//r<>cup<75>ration des propri<72>t<EFBFBD>s de la fen<65>tre google earth
HWND hGoogleEarth = FindWindow("QWidget", NULL);
LPRECT lpRect = new tagRECT();
if(hGoogleEarth) GetWindowRect(hGoogleEarth, lpRect);
COPY(&SOURCEMAP, &MASKMAP);
showSkin(MASKMAP, SOURCEMAP, 30, 200, 30, 250, 130, 200);
getBiggestParts(WSPC2, MASKMAP, 100);
getHoles(WSPC2, MASKMAP);
getBiggestParts(WSPC2, MASKMAP, 350);
if(WSPC->PREVIOUSMAP == NULL) WSPC->PREVIOUSMAP = (MAP*)ZeroAlloc(sizeof(SOURCEMAP));
bool srcChanged = (WSPC->PREVIOUSMAP->SX != SOURCEMAP.SX || WSPC->PREVIOUSMAP->SY != SOURCEMAP.SY);
if(WSPC->HANDWORK[1]==NULL || srcChanged) WSPC->HANDWORK[1] = (s32*)ZeroAlloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); //lastCenterPos
if(WSPC->HANDWORK[2]==NULL || srcChanged) WSPC->HANDWORK[2] = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); //XGravity
if(WSPC->HANDWORK[3]==NULL || srcChanged) WSPC->HANDWORK[3] = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); //YGravity
if(WSPC->HANDWORK[4]==NULL || srcChanged) WSPC->HANDWORK[4] = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); //XStackPartInit
if(WSPC->HANDWORK[5]==NULL || srcChanged) WSPC->HANDWORK[5] = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); //YStackPartInit
if(WSPC->HANDWORK[6]==NULL || srcChanged) WSPC->HANDWORK[6] = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); //pixels visit<69>s
if(WSPC->HANDWORK[7]==NULL || srcChanged) WSPC->HANDWORK[7] = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); //XStack
if(WSPC->HANDWORK[8]==NULL || srcChanged) WSPC->HANDWORK[8] = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); //YStack
if(WSPC->HANDWORK[0]==NULL || srcChanged) WSPC->HANDWORK[0] = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); //SumXXYY
if(WSPC->HANDWORK[9]==NULL || srcChanged) WSPC->HANDWORK[9] = (s32*)CC_malloc(SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); //SumXY
if(srcChanged)
{
WSPC->PREVIOUSMAP->SX = SOURCEMAP.SX;
WSPC->PREVIOUSMAP->SY = SOURCEMAP.SY;
}
s32 * src = MASKMAP.BASE;
s32 * PartInitPx = WSPC->HANDWORK[4];
s32 * PartInitPy = WSPC->HANDWORK[5];
s32 * visited = WSPC->HANDWORK[6];
s32 * XStack = WSPC->HANDWORK[7];
s32 * YStack = WSPC->HANDWORK[8];
s32 * Xgrav = WSPC->HANDWORK[2];
s32 * Ygrav = WSPC->HANDWORK[3];
s32 * lastCenterPos = WSPC->HANDWORK[1];
//copie de l'inverse de src dans visited
for(int px=0; px<SOURCEMAP.SX; px++)
for(int py=0; py<SOURCEMAP.SY; py++)
{
*(visited + px + py*SOURCEMAP.PITCH) = 0xffffffff ^ (*(src + px + py*SOURCEMAP.PITCH));
}
memcpy(WSPC->HANDWORK[9], visited, SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32));
int nbParts = 0;
for(int px=0; px<SOURCEMAP.SX; px++)
for(int py=0; py<SOURCEMAP.SY; py++)
{
if(*(visited + px + py*SOURCEMAP.PITCH)==0)
{
spreadPx(visited, visited, px, py, SOURCEMAP.PITCH, SOURCEMAP.SY, SOURCEMAP.SX, XStack, YStack);
*(PartInitPx + nbParts) = px;
*(PartInitPy + nbParts) = py;
nbParts++;
}
}
memcpy(visited, WSPC->HANDWORK[9], SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32));
for(int i=0; i<nbParts; i++)
{
int debOfStack = 0;
int endOfStack = 0;
*XStack = *(PartInitPx + i);
*YStack = *(PartInitPy + i);
int gravityCenterX = 0;
int gravityCenterY = 0;
int nbPixels = 0;
while (endOfStack>=debOfStack)
{
gravityCenterX += *(XStack+debOfStack);
gravityCenterY += *(YStack+debOfStack);
*(visited + *(XStack+debOfStack) + (*(YStack+debOfStack))*SOURCEMAP.PITCH) =-1;
for(int x = -1; x < 2; x++)
for(int y = -1; y < 2; y++)
{
if(*(XStack+debOfStack)+x>=0 && *(YStack+debOfStack)+y>=0 && *(XStack+debOfStack)+x<SOURCEMAP.SX && *(YStack+debOfStack)+y<SOURCEMAP.SY)
{
if(*(visited + *(XStack+debOfStack) + x + (*(YStack+debOfStack) + y)*SOURCEMAP.PITCH) != -1)
{
*(visited + *(XStack+debOfStack) + x + (*(YStack+debOfStack) + y)*SOURCEMAP.PITCH) = -1;
endOfStack++;
*(XStack+endOfStack) = *(XStack+debOfStack) + x;
*(YStack+endOfStack) = *(YStack+debOfStack) + y;
}
}
}
debOfStack++;
nbPixels = debOfStack;
}
gravityCenterX = gravityCenterX/nbPixels;
gravityCenterY = gravityCenterY/nbPixels;
*(Xgrav+i) = gravityCenterX;
*(Ygrav+i) = gravityCenterY;
}
DWORD dwEventFlags = 0;
bool leftPressed = false;
bool middlePressed = false;
bool rightPressed = false;
bool modeRotate = false;
if(nbParts==1)
{
POINT pos;
GetCursorPos(&pos);
if(lastCenterPos[0] && lastCenterPos[1])
{
if(googleEarthMode && hGoogleEarth && GetAsyncKeyState(VK_LBUTTON))
{
pos.x -= 3*(*(Xgrav)-lastCenterPos[0]); //derniere position en X du centre de gravit<69>
pos.y -= 3*(*(Ygrav)-lastCenterPos[1]); //derniere position en Y du centre de gravit<69>
}
else
{
pos.x += 3*(*(Xgrav)-lastCenterPos[0]); //derniere position en X du centre de gravit<69>
pos.y += 3*(*(Ygrav)-lastCenterPos[1]); //derniere position en Y du centre de gravit<69>
}
}
bool clic = (lastCenterPos[2]!=1); //symbolise une fermeture
if(clic //&& lastCenterPos[5]!=0 && lastCenterPos[6]!=0
//&& lastCenterPos[3]!=0 // && (GetTickCount()-lastCenterPos[3])<1000
&& abs(lastCenterPos[5] - *(Xgrav))<15 && abs(lastCenterPos[6] - *(Ygrav))<15)
{
//simple fermeture effectu<74>e
dwEventFlags |= MOUSEEVENTF_LEFTDOWN; //bouton gauche appuy<75>
leftPressed = true;
//if(googleEarthMode && GetWindowRect(hGoogleEarth, lpRect))
//SetCursorPos((lpRect->right+lpRect->left)/2+200, (lpRect->top+lpRect->bottom)/2);
}
else
{
SetCursorPos(pos.x, pos.y);
}
if(clic) lastCenterPos[3] = GetTickCount(); //nb de Millisec apr<70>s un clic
lastCenterPos[0] = *(Xgrav);
lastCenterPos[1] = *(Ygrav);
lastCenterPos[5] = *(Xgrav);
lastCenterPos[6] = *(Ygrav);
}
if(googleEarthMode && hGoogleEarth)
{
if(nbParts==2)
{
int alpha = atan((double)(*(Ygrav)-*(Ygrav+1))/(*(Xgrav)-*(Xgrav+1)))*180/PI;
while(alpha<0 || alpha>=360)
{
if(alpha<0) alpha+=360;
if(alpha>=360) alpha-=360;
}
double diff = abs((double)lastCenterPos[7]-alpha);
while(diff>=360)
{
diff-=360;
}
if(diff>180-45 && diff<180+45) alpha += 180;
while(alpha>=360)
{
alpha-=360;
}
bool clic = (lastCenterPos[2]!=2); //symbolise une deuxi<78>me fermeture
int seuil = 1;
modeRotate = diff>seuil && diff<360-seuil;
//double fermeture effectu<74>e
if(clic)
{
SetCursorPos((lpRect->right+lpRect->left)/2+200, (lpRect->top+lpRect->bottom)/2);
if(modeRotate)
middlePressed = true;
else
rightPressed = true;
}
else
{
diff =(double)lastCenterPos[7]-alpha;
if(diff<=-180) diff+=360;
if(diff>=180) diff-=360;
POINT pos;
GetCursorPos(&pos);
if(modeRotate)
{
//mode rotation
if(GetAsyncKeyState(VK_RBUTTON)) dwEventFlags |= MOUSEEVENTF_RIGHTUP;
if(!GetAsyncKeyState(VK_MBUTTON)) dwEventFlags |= MOUSEEVENTF_MIDDLEDOWN; //bouton central appuy<75>
middlePressed = true;
pos.x -= 6*((int)diff);
}
else
{
int seuil2 = 4; //plus le seuil est petit, plus on rentre en mode inclinaison facilement
if(abs((int)(lastCenterPos[11] - *(Ygrav)))
+ abs((int)(lastCenterPos[9] - *(Ygrav+1))) > seuil2)
{
//mode inclinaison
if(GetAsyncKeyState(VK_RBUTTON)) dwEventFlags |= MOUSEEVENTF_RIGHTUP;
if(!GetAsyncKeyState(VK_MBUTTON)) dwEventFlags |= MOUSEEVENTF_MIDDLEDOWN; //bouton central appuy<75>
middlePressed = true;
pos.y += 1*((int)(lastCenterPos[11] - *(Ygrav)) + (int)(lastCenterPos[9] - *(Ygrav+1)));
}
else
{
//mode zoom
if(GetAsyncKeyState(VK_MBUTTON)) dwEventFlags |= MOUSEEVENTF_MIDDLEUP;
if(!GetAsyncKeyState(VK_RBUTTON)) dwEventFlags |= MOUSEEVENTF_RIGHTDOWN; //bouton droit appuy<75>
rightPressed = true;
int length = (int)sqrt((double)((*(Xgrav)-*(Xgrav+1))*(*(Xgrav)-*(Xgrav+1))+(*(Ygrav)-*(Ygrav+1))*(*(Ygrav)-*(Ygrav+1))));
int previousLength = (int)sqrt((double)((lastCenterPos[8]-lastCenterPos[10])*(lastCenterPos[8]-lastCenterPos[10])+(lastCenterPos[9]-lastCenterPos[11])*(lastCenterPos[9]-lastCenterPos[11])));
pos.y -= 2*(length-previousLength);
}
}
SetCursorPos(pos.x, pos.y);
}
lastCenterPos[10] = *(Xgrav);
lastCenterPos[11] = *(Ygrav);
lastCenterPos[8] = *(Xgrav+1);
lastCenterPos[9] = *(Ygrav+1);
lastCenterPos[5] = 0;
lastCenterPos[6] = 0;
lastCenterPos[7] = alpha;
}
}
if(nbParts!=1)
lastCenterPos[0] = lastCenterPos[1] = 0;
int buttonValue;
buttonValue = GetAsyncKeyState(VK_LBUTTON);
/*
if(nbParts==0 && GetAsyncKeyState(VK_LBUTTON) && leftPressed)
{
dwEventFlags |= MOUSEEVENTF_LEFTUP; //bouton gauche relach<63>
leftPressed = false;
}
*/
/*
if(nbParts==0 && GetAsyncKeyState(VK_MBUTTON) && middlePressed)
{
dwEventFlags |= MOUSEEVENTF_MIDDLEUP; //bouton gauche relach<63>
middlePressed = false;
}
if(nbParts==0 && GetAsyncKeyState(VK_RBUTTON) && rightPressed)
{
dwEventFlags |= MOUSEEVENTF_RIGHTUP; //bouton gauche relach<63>
rightPressed = false;
}
*/
if(lastCenterPos[2]!=0 && nbParts==0)
leftPressed = true;
if(nbParts!=1 && GetAsyncKeyState(VK_LBUTTON) && leftPressed)
{
dwEventFlags |= MOUSEEVENTF_LEFTUP; //bouton gauche relach<63>
}
if(nbParts!=2 && GetAsyncKeyState(VK_MBUTTON))
{
dwEventFlags |= MOUSEEVENTF_MIDDLEUP; //bouton central relach<63>
middlePressed = false;
}
if(nbParts!=2 && GetAsyncKeyState(VK_RBUTTON))
{
dwEventFlags |= MOUSEEVENTF_RIGHTUP; //bouton droit relach<63>
rightPressed = false;
}
lastCenterPos[2] = nbParts; //dernier nombre de trous
mouse_event(dwEventFlags, 0, 0, 0, 0); //envoie des actions <20> la souris
memcpy(visited, WSPC->HANDWORK[9], SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32));
for(int i=0; i<nbParts; i++)
{
int debOfStack = 0;
int endOfStack = 0;
*XStack = *(PartInitPx + i);
*YStack = *(PartInitPy + i);
int sumXY = 0;
int sumXX = 0;
int sumYY = 0;
int gravityCenterX = *(Xgrav+i);
int gravityCenterY = *(Ygrav+i);
while (endOfStack>=debOfStack)
{
sumXY += 2*(*(XStack+debOfStack)-gravityCenterX)*(*(YStack+debOfStack)-gravityCenterY);
sumXX += (gravityCenterX-*(XStack+debOfStack))*(gravityCenterX-*(XStack+debOfStack));
sumYY += (gravityCenterY-*(YStack+debOfStack))*(gravityCenterY-*(YStack+debOfStack));
*(visited + *(XStack+debOfStack) + (*(YStack+debOfStack))*SOURCEMAP.PITCH) =-1;
for(int x = -1; x < 2; x++)
for(int y = -1; y < 2; y++)
{
if(*(XStack+debOfStack)+x>=0 && *(YStack+debOfStack)+y>=0 && *(XStack+debOfStack)+x<SOURCEMAP.SX && *(YStack+debOfStack)+y<SOURCEMAP.SY)
{
if(*(visited + *(XStack+debOfStack) + x + (*(YStack+debOfStack) + y)*SOURCEMAP.PITCH) != -1)
{
*(visited + *(XStack+debOfStack) + x + (*(YStack+debOfStack) + y)*SOURCEMAP.PITCH) = -1;
endOfStack++;
*(XStack+endOfStack) = *(XStack+debOfStack) + x;
*(YStack+endOfStack) = *(YStack+debOfStack) + y;
}
}
}
debOfStack++;
}
if(sumXX!=sumYY)
{
double delta = (double)sumXY/(double)(sumXX-sumYY);
double alpha = (atan(delta)/2+(PI/180*(45-45*((abs(sumXX-sumYY))/(sumXX-sumYY)))))*180.0/PI;
while(alpha<0 || alpha>=360)
{
if(alpha<0) alpha+=360;
if(alpha>=360) alpha-=360;
}
double diff = abs((double)lastCenterPos[4]-alpha);
while(diff>=360)
{
diff-=360;
}
if(diff>180-45 && diff<180+45) alpha += 180;
while(alpha>=360)
{
alpha-=360;
}
lastCenterPos[4] = alpha;
int lineSizeX = 0;
int lineSizeX2 = 0;
int Mx;
int My;
int pixel;
do
{
Mx = gravityCenterX + lineSizeX*cos(PI/180.0*alpha);
My = gravityCenterY + lineSizeX*sin(PI/180.0*alpha);
lineSizeX++;
pixel = *(MASKMAP.BASE + Mx + My*MASKMAP.PITCH);
}while((Mx>=0 && My>=0 && Mx<SOURCEMAP.SX && My<SOURCEMAP.SY) && pixel==-1);
alpha+=180;
do
{
Mx = gravityCenterX + lineSizeX2*cos(PI/180.0*alpha);
My = gravityCenterY + lineSizeX2*sin(PI/180.0*alpha);
lineSizeX2++;
pixel = *(MASKMAP.BASE + Mx + My*MASKMAP.PITCH);
}while((Mx>=0 && My>=0 && Mx<SOURCEMAP.SX && My<SOURCEMAP.SY) && pixel==-1);
if(lineSizeX2>lineSizeX) lineSizeX = lineSizeX2;
alpha+=90;
int lineSizeY = 0;
int lineSizeY2 = 0;
do
{
Mx = gravityCenterX + lineSizeY*cos(PI/180.0*alpha);
My = gravityCenterY + lineSizeY*sin(PI/180.0*alpha);
lineSizeY++;
pixel = *(MASKMAP.BASE + Mx + My*MASKMAP.PITCH);
}while((Mx>=0 && My>=0 && Mx<SOURCEMAP.SX && My<SOURCEMAP.SY) && pixel==-1);
alpha+=180;
do
{
Mx = gravityCenterX + lineSizeY2*cos(PI/180.0*alpha);
My = gravityCenterY + lineSizeY2*sin(PI/180.0*alpha);
lineSizeY2++;
pixel = *(MASKMAP.BASE + Mx + My*MASKMAP.PITCH);
}while((Mx>=0 && My>=0 && Mx<SOURCEMAP.SX && My<SOURCEMAP.SY) && pixel==-1);
if(lineSizeY2>lineSizeY) lineSizeY = lineSizeY2;
lineSizeX += 10;
lineSizeY += 5;
alpha-=180+90;
int x;
int y;
int color = makeRGB(255,0,0);
if(nbParts==1) color = makeRGB(0,255,0);
if((GetAsyncKeyState(VK_LBUTTON) || leftPressed) && nbParts==1) color = makeRGB(255,255,0);
if((GetAsyncKeyState(VK_MBUTTON) || middlePressed) && nbParts==2 && modeRotate) color = makeRGB(0,255,0);
if((GetAsyncKeyState(VK_MBUTTON) || middlePressed) && nbParts==2 && !modeRotate) color = makeRGB(250,120,0);
if((GetAsyncKeyState(VK_RBUTTON) || rightPressed) && nbParts==2) color = makeRGB(255,255,0);
for(int px=0; px<SOURCEMAP.SX; px++)
{
for(int py=0; py<SOURCEMAP.SY; py++)
{
x = (py-gravityCenterY)*sin(PI/180.0*alpha)+(px-gravityCenterX)*cos(PI/180.0*alpha);
y = (py-gravityCenterY)*cos(PI/180.0*alpha)-(px-gravityCenterX)*sin(PI/180.0*alpha);
if((double)((x)*(x))/(double)(lineSizeX*lineSizeX)
+(double)((y)*(y))/(double)(lineSizeY*lineSizeY) < 1)
{
pixel = getY(*(SOURCEMAP.BASE + px + py*SOURCEMAP.PITCH));
*(SOURCEMAP.BASE + px + py*SOURCEMAP.PITCH) = makeRGB((pixel+getR(color))/2, (pixel+getV(color))/2, (pixel+getB(color))/2);
}
}
}
}
}
int tmp;
for(int px=0; px<SOURCEMAP.SX; px++)
for(int py=0; py<SOURCEMAP.SY/2; py++)
{
tmp = *(SOURCEMAP.BASE + px + py*SOURCEMAP.PITCH);
*(SOURCEMAP.BASE + px + py*SOURCEMAP.PITCH) = *(SOURCEMAP.BASE + px + (SOURCEMAP.SY-1-py)*SOURCEMAP.PITCH);
*(SOURCEMAP.BASE + px + (SOURCEMAP.SY-1-py)*SOURCEMAP.PITCH) = tmp;
}
static bool previousCtrlState = false;
char * state = (char *)ZeroAlloc(30*sizeof(char));
sprintf(state, "HAND-MOUSE ON");
DRawTEXT_Soft_B((unsigned char*)state, (unsigned int*)SOURCEMAP.BASE, 10, 25, SOURCEMAP.PITCH, SOURCEMAP.SY, 255<<8);
static bool previousGState = false;
if((!GetAsyncKeyState(0x47) || !GetAsyncKeyState(VK_CONTROL)) && previousGState==true && previousCtrlState)
{
googleEarthMode = !googleEarthMode;
if(GetAsyncKeyState(VK_LBUTTON)) mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
if(GetAsyncKeyState(VK_MBUTTON)) mouse_event(MOUSEEVENTF_MIDDLEUP,0,0,0,0);
if(GetAsyncKeyState(VK_RBUTTON)) mouse_event(MOUSEEVENTF_RIGHTUP,0,0,0,0);
if(googleEarthMode && hGoogleEarth)
{
if(hGoogleEarth!=GetForegroundWindow())
{
SetForegroundWindow(hGoogleEarth);
Sleep(100);
}
SetCursorPos((lpRect->right+lpRect->left)/2+200, (lpRect->top+lpRect->bottom)/2);
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
Sleep(200);
keybd_event(VK_CONTROL,0,0,0);
keybd_event(0x54,0,0,0);
keybd_event(0x54,0,KEYEVENTF_KEYUP,0);
keybd_event(VK_CONTROL,0,KEYEVENTF_KEYUP,0);
SetCursorPos((lpRect->right+lpRect->left)/2+202, (lpRect->top+lpRect->bottom)/2);
}
if(!googleEarthMode && hGoogleEarth)
{
Sleep(200);
keybd_event(VK_CONTROL,0,0,0);
keybd_event(0x54,0,0,0);
keybd_event(0x54,0,KEYEVENTF_KEYUP,0);
keybd_event(VK_CONTROL,0,KEYEVENTF_KEYUP,0);
POINT pt;
GetCursorPos(&pt);
SetCursorPos(pt.x+2, pt.y);
}
}
previousGState = (bool)GetAsyncKeyState(0x47);
previousCtrlState = (bool)GetAsyncKeyState(VK_CONTROL);
char * state2 = (char *)ZeroAlloc(30*sizeof(char));
if(googleEarthMode)
{
sprintf(state2, "GOOGLE EARTH MODE ON");
DRawTEXT_Soft_B((unsigned char*)state2, (unsigned int*)SOURCEMAP.BASE, 10, 10, SOURCEMAP.PITCH, SOURCEMAP.SY, 255<<8);
}
else
{
sprintf(state2, "GOOGLE EARTH MODE OFF");
DRawTEXT_Soft_B((unsigned char*)state2, (unsigned int*)SOURCEMAP.BASE, 10, 10, SOURCEMAP.PITCH, SOURCEMAP.SY, 255<<16);
}
DI->UpdateTexture_BM_2_HW(textureIndex);
memcpy(SOURCEMAP.BASE, originalSrc, SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32));
}
u32 trackHands(WORKINGSPACE* WSPC, MAP &SOURCEMAP)
{
//if(WSPC->bDrawHands);
return 1;
}
void applyTransf(WORKINGSPACE* WSPC, s32 * imC, int PITCH, int Height, int Width)
{
if(WSPC->PREVIOUSMAP == NULL) WSPC->bFirstFrame = 1;
if(WSPC->bFirstFrame)
{
WSPC->PREVIOUSMAP = (MAP*)ZeroAlloc(sizeof(MAP));
WSPC->PREVIOUSMAP->BASE = (s32*)ZeroAlloc(Height*Width*sizeof(s32));
}
s32 * imP = WSPC->PREVIOUSMAP->BASE;
if(!WSPC->bFirstFrame)
{
for(int px=0;px<Width;px++)
{
for(int py=0;py<Height;py++)
{
s32 pixel = abs(getY(*(imC + px + py*PITCH)) - getY(*(imP + px + py*PITCH)));
*(imC + px + py*PITCH) = makeRGB(pixel, pixel, pixel);
}
}
}
WSPC->bFirstFrame = 0;
}
void filterImgRVB(MAP& mapFiltered, MAP& mapRGB, MAP& imgTmp)
{
s32 * imgFiltered = mapFiltered.BASE;
s32 * imgRGB = mapRGB.BASE;
s32 * tmpFiltered = imgTmp.BASE;
int PITCH = mapRGB.PITCH;
int Height = mapRGB.SY;
int Width = mapRGB.SX;
int sumR, sumV, sumB;
if(imgRGB)
{
for(int px=0;px<Width;px++)
{
for(int py=0;py<Height;py++)
{
if(px==0 || px==Width-1 || py==0 || py==Height-1)
*(imgFiltered + px + py*PITCH) = *(imgRGB + px + py*PITCH);
else
{
sumR = getR(*(imgRGB + px + py*PITCH))
+getR(*(imgRGB + px + py*PITCH - PITCH))
+getR(*(imgRGB + px + py*PITCH + PITCH))
+getR(*(imgRGB + px - 1 + py*PITCH - PITCH))
+getR(*(imgRGB + px - 1 + py*PITCH + PITCH))
+getR(*(imgRGB + px - 1 + py*PITCH))
+getR(*(imgRGB + px + 1 + py*PITCH + PITCH))
+getR(*(imgRGB + px + 1 + py*PITCH - PITCH))
+getR(*(imgRGB + px + 1 + py*PITCH));
sumV = getV(*(imgRGB + px + py*PITCH))
+getV(*(imgRGB + px + py*PITCH - PITCH))
+getV(*(imgRGB + px + py*PITCH + PITCH))
+getV(*(imgRGB + px - 1 + py*PITCH - PITCH))
+getV(*(imgRGB + px - 1 + py*PITCH + PITCH))
+getV(*(imgRGB + px - 1 + py*PITCH))
+getV(*(imgRGB + px + 1 + py*PITCH + PITCH))
+getV(*(imgRGB + px + 1 + py*PITCH - PITCH))
+getV(*(imgRGB + px + 1 + py*PITCH));
sumB = getB(*(imgRGB + px + py*PITCH))
+getB(*(imgRGB + px + py*PITCH - PITCH))
+getB(*(imgRGB + px + py*PITCH + PITCH))
+getB(*(imgRGB + px - 1 + py*PITCH - PITCH))
+getB(*(imgRGB + px - 1 + py*PITCH + PITCH))
+getB(*(imgRGB + px - 1 + py*PITCH))
+getB(*(imgRGB + px + 1 + py*PITCH + PITCH))
+getB(*(imgRGB + px + 1 + py*PITCH - PITCH))
+getB(*(imgRGB + px + 1 + py*PITCH));
*(tmpFiltered + px + py*PITCH) = makeRGB(sumR/9, sumV/9, sumB/9);
}
}
}
memcpy(imgFiltered, tmpFiltered, Width*Height*sizeof(s32));
}
}
void filterImgRVB(s32 * imgFiltered, s32 * imgRGB, int PITCH, int Height, int Width)
{
s32 * tmpFiltered = (s32*)CC_malloc(Height*Width*sizeof(s32));
int sumR, sumV, sumB;
if(imgRGB)
{
for(int px=0;px<Width;px++)
{
for(int py=0;py<Height;py++)
{
if(px==0 || px==Width-1 || py==0 || py==Height-1)
*(imgFiltered + px + py*PITCH) = *(imgRGB + px + py*PITCH);
else
{
sumR = getR(*(imgRGB + px + py*PITCH))
+getR(*(imgRGB + px + py*PITCH - PITCH))
+getR(*(imgRGB + px + py*PITCH + PITCH))
+getR(*(imgRGB + px - 1 + py*PITCH - PITCH))
+getR(*(imgRGB + px - 1 + py*PITCH + PITCH))
+getR(*(imgRGB + px - 1 + py*PITCH))
+getR(*(imgRGB + px + 1 + py*PITCH + PITCH))
+getR(*(imgRGB + px + 1 + py*PITCH - PITCH))
+getR(*(imgRGB + px + 1 + py*PITCH));
sumV = getV(*(imgRGB + px + py*PITCH))
+getV(*(imgRGB + px + py*PITCH - PITCH))
+getV(*(imgRGB + px + py*PITCH + PITCH))
+getV(*(imgRGB + px - 1 + py*PITCH - PITCH))
+getV(*(imgRGB + px - 1 + py*PITCH + PITCH))
+getV(*(imgRGB + px - 1 + py*PITCH))
+getV(*(imgRGB + px + 1 + py*PITCH + PITCH))
+getV(*(imgRGB + px + 1 + py*PITCH - PITCH))
+getV(*(imgRGB + px + 1 + py*PITCH));
sumB = getB(*(imgRGB + px + py*PITCH))
+getB(*(imgRGB + px + py*PITCH - PITCH))
+getB(*(imgRGB + px + py*PITCH + PITCH))
+getB(*(imgRGB + px - 1 + py*PITCH - PITCH))
+getB(*(imgRGB + px - 1 + py*PITCH + PITCH))
+getB(*(imgRGB + px - 1 + py*PITCH))
+getB(*(imgRGB + px + 1 + py*PITCH + PITCH))
+getB(*(imgRGB + px + 1 + py*PITCH - PITCH))
+getB(*(imgRGB + px + 1 + py*PITCH));
*(tmpFiltered + px + py*PITCH) = makeRGB(sumR/9, sumV/9, sumB/9);
}
}
}
memcpy(imgFiltered, tmpFiltered, Height*Width*sizeof(s32));
}
CC_free(tmpFiltered);
tmpFiltered = 0;
}
void filterImg(s32 * imgG, s32 * imgRGB, int PITCH, int Height, int Width)
{
int sumInt;
for(int px=0;px<Width;px++)
{
for(int py=0;py<Height;py++)
{
if(px==0 || px==Width-1 || py==0 || py==Height-1)
*(imgG + px + py*PITCH) = getY(*(imgRGB + px + py*PITCH));
else
{//filtre moyenneur en 8-voisinage
sumInt = getY(*(imgRGB + px + py*PITCH))
+getY(*(imgRGB + px + py*PITCH - PITCH))
+getY(*(imgRGB + px + py*PITCH + PITCH))
+getY(*(imgRGB + px - 1 + py*PITCH - PITCH))
+getY(*(imgRGB + px - 1 + py*PITCH + PITCH))
+getY(*(imgRGB + px - 1 + py*PITCH))
+getY(*(imgRGB + px + 1 + py*PITCH + PITCH))
+getY(*(imgRGB + px + 1 + py*PITCH - PITCH))
+getY(*(imgRGB + px + 1 + py*PITCH));
*(imgG + px + py*PITCH) = sumInt/9;
}
}
}
}