3530 lines
112 KiB
C++
3530 lines
112 KiB
C++
#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;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|