739 lines
19 KiB
C++
739 lines
19 KiB
C++
#define _WIN32_WINNT 0x500
|
|
#include "SCENE.H"
|
|
#include <windows.h>
|
|
#include <process.h>
|
|
|
|
u32 WORLD::VALIDATE_ID(u32 ID)
|
|
{
|
|
TRACK_Synchronise_Multithread();
|
|
if ((ID <= MAX_ID)&&(ID_TABLE[ID] != NULL))
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
float NoisThreshold = 0.5f;
|
|
|
|
Vector CursorDoubleSpeed(Vector &V)
|
|
{
|
|
float Norm;
|
|
V.y *= 1.2f;
|
|
return V;
|
|
}
|
|
|
|
extern MATRIX FACE_FROMHAAR;
|
|
|
|
typedef struct TRACK_OneFrameCall_Parrams_
|
|
{
|
|
WORKINGSPACE *WSPC;
|
|
IDFX **ID_TABLE;
|
|
HeadDetector *pHeadDetector;
|
|
HANDLE AccesMutexA;
|
|
HANDLE AccesMutexB;
|
|
HANDLE AccesMutexComputeBackGround;
|
|
u32 InputthreadID;
|
|
u32 volatile State;
|
|
WORLD *p_Owner;
|
|
} TRACK_OneFrameCall_Parrams;
|
|
|
|
void GID_SetScale(IDFX *pId,Vector *pNewScale)
|
|
{
|
|
if ((pNewScale->x < 0.1) || (pNewScale->y < 0.1) || (pNewScale->z < 0.1))
|
|
*(u32 *)0 = *(u32 *)1;
|
|
|
|
|
|
{
|
|
if ((pNewScale->x == pId->vModelScale.x) &&
|
|
(pNewScale->y == pId->vModelScale.y) &&
|
|
(pNewScale->z == pId->vModelScale.z))
|
|
return;
|
|
if (pId->vModelScale.SqrNorm() == 0)
|
|
pId->vModelScale = Vector(1,1,1);
|
|
Vector Mult;
|
|
u32 Counter;
|
|
Mult.x = pNewScale->x / pId->vModelScale.x;
|
|
Mult.y = pNewScale->y / pId->vModelScale.y;
|
|
Mult.z = pNewScale->z / pId->vModelScale.z;
|
|
Counter = pId->p_UsedMesh->NumberOfPoints;
|
|
while (Counter--)
|
|
pId->p_UsedMesh->Points[Counter] &= Mult;
|
|
pId->vModelScale = *pNewScale;
|
|
}
|
|
}
|
|
|
|
unsigned __stdcall TRACK_OneFrameCall_THREAD(void *params)
|
|
{
|
|
TRACK_OneFrameCall_Parrams *P;
|
|
P = (TRACK_OneFrameCall_Parrams *)params;
|
|
//SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_BELOW_NORMAL );
|
|
while (P->State != 2)
|
|
{
|
|
/* Compress Size HERE */
|
|
/*void DrawingEffect(MAP *CurrentMap,s32 Denoise1);
|
|
DrawingEffect(P->WSPC->RENDERMAP,1);*/
|
|
#ifdef TEST_PHILIPPE
|
|
//void Segmenting(MAP *CurrentMap);
|
|
//Segmenting(P->WSPC->RENDERMAP);
|
|
void TEST(MAP *CurrentMap);
|
|
TEST(P->WSPC->RENDERMAP);
|
|
#endif
|
|
void SetBackGround(MAP *CurrentMap,MAP *ZMap,s32 Color);
|
|
SetBackGround(P->WSPC->RENDERMAP,P->WSPC->ZBUFFERMAP,1);
|
|
|
|
//ReleaseSemaphore(P->AccesMutexComputeBackGround,1,NULL);
|
|
|
|
//*/
|
|
START_RASTER(Track_Match2D3D);
|
|
if (P->WSPC->RENDERMAP->GetBase() != P->WSPC->DRAWMAP->GetBase())
|
|
COPY_OX_RGBA(P->WSPC->RENDERMAP,P->WSPC->DRAWMAP);
|
|
STOP_RASTER(Track_Match2D3D);
|
|
|
|
START_RASTER(Track_FaceDetection);
|
|
/* Face detector */
|
|
P->pHeadDetector->SetDrawImage(P->WSPC->RENDERMAP);
|
|
P->pHeadDetector->ProcessImage(P->WSPC->DRAWMAP);
|
|
|
|
if (1)
|
|
{
|
|
IDFX **Parser = P->ID_TABLE;
|
|
for ( u32 Counter = 0 ; Counter < MAX_ID ; Counter++,Parser++)
|
|
{
|
|
if ((*Parser) && (!(*Parser)->SF_T.IsAnimatedTrack))
|
|
{
|
|
if (((*Parser)->SF_T.ViolaStart) && (P->pHeadDetector->GetNumberOfFace()))
|
|
{
|
|
Vector Center,Size;
|
|
P->pHeadDetector->GetFace(0, &Center,&Size);
|
|
{
|
|
ID_RESET((*Parser));
|
|
|
|
float ZATB = 980.0f;
|
|
float Alpha = Center.z;
|
|
ZATB /= Size.x / 8.0f;
|
|
Center *= 2.0f * ZATB / (float)P->WSPC->DRAWMAP->SX;
|
|
Center.x -= ZATB ;
|
|
Center.y -= ((float)P->WSPC->DRAWMAP->SY / (float)P->WSPC->DRAWMAP->SX) * ZATB ;
|
|
Center *= 2.0f / (*Parser)->p_UsedMesh->Focale;
|
|
Center.z = 2.0f * ZATB;
|
|
(*Parser)->CurrentMatrix_T.Identity();
|
|
(*Parser)->CurrentMatrix_T.T = Center ;
|
|
/* (*Parser)->SF_T.ViolaStart = 1;
|
|
(*Parser)->SF_T.Ready2Learn = 0;*/
|
|
(*Parser)->SF_T.DrawMesh = 0;
|
|
|
|
|
|
(*Parser)->CurrentMatrix_T.K = (*Parser)->CurrentMatrix_T.T ;
|
|
(*Parser)->CurrentMatrix_T.K.y= 0;
|
|
(*Parser)->CurrentMatrix_T.K.Normalize();
|
|
(*Parser)->CurrentMatrix_T.I = (*Parser)->CurrentMatrix_T.J^(*Parser)->CurrentMatrix_T.K;
|
|
(*Parser)->CurrentMatrix_T.I.Normalize();
|
|
(*Parser)->CurrentMatrix_T.J = (*Parser)->CurrentMatrix_T.K^(*Parser)->CurrentMatrix_T.I;
|
|
(*Parser)->CurrentMatrix_T.J.Normalize();
|
|
(*Parser)->CurrentMatrix_T.T += (*Parser)->CurrentMatrix_T.J * 5.5f;
|
|
|
|
(*Parser)->CurrentMatrix_T.RotateAround_K(Alpha);
|
|
|
|
Vector RE,LE,RM,LM,Scale;
|
|
Scale = Vector(1,1.1,1);
|
|
if (
|
|
P->pHeadDetector->GetFaceFeature(0, 0, &RE) &&
|
|
P->pHeadDetector->GetFaceFeature(0, 1, &LE) &&
|
|
P->pHeadDetector->GetFaceFeature(0, 3, &LM) &&
|
|
P->pHeadDetector->GetFaceFeature(0, 4, &RM))
|
|
{
|
|
Vector Local,Local2;
|
|
Local = RE - LE;
|
|
Local2 = ((RE + LE) - (LM + RM)) * 0.5f;
|
|
float VSale;
|
|
VSale = 1.0f * Local2.NormXY() / Local.NormXY();
|
|
VSale = (1.0f + VSale) / 2.0f;
|
|
if (VSale < 0.8f) VSale = 0.8f;
|
|
if (VSale > 1.3f) VSale = 1.3f;
|
|
Local = Vector(1,VSale,1);
|
|
Scale &= Local;
|
|
|
|
}
|
|
GID_SetScale((*Parser), &Scale);
|
|
(*Parser)->SF_T.ViolaStart = 0;
|
|
(*Parser)->SF_T.Ready2Learn = 1;
|
|
(*Parser)->CurrentMatrix_U = (*Parser)->CurrentMatrix_T;
|
|
(*Parser)->CurrentMatrix_UNS = (*Parser)->CurrentMatrix_T;
|
|
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
STOP_RASTER(Track_FaceDetection);
|
|
|
|
|
|
{
|
|
u32 IDnumber = 0;
|
|
START_RASTER(Track_Match2D3D);
|
|
WSPC_2D_BEGIN(P->WSPC);
|
|
STOP_RASTER(Track_Match2D3D);
|
|
|
|
IDFX **Parser = P->ID_TABLE;
|
|
for ( u32 Counter = 0 ; Counter < MAX_ID ; Counter++,Parser++)
|
|
{
|
|
if ((*Parser) && (*Parser)->p_UsedMesh && (!(*Parser)->SF_T.IsAnimatedTrack))
|
|
{
|
|
IDnumber++;
|
|
START_RASTER(Track_Tracker);
|
|
ID_TRACK((*Parser),P->WSPC);
|
|
STOP_RASTER(Track_Tracker);
|
|
}
|
|
}
|
|
START_RASTER(Track_Match2D3D);
|
|
WSPC_2D_END(P->WSPC);//*/
|
|
STOP_RASTER(Track_Match2D3D);
|
|
if (IDnumber > 1)
|
|
{
|
|
P->WSPC->LastMax.x = P->WSPC->LastMax.y = 1000000.0f;
|
|
P->WSPC->LastMax.x = P->WSPC->LastMax.y = 1000000.0f;
|
|
P->WSPC->LastMin.x = P->WSPC->LastMin.y = -1000000.0f;
|
|
P->WSPC->LastMin.x = P->WSPC->LastMin.y = -1000000.0f;
|
|
}
|
|
}
|
|
|
|
|
|
// Release "B"
|
|
//ReleaseSemaphore(P->AccesMutexB,1,NULL);
|
|
// Take "A"
|
|
//WaitForSingleObject(P->AccesMutexA, INFINITE);
|
|
// ==
|
|
|
|
|
|
|
|
SignalObjectAndWait(P->AccesMutexB,P->AccesMutexA,INFINITE, FALSE);
|
|
}
|
|
P->State = 3;
|
|
_endthreadex( 0 );
|
|
return 0;
|
|
}
|
|
|
|
u32 WORLD::TRACK_Synchronise_Multithread()
|
|
{
|
|
// Take "B"
|
|
if (ParramT)
|
|
{
|
|
WaitForSingleObject(ParramT->AccesMutexB, INFINITE);
|
|
ReleaseSemaphore(ParramT->AccesMutexB,1,NULL);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
#define MAX_TRACKER_SIZE 320
|
|
/* Working Call */
|
|
u32 WORLD::TRACK_OneFrameCall(MAP &SOURCEMAP_SRC,MAP *ZMAP)
|
|
{
|
|
static u32 LastAverage = 0;
|
|
static u32 FirstTime = 0;
|
|
u32 GTime,PTime,CTime,NewAverage;
|
|
|
|
//if (ZMAP) COPY(ZMAP,&SOURCEMAP_SRC);
|
|
|
|
MAP SOURCEMAP;
|
|
PTime=CTime=0;
|
|
SOURCEMAP = SOURCEMAP_SRC; SOURCEMAP.staticBase = 1;
|
|
|
|
GTime = timeGetTime();
|
|
|
|
if (trackSize == 0)
|
|
trackSize = MAX_TRACKER_SIZE;
|
|
|
|
/* Eventual Resize */
|
|
if (SOURCEMAP.SX > trackSize)
|
|
{
|
|
float FACTOR;
|
|
FACTOR = (float)trackSize / SOURCEMAP.SX;
|
|
SOURCEMAP.SX *= FACTOR;
|
|
SOURCEMAP.SY *= FACTOR;
|
|
}
|
|
|
|
if (SOURCEMAP.SX <= 32) return 0;
|
|
if (SOURCEMAP.SY <= 32) return 0;
|
|
|
|
if (
|
|
(WSPC != NULL) &&
|
|
(
|
|
(SOURCEMAP.SX != WSPC->DRAWMAP->SX) ||
|
|
(SOURCEMAP.SY != WSPC->DRAWMAP->SY) ||
|
|
(SOURCEMAP_SRC.SX != WSPC->RENDERMAP->SX) ||
|
|
(SOURCEMAP_SRC.SY != WSPC->RENDERMAP->SY)/* ||
|
|
(SOURCEMAP.BASE != WSPC->RENDERMAP->BASE)*/
|
|
)
|
|
)
|
|
{
|
|
DestroyTrackeur();
|
|
WSPC_Destroy(WSPC);
|
|
WSPC = NULL;
|
|
}
|
|
|
|
if (WSPC == NULL)
|
|
{
|
|
if (SOURCEMAP.SX != SOURCEMAP_SRC.SX)
|
|
WSPC = WSPC_CreateWspc(&SOURCEMAP,&SOURCEMAP_SRC,ZMAP);
|
|
else
|
|
WSPC = WSPC_CreateWspc(&SOURCEMAP,NULL,ZMAP);
|
|
}
|
|
|
|
//trackHands(WSPC, SOURCEMAP);
|
|
|
|
if (FirstTime == 0) FirstTime = timeGetTime();
|
|
|
|
|
|
if (!ForceTraking)
|
|
{
|
|
NewAverage = 0;
|
|
for (u32 YCounter = SOURCEMAP.SY >> 2;YCounter < SOURCEMAP.SY - (SOURCEMAP.SY >> 2); YCounter += 2)
|
|
for (u32 XCounter = SOURCEMAP.SX >> 2;XCounter < SOURCEMAP.SX - (SOURCEMAP.SX >> 2); XCounter += 2)
|
|
{
|
|
u32 *Ptr;
|
|
Ptr = (u32*)SOURCEMAP.GetBase() + XCounter + YCounter * SOURCEMAP.PITCH;
|
|
NewAverage += *Ptr & 0xff;
|
|
}
|
|
|
|
|
|
if (NewAverage != LastAverage)
|
|
{
|
|
LastAverage = NewAverage;
|
|
} else
|
|
{
|
|
if (ulSkippedFrameCounter < 128)
|
|
{
|
|
ulSkippedFrameCounter++;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
ulSkippedFrameCounter = 0;
|
|
}
|
|
|
|
if (ParramT == NULL)
|
|
{
|
|
ParramT = (TRACK_OneFrameCall_Parrams *)CC_malloc(sizeof(TRACK_OneFrameCall_Parrams));
|
|
ParramT->pHeadDetector = &headDetector;
|
|
ParramT->WSPC = WSPC;
|
|
ParramT->ID_TABLE = ID_TABLE;
|
|
ParramT->AccesMutexA = CreateSemaphore(NULL, 0, 1,NULL);
|
|
ParramT->AccesMutexB = CreateSemaphore(NULL, 0, 1,NULL);
|
|
//ParramT->AccesMutexComputeBackGround = CreateSemaphore(NULL, 0, 1,NULL);
|
|
ParramT->State = 0;
|
|
ParramT->p_Owner = this;
|
|
_beginthreadex( NULL , 10*1024*1024 , TRACK_OneFrameCall_THREAD , (void *)ParramT , 0 , &ParramT->InputthreadID );
|
|
}
|
|
|
|
|
|
// Take "B"
|
|
#if 0
|
|
if (WaitForSingleObject(ParramT->AccesMutexB, 0) == WAIT_TIMEOUT)
|
|
{
|
|
//WaitForSingleObject(ParramT->AccesMutexComputeBackGround, 100);
|
|
MAP32_COPY(WSPC->RENDERMAP,&SOURCEMAP_SRC);
|
|
return 1;
|
|
}
|
|
#else
|
|
WaitForSingleObject(ParramT->AccesMutexB, INFINITE);
|
|
#endif
|
|
// Acces safely data here
|
|
|
|
// Swap tracked media
|
|
SWAPMAP(WSPC->RENDERMAP,&SOURCEMAP_SRC);
|
|
if (ZMAP) SWAPMAP(WSPC->ZBUFFERMAP,ZMAP);
|
|
|
|
headDetector.CopyAsync();
|
|
|
|
// Swap track results
|
|
{
|
|
IDFX **Parser = ID_TABLE;
|
|
for ( u32 Counter = 0 ; Counter < MAX_ID ; Counter++,Parser++)
|
|
{
|
|
if (*Parser)
|
|
{
|
|
/* SWAP U & V */
|
|
MATRIX SwpM;
|
|
SwpM = (*Parser)->CurrentMatrix_U;
|
|
if ((*Parser)->SF_T.Booted)
|
|
{
|
|
//
|
|
/* *******************************************************************************************/
|
|
/* BEGIN SMOOTH ******************************************************************************/
|
|
/* *******************************************************************************************/
|
|
if (1)
|
|
{
|
|
Quat Angle;
|
|
float SinAlpha;
|
|
MATRIX InVertPrev;
|
|
Vector OdlT,NewT;
|
|
OdlT = (*Parser)->CurrentMatrix_U.T;
|
|
NewT = (*Parser)->CurrentMatrix_T.T;
|
|
(*Parser)->CurrentMatrix_T.Inverse(InVertPrev);
|
|
InVertPrev *= (*Parser)->CurrentMatrix_U;
|
|
Angle.ComputeFromMatrix(&InVertPrev);
|
|
SinAlpha = (*((Vector *)&Angle)).SqrNorm();
|
|
#define COEF 0.04f
|
|
#define TRESH (COEF / 2.0f)
|
|
#define BLEND (0.4f)
|
|
// Blend Angles
|
|
if (0)//SinAlpha < COEF*COEF)
|
|
{
|
|
// blend
|
|
if (SinAlpha) SinAlpha = sqrtf(SinAlpha);
|
|
if (SinAlpha < TRESH)
|
|
(*Parser)->CurrentMatrix_U.Blend((*Parser)->CurrentMatrix_T,BLEND);//0.975f);
|
|
else
|
|
{
|
|
SinAlpha -= TRESH;
|
|
SinAlpha *= 1.0f / (COEF-TRESH);
|
|
SinAlpha = 1.0f - SinAlpha;
|
|
(*Parser)->CurrentMatrix_U.Blend((*Parser)->CurrentMatrix_T, 1.0f - (1.0f - BLEND) * SinAlpha);//0.975f);
|
|
}
|
|
(*Parser)->CurrentMatrix_U.T = (*Parser)->CurrentMatrix_T.T;
|
|
} else
|
|
// Copy
|
|
(*Parser)->CurrentMatrix_U = (*Parser)->CurrentMatrix_T;//*/
|
|
|
|
// Blend Translation
|
|
//(*Parser)->CurrentMatrix_U.T = (*Parser)->CurrentMatrix_T.T * 0.1 + OdlT * 0.9;
|
|
|
|
|
|
Vector ToleranceVector,ErrorVector;
|
|
ToleranceVector.x = 0.001f * /*Pixel*/ NewT.z * (*Parser)->p_UsedMesh->Focale ;
|
|
ToleranceVector.y = ToleranceVector.x;
|
|
ErrorVector = NewT - OdlT;
|
|
/* if ((fabs(ErrorVector.x) > ToleranceVector.x) ||
|
|
(fabs(ErrorVector.y) > ToleranceVector.y))*/
|
|
/* Out Of Tolerance -> Copy */
|
|
(*Parser)->CurrentMatrix_U.T = NewT;
|
|
//else
|
|
/* else -> Blend */
|
|
// (*Parser)->CurrentMatrix_U.T = NewT * 0.25f + OdlT * 0.75f;
|
|
/*
|
|
extern MATRIX MatrixSrc;
|
|
MatrixSrc = (*Parser)->CurrentMatrix_U;
|
|
if ((*Parser)->SF_T.DrawMesh) RenderMesh(SOURCEMAP_SRC , (*Parser)->p_UsedMesh , 0xff, 0,(*Parser)->SF_T.DrawMesh);
|
|
//*/
|
|
} else
|
|
(*Parser)->CurrentMatrix_U = (*Parser)->CurrentMatrix_T;
|
|
(*Parser)->CurrentMatrix_UNS = (*Parser)->CurrentMatrix_T;
|
|
|
|
/* *******************************************************************************************/
|
|
/* END SMOOTH ******************************************************************************/
|
|
/* *******************************************************************************************/
|
|
|
|
(*Parser)->SF_U.FromScratch = (*Parser)->SF_T.FromScratch;
|
|
(*Parser)->SF_U.FlyStart = (*Parser)->SF_T.FlyStart;
|
|
(*Parser)->SF_U.Booted = (*Parser)->SF_T.Booted;
|
|
(*Parser)->SF_U.Ready2Learn = (*Parser)->SF_T.Ready2Learn;
|
|
(*Parser)->SF_U.ContinuousLearn = (*Parser)->SF_T.ContinuousLearn;
|
|
//(*Parser)->SF_U.ComputeMask = (*Parser)->SF_T.ComputeMask;
|
|
} else
|
|
(*Parser)->CurrentMatrix_T = SwpM;
|
|
(*Parser)->SF_T = (*Parser)->SF_U;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
// Release "A"
|
|
//WaitForSingleObject(ParramT->AccesMutexComputeBackGround, 10);
|
|
ReleaseSemaphore(ParramT->AccesMutexA,1,NULL);
|
|
|
|
if (SkipFunctions & SKIP_SWITCH_NEW_INTEREST)
|
|
{
|
|
WaitForSingleObject(ParramT->AccesMutexB, INFINITE);
|
|
ReleaseSemaphore(ParramT->AccesMutexB,1,NULL);
|
|
}
|
|
//*/
|
|
STOP_RASTER(Track_Match2D3D);
|
|
|
|
return 1;
|
|
}
|
|
void WORLD::DestroyTrackeur()
|
|
{
|
|
if (ParramT != NULL)
|
|
{
|
|
// Take "B"
|
|
WaitForSingleObject(ParramT->AccesMutexB, INFINITE);
|
|
ParramT->State = 2;
|
|
ReleaseSemaphore(ParramT->AccesMutexA,1,NULL);
|
|
while (ParramT->State != 3)
|
|
{
|
|
ReleaseSemaphore(ParramT->AccesMutexA,1,NULL);
|
|
ReleaseSemaphore(ParramT->AccesMutexB,1,NULL);
|
|
Sleep(1);
|
|
}
|
|
// Release "B"
|
|
CloseHandle(ParramT->AccesMutexA);
|
|
CloseHandle(ParramT->AccesMutexB);
|
|
CC_free(ParramT);
|
|
ParramT = NULL;
|
|
}
|
|
}
|
|
|
|
/* Create a new Empty ID */
|
|
u32 WORLD::ID_New(int ID)
|
|
{
|
|
u32 Counter;
|
|
|
|
if (ID == -1)
|
|
for (Counter = 0 ; Counter < MAX_ID && ID_TABLE[Counter] != NULL; Counter++);
|
|
else
|
|
Counter = ID;
|
|
if (Counter >= MAX_ID)
|
|
return 0xffffffff;
|
|
|
|
ID_TABLE[Counter] = ID_NEW();
|
|
ID_SetName(Counter, "");
|
|
|
|
#ifdef CONSOLE
|
|
OutputConsole("created");
|
|
#endif
|
|
NumberOfID = max(Counter+1, NumberOfID);
|
|
return Counter;
|
|
}
|
|
void WORLD::ID_Destroy(u32 Counter)
|
|
{
|
|
TRACK_Synchronise_Multithread();
|
|
if (Counter < MAX_ID)
|
|
{
|
|
if (ID_TABLE[Counter] != NULL)
|
|
{
|
|
FreeIDFX(ID_TABLE[Counter]);
|
|
ID_DELETE(ID_TABLE[Counter]);
|
|
ID_TABLE[Counter] = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
void WORLD::ID_NewAnimated(u32 Counter,u32 MediaSourceIndex,u32 MediaSubTrackIndex)
|
|
{
|
|
if (Counter < MAX_ID)
|
|
{
|
|
ID_Destroy(Counter);
|
|
if (ID_TABLE[Counter] == NULL)
|
|
{
|
|
ID_TABLE[Counter] = ID_NEW();
|
|
ID_TABLE[Counter]->AnimatedMedia = MediaSourceIndex;
|
|
ID_TABLE[Counter]->AnimatedMedia_SubIndex = MediaSubTrackIndex;
|
|
ID_SetName(Counter, "");
|
|
//NumberOfID = Counter + 1;
|
|
NumberOfID = max(Counter+1, NumberOfID);
|
|
}
|
|
}
|
|
}
|
|
|
|
void WORLD::ID_SetHaarParrams(u32 ID , Vector *pNewHaarP)
|
|
{
|
|
if (VALIDATE_ID(ID))
|
|
{
|
|
ID_TABLE[ID]->HaarParameter = *pNewHaarP;
|
|
}
|
|
}
|
|
|
|
|
|
void WORLD::ID_SetScale(u32 ID , Vector *pNewScale)
|
|
{
|
|
if (VALIDATE_ID(ID))
|
|
{
|
|
GID_SetScale(ID_TABLE[ID],pNewScale);
|
|
}
|
|
}
|
|
void WORLD::ID_SetMesh(u32 ID , Mesh *NewMesh)
|
|
{
|
|
if (VALIDATE_ID(ID))
|
|
{
|
|
Vector Scale = ID_TABLE[ID]->vModelScale;
|
|
if (Scale.x == 0 && Scale.y == 0 && Scale.z == 0)
|
|
Scale = Vector(1.0f,1.0f,1.0f);
|
|
ID_TABLE[ID]->vModelScale = Vector(1.0f,1.0f,1.0f);
|
|
if (ID_TABLE[ID]->p_UsedMesh)
|
|
{
|
|
ID_TABLE[ID]->p_UsedMesh->Destroy();
|
|
CC_free(ID_TABLE[ID]->p_UsedMesh);
|
|
}
|
|
ID_TABLE[ID]->p_UsedMesh = CopyMesh(NewMesh);
|
|
ID_SetScale(ID, &Scale);
|
|
}
|
|
}
|
|
|
|
/* Select the mesh 0:Plane 1:Face */
|
|
void WORLD::ID_SelectMesh(u32 ID , u32 MeshMode)
|
|
{
|
|
if (VALIDATE_ID(ID))
|
|
{
|
|
if (ID_TABLE[ID]->p_UsedMesh)
|
|
{
|
|
ID_TABLE[ID]->p_UsedMesh->Destroy();
|
|
CC_free(ID_TABLE[ID]->p_UsedMesh);
|
|
}
|
|
Mesh myMesh;
|
|
if (MeshMode & 1)
|
|
BuildHead(&myMesh);
|
|
else
|
|
BuildPlane(&myMesh);
|
|
ID_SetMesh(ID , &myMesh);
|
|
#ifdef CONSOLE
|
|
OutputConsole("mesh Selec");
|
|
#endif
|
|
|
|
}
|
|
}
|
|
/* Select debug info level */
|
|
void WORLD::ID_SetDebugInfo(u32 ID,u32 DisplayTextInfos , u32 DisplayTrackedMeshes)
|
|
{
|
|
if (VALIDATE_ID(ID))
|
|
{
|
|
ID_TABLE[ID]->SF_U.DrawMesh = DisplayTrackedMeshes ? 1 : 0;
|
|
ID_TABLE[ID]->SF_U.DrawText = DisplayTextInfos ? 1 : 0;
|
|
}
|
|
}
|
|
/* Destroy all ID */
|
|
void WORLD::ID_ResetAll()
|
|
{
|
|
};
|
|
/* Reset an ID */
|
|
void WORLD::ID_Reset(u32 ID)
|
|
{
|
|
TRACK_Synchronise_Multithread();
|
|
if (VALIDATE_ID(ID)) ID_RESET(ID_TABLE[ID]);
|
|
}
|
|
/* Launche face detector to boot tracking */
|
|
void WORLD::ID_AutoStart(u32 ID)
|
|
{
|
|
if (VALIDATE_ID(ID))
|
|
{
|
|
ID_TABLE[ID]->SF_U.ViolaStart = 1;
|
|
#ifdef CONSOLE
|
|
OutputConsole("Start viola");
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/* Load an ID and TRACK it */
|
|
void WORLD::ID_Load (u32 ID , char *FileName)
|
|
{
|
|
char localName[2048];
|
|
char *TT;
|
|
TRACK_Synchronise_Multithread();
|
|
TT = FileName;
|
|
if (GetFileNameExtend(TT) != '.IDX')
|
|
{
|
|
TT = localName;
|
|
while (*FileName) {*(TT++) = *(FileName++);};
|
|
*(TT++) = '.';
|
|
*(TT++) = 'I';
|
|
*(TT++) = 'D';
|
|
*(TT++) = 'X';
|
|
*(TT++) = 0;
|
|
TT = localName;
|
|
}
|
|
|
|
ID_Destroy(ID);
|
|
LoadIDFX(&ID_TABLE[ID], TT);
|
|
}
|
|
/* Save an ID */
|
|
void WORLD::ID_Save (u32 ID , char *FileName)
|
|
{
|
|
char localName[2048];
|
|
char *TT;
|
|
TT = FileName;
|
|
TRACK_Synchronise_Multithread();
|
|
if (GetFileNameExtend(TT) != '.IDX')
|
|
{
|
|
TT = localName;
|
|
while (*FileName) {*(TT++) = *(FileName++);};
|
|
*(TT++) = '.';
|
|
*(TT++) = 'I';
|
|
*(TT++) = 'D';
|
|
*(TT++) = 'X';
|
|
*(TT++) = 0;
|
|
TT = localName;
|
|
}
|
|
|
|
if (VALIDATE_ID(ID))
|
|
{
|
|
FILE *F;
|
|
F = CC_fopen(TT,"wb");
|
|
if (F)
|
|
{
|
|
ID_SAVE(F,ID_TABLE[ID]);
|
|
CC_fclose(F);
|
|
#ifdef CONSOLE
|
|
OutputConsole("Saved");
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
/* Get the current tracked 3D matrix of an ID */
|
|
u32 ActualFrameNumber;
|
|
u32 WORLD::ID_GetMatrix(u32 ID , float *XYZ_IJKT)
|
|
{
|
|
if (VALIDATE_ID(ID))
|
|
{
|
|
MATRIX SaveME;
|
|
SaveME = ID_TABLE[ID]->CurrentMatrix_U;
|
|
*(XYZ_IJKT++) = ID_TABLE[ID]->CurrentMatrix_U.I.x;
|
|
*(XYZ_IJKT++) = ID_TABLE[ID]->CurrentMatrix_U.I.y;
|
|
*(XYZ_IJKT++) = ID_TABLE[ID]->CurrentMatrix_U.I.z;
|
|
*(XYZ_IJKT++) = ID_TABLE[ID]->CurrentMatrix_U.J.x;
|
|
*(XYZ_IJKT++) = ID_TABLE[ID]->CurrentMatrix_U.J.y;
|
|
*(XYZ_IJKT++) = ID_TABLE[ID]->CurrentMatrix_U.J.z;
|
|
*(XYZ_IJKT++) = ID_TABLE[ID]->CurrentMatrix_U.K.x;
|
|
*(XYZ_IJKT++) = ID_TABLE[ID]->CurrentMatrix_U.K.y;
|
|
*(XYZ_IJKT++) = ID_TABLE[ID]->CurrentMatrix_U.K.z;
|
|
*(XYZ_IJKT++) = ID_TABLE[ID]->CurrentMatrix_U.T.x;
|
|
*(XYZ_IJKT++) = ID_TABLE[ID]->CurrentMatrix_U.T.y;
|
|
*(XYZ_IJKT++) = ID_TABLE[ID]->CurrentMatrix_U.T.z;
|
|
ID_TABLE[ID]->CurrentMatrix_U = SaveME;
|
|
return ID_TABLE[ID]->SF_U.FromScratch == 0;
|
|
}
|
|
return 0;
|
|
}
|
|
/* Set a matrix to an ID and track it */
|
|
u32 WORLD::ID_SetMatrix(u32 ID , float *XYZ_IJKT)
|
|
{
|
|
if (VALIDATE_ID(ID))
|
|
{
|
|
ID_TABLE[ID]->CurrentMatrix_U.I.x = *(XYZ_IJKT++);
|
|
ID_TABLE[ID]->CurrentMatrix_U.I.y = *(XYZ_IJKT++);
|
|
ID_TABLE[ID]->CurrentMatrix_U.I.z = *(XYZ_IJKT++);
|
|
ID_TABLE[ID]->CurrentMatrix_U.J.x = *(XYZ_IJKT++);
|
|
ID_TABLE[ID]->CurrentMatrix_U.J.y = *(XYZ_IJKT++);
|
|
ID_TABLE[ID]->CurrentMatrix_U.J.z = *(XYZ_IJKT++);
|
|
ID_TABLE[ID]->CurrentMatrix_U.K.x = *(XYZ_IJKT++);
|
|
ID_TABLE[ID]->CurrentMatrix_U.K.y = *(XYZ_IJKT++);
|
|
ID_TABLE[ID]->CurrentMatrix_U.K.z = *(XYZ_IJKT++);
|
|
ID_TABLE[ID]->CurrentMatrix_U.T.x = *(XYZ_IJKT++);
|
|
ID_TABLE[ID]->CurrentMatrix_U.T.y = *(XYZ_IJKT++);
|
|
ID_TABLE[ID]->CurrentMatrix_U.T.z = *(XYZ_IJKT++);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
/* Set a matrix to an ID and track it */
|
|
void WORLD::ID_Boot(u32 ID )
|
|
{
|
|
if (VALIDATE_ID(ID))
|
|
{
|
|
ID_TABLE[ID]->SF_U.Ready2Learn = 1;
|
|
}
|
|
}
|
|
/* Set the name of an ID */
|
|
void WORLD::ID_SetName (u32 ID , char *Name)
|
|
{
|
|
char *Dst;
|
|
if (VALIDATE_ID(ID))
|
|
{
|
|
Dst = ID_TABLE[ID]->ID_Name;
|
|
while (*Name) {*(Dst++) = *(Name++);};
|
|
#ifdef CONSOLE
|
|
OutputConsole("Named");
|
|
#endif
|
|
|
|
}
|
|
}
|
|
|