#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; pyImage.SY; py++) { for(int px=0; pxImage.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]Image.SX && py+vy[v]>=0 && py+vy[v]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; pyImage.SY-1; py++) { for(int px=1; pxImage.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; pxImage.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; pyImage.SY; py++) { for(int px=0; pxImage.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]Image.SX && py+vy[v]>=0 && py+vy[v]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 à 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]Image.SX && y+vy[v]>=0 && y+vy[v]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; pxImage.SX*ID_MEDIA[Mask1]->Image.SY*sizeof(s32)); for(int px=0; pxHANDWORK[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>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; pxImage.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; pyImage.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; pxImage.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; hImage.BASE + niv + h*ID_MEDIA[MediaDest]->Image.PITCH) = makeRGB(200, 200, 0); } for(int h = 0; hImage.BASE + niv + (h + 100)*ID_MEDIA[MediaDest]->Image.PITCH) = makeRGB(0, 150, 150); } for(int h = 0; hImage.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 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; x3 || 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é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 é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é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 à partir d'une en RVB } else { COPY_BW(&srcMap, &srcMapBlurred); LF_GaussianFilter(&srcMapBlurred, &srcMapBlurred, &tmpMap, 1, 3);//donne une image en BW à partir d'une en BW } } //TODO : calcul d'erreur différent selon si on travaille sur une image blurée en niveaux de gris ou en couleur //TODO : demander pour meilleur filtre pour image RGB de webcam dans Pandore à 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 à trouver int vx, vy; //-> mise à 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écédente // par parcours des blocs de l'image source courante for(int i=0; imaxRC+maxVC+maxBC)) { maxRC = getR(currentPixel); maxVC = getV(currentPixel); maxBC = getB(currentPixel); } if((sumPixelCmaxRP+maxVP+maxBP)) { maxRP = getR(previousPixel); maxVP = getV(previousPixel); maxBP = getB(previousPixel); } if((sumPixelPPREVIOUSMAP == 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 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-1 && (k+v+tbloc)-1 && (l+u+tbloc) 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-1 && (k+v+tbloc)-1 && (l+u+tbloc) 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)-1 && (l+umin+u+tbloc) 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;pyHANDWORK[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 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 été 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è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é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éation des signatures des points de réfé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))<>31))<>31))<>31))<>31))<>31))<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é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é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=0 && x+maxWidth/2=0 && y45 && 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=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)+x0.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ération du point le plus haut dans la forme sélectionnée memset(workBuffer3, 0, SX*SY*sizeof(s32)); memset(visited, 0, SX*SY*sizeof(s32)); for(int px=0; px=0 && x+maxWidth/2=0 && y45 && 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é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émité de doigt a été repéré 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=0 && yFingerPos+j180) angle -= 180; float coeffDir = tan((angle)*3.14/180.0); int x = xFingerPos; int y = yFingerPos; while((x>=0 && y>=0 && x45 && 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 && x45 && 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 && x45 && 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=0 && y>=0 && x45 && 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=0 && xFingerPos+i=0 && yFingerPos+j=0 && y>=0 && x=0 && y>=0 && x45 && 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=0 && y>=0 && x45 && 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é 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=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 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=180) { if(alpha<0) alpha+=180; if(alpha>=180) alpha-=180; } char * angleText = (char *)ZeroAlloc(2*sizeof(char)); sprintf(angleText, "%.2f°", (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é 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 && x45 && 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 && x45 && 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=0 && yFingerExtremity+jObjectNameDico.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-1; py+=inc) { for(px=0; 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]=0 && py+vy[v]=0 && x+vx[v]=0 && y+vy[v]=0 && x+vx[v2]=0 && y+vy[v2]=0 && x+vx[v2]Image.SX && y+vy[v2]>=0 && y+vy[v2]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émités for(int i=0; i=0 && Pixels2X[i]+vx[v2]=0 && Pixels2Y[i]+vy[v2]=0 && Pixels1X[i]+vx[v2]=0 && Pixels1Y[i]+vy[v2]=0 && x+i=0 && y+j=0 && x+vx[v]=0 && y+vy[v]=0 && x+vx[v2]=0 && y+vy[v2]=0 && x+v2=0 && y+v2=0 && x+vx[v]=0 && y+vy[v]=0 && x+vx[v]=0 && y+vy[v]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=0 && y+v215) 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)+xgetY(voisin)) YMin = getY(voisin); if(YMaxgetCb(voisin)) CbMin = getCb(voisin); if(CbMaxgetCr(voisin)) CrMin = getCr(voisin); if(CrMaxYMax) { 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=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=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=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)+xPREVIOUSMAP == 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é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= 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; iPREVIOUSMAP == 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é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; pxPREVIOUSMAP == 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é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; pxPREVIOUSMAP == 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é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; pxPREVIOUSMAP == 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é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; pxHANDWORK[9], visited, SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); int nbParts = 0; for(int px=0; pxHANDWORK[9], SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); for(int i=0; i=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)+xright+lpRect->left)/2+200, (lpRect->top+lpRect->bottom)/2); } else { SetCursorPos(pos.x, pos.y); } if(clic) lastCenterPos[3] = GetTickCount(); //nb de Millisec aprè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ème fermeture int seuil = 1; modeRotate = diff>seuil && diff<360-seuil; //double fermeture effectué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é 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é 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é 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é leftPressed = false; } */ /* if(nbParts==0 && GetAsyncKeyState(VK_MBUTTON) && middlePressed) { dwEventFlags |= MOUSEEVENTF_MIDDLEUP; //bouton gauche relaché middlePressed = false; } if(nbParts==0 && GetAsyncKeyState(VK_RBUTTON) && rightPressed) { dwEventFlags |= MOUSEEVENTF_RIGHTUP; //bouton gauche relaché rightPressed = false; } */ if(lastCenterPos[2]!=0 && nbParts==0) leftPressed = true; if(nbParts!=1 && GetAsyncKeyState(VK_LBUTTON) && leftPressed) { dwEventFlags |= MOUSEEVENTF_LEFTUP; //bouton gauche relaché } if(nbParts!=2 && GetAsyncKeyState(VK_MBUTTON)) { dwEventFlags |= MOUSEEVENTF_MIDDLEUP; //bouton central relaché middlePressed = false; } if(nbParts!=2 && GetAsyncKeyState(VK_RBUTTON)) { dwEventFlags |= MOUSEEVENTF_RIGHTUP; //bouton droit relaché rightPressed = false; } lastCenterPos[2] = nbParts; //dernier nombre de trous mouse_event(dwEventFlags, 0, 0, 0, 0); //envoie des actions à la souris memcpy(visited, WSPC->HANDWORK[9], SOURCEMAP.SX*SOURCEMAP.SY*sizeof(s32)); for(int i=0; i=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=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=0 && My>=0 && MxlineSizeX) 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=0 && My>=0 && MxlineSizeY) 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; pxright+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;pxbFirstFrame = 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