#include "SCENE.h" #include "Wininet.h" #include "xmmintrin.h" #include static Vector BaseTranslate; //#pragma optimize("",off) typedef struct { Vector xyz; float angle; } QuatInfo; #define DEFAULT_TRANSLATION_SMOOTH 1.0f #define DEFAULT_ROTATION_SMOOTH 2.0f #define DEFAULT_QUAT_SMOOTH 1.0f //static float translationSmooth = DEFAULT_TRANSLATION_SMOOTH; //static float rotationSmooth = DEFAULT_ROTATION_SMOOTH; //static float quatSmooth = DEFAULT_QUAT_SMOOTH; static BOOL initDone = 0; static QuatInfo* prevMatrix[MAX_ID]; static Vector* prevTranslation[MAX_ID]; static Quat* prevQuat[MAX_ID]; #define VECTOR_LIMIT 0.3 #define ANGLE_LIMIT 0.08 void FreePrevs() { if (!initDone) return; QuatInfo** prevMatrixPtr = prevMatrix; Vector** prevTranslationPtr = prevTranslation; Quat** prevQuatPtr = prevQuat; for (int i=0; ixyz = *xyz; prevMatrix[index]->angle= *angle; return; } ANorm = (*xyz - prevMatrix[index]->xyz).Norm()/*Only add*/ + fabs(*angle - prevMatrix[index]->angle); ANorm *= rotationSmooth; if (ANorm < 1.0f) { ANorm *= 1.0f + 0.05f;//1.0f + 0.025f; ANorm -= 0.05f;//0.025f; if (ANorm < 0.0f) { ANorm = 0.0f; *xyz = prevMatrix[index]->xyz; *angle = prevMatrix[index]->angle; } else { *xyz = prevMatrix[index]->xyz*(1-ANorm) + *xyz*ANorm; *angle = prevMatrix[index]->angle*(1-ANorm) + *angle*ANorm;; } } prevMatrix[index]->xyz = *xyz; prevMatrix[index]->angle = *angle; } void SmoothFuncTranslation(int index, Vector *T, float translationSmooth, float translationHold) { if (translationSmooth == 0 && translationHold == 0) translationSmooth = DEFAULT_TRANSLATION_SMOOTH; if (!initDone) { memset(prevMatrix, 0, MAX_ID*sizeof(QuatInfo*)); memset(prevTranslation, 0, MAX_ID*sizeof(Vector*)); memset(prevQuat, 0, MAX_ID*sizeof(Quat*)); initDone = 1; } if (prevTranslation[index] == NULL) { prevTranslation[index] = (Vector*)CC_malloc(sizeof(Vector)); *prevTranslation[index] = *T; return; } if (translationHold) { Vector holdVector = *T - *prevTranslation[index]; if (holdVector.Norm() > translationHold) { *prevTranslation[index] = *T; return; } } *T = *prevTranslation[index]*(1.0f-translationSmooth) + *T*translationSmooth; *prevTranslation[index] = *T; } void SmoothFuncQuat(int index, Quat *Q, float quatSmooth, float quatHold) { if (quatSmooth == 0 && quatHold == 0) quatSmooth = DEFAULT_QUAT_SMOOTH; if (!initDone) { memset(prevMatrix, 0, MAX_ID*sizeof(QuatInfo*)); memset(prevTranslation, 0, MAX_ID*sizeof(Vector*)); memset(prevQuat, 0, MAX_ID*sizeof(Quat*)); initDone = 1; } if (prevQuat[index] == NULL) { prevQuat[index] = (Quat*)CC_malloc(sizeof(Quat)); *prevQuat[index] = *Q; return; } if (quatHold) { Quat holdQuat; holdQuat = *prevQuat[index]*-1.0f; holdQuat.NormalizeW(); holdQuat *= *Q; if (holdQuat.w < quatHold) { *prevQuat[index] = *Q; return; } } *Q = *prevQuat[index]*(1.0f-quatSmooth) + *Q*quatSmooth; Q->NormalizeW(); *prevQuat[index] = *Q; } void MatrixGetRotationAngle(MATRIX *MatrixPtr, Vector *xyzPtr, float *anglePtr) { Quat rotQuat; float sin_angle, cos_angle; rotQuat.ComputeFromMatrix(MatrixPtr); rotQuat.Normalize(); cos_angle = rotQuat.w; *anglePtr = acos( cos_angle ) * 2; sin_angle = sqrt( 1.0 - cos_angle * cos_angle ); if ( fabs( sin_angle ) < 0.0005 ) sin_angle = 1; xyzPtr->x = rotQuat.x / sin_angle; xyzPtr->y = rotQuat.y / sin_angle; xyzPtr->z = rotQuat.z / sin_angle; } void MatrixFromRotationAngle(MATRIX *MatrixPtr, Vector *xyzPtr, float *anglePtr) { Quat rotQuat; float sin_angle, cos_angle; Vector Translation = MatrixPtr->T; sin_angle = sin( *anglePtr / 2 ); cos_angle = cos( *anglePtr / 2 ); rotQuat.x = xyzPtr->x * sin_angle; rotQuat.y = xyzPtr->y * sin_angle; rotQuat.z = xyzPtr->z * sin_angle; rotQuat.w = cos_angle; rotQuat.TransforToMatrix(MatrixPtr); MatrixPtr->T = Translation; } void MatrixStretchAngle(MATRIX *MatrixPtr, float factor, float limit) { if ((factor == 0.0f || factor == 1.0f) && limit == 0.0) return; Vector xyz; float angle; MatrixGetRotationAngle(MatrixPtr, &xyz, &angle); angle *= factor; if (limit > 0) { if ((angle * 45 / atan(1.0)) > limit) angle = limit * atan(1.0) / 45; if ((angle * 45 / atan(1.0)) < -limit) angle = -limit * atan(1.0) / 45; } MatrixFromRotationAngle(MatrixPtr, &xyz, &angle); } void FactorSmoothMatrix(int index, MATRIX *MatrixPtr, float rotationSmooth) { Vector NormVals; Vector xyz; float angle; NormVals.x = MatrixPtr->I.Norm(); MatrixPtr->I *= 1/NormVals.x; NormVals.y = MatrixPtr->J.Norm(); MatrixPtr->J *= 1/NormVals.y; NormVals.z = MatrixPtr->K.Norm(); MatrixPtr->K *= 1/NormVals.z; MatrixGetRotationAngle(MatrixPtr, &xyz, &angle); SmoothFuncVectorAngle(index, &xyz, &angle, rotationSmooth); MatrixFromRotationAngle(MatrixPtr, &xyz, &angle); MatrixPtr->I *= NormVals.x; MatrixPtr->J *= NormVals.y; MatrixPtr->K *= NormVals.z; } void FactorSmoothMatrixQuat(int index, MATRIX *MatrixPtr, float quatSmooth, float quatHold) { Vector NormVals; Quat quat; Vector T = MatrixPtr->T; NormVals.x = MatrixPtr->I.Norm(); MatrixPtr->I *= 1/NormVals.x; NormVals.y = MatrixPtr->J.Norm(); MatrixPtr->J *= 1/NormVals.y; NormVals.z = MatrixPtr->K.Norm(); MatrixPtr->K *= 1/NormVals.z; quat.ComputeFromMatrix(MatrixPtr); SmoothFuncQuat(index, &quat, quatSmooth, quatHold); quat.TransforToMatrix(MatrixPtr); MatrixPtr->I *= NormVals.x; MatrixPtr->J *= NormVals.y; MatrixPtr->K *= NormVals.z; MatrixPtr->T = T; } void WORLD::SetSmoothMatrix(int SmoothNumber, MATRIX *TMatrix, int Affect, int axeInversion) { if (SmoothNumber) { if (Affect & 1) SmoothFuncTranslation(SmoothNumber, &TMatrix->T, FrmSmooth.Translation, FrmSmooth.TranslationHold); if (Affect & 2) { if (FrmQuatMode) FactorSmoothMatrixQuat(SmoothNumber, TMatrix, FrmSmooth.Quat, FrmSmooth.QuatHold); else FactorSmoothMatrix(SmoothNumber, TMatrix, FrmSmooth.Rotation); } } if (axeInversion == 0) return; int rotations; MATRIX AxeMatrix; MATRIX AxeMatrixInv; MATRIX RotMatrix; Vector Translation = TMatrix->T; rotations = axeInversion % 10; if (rotations) // rot around I { RotMatrix.I.y = RotMatrix.I.z = 0; RotMatrix.I.x = 1; RotMatrix.J.x = RotMatrix.J.y = 0; RotMatrix.J.z = -1; RotMatrix.K.x = RotMatrix.K.z = 0; RotMatrix.K.y = 1; while (rotations--) AxeMatrix *= RotMatrix; } rotations = (axeInversion/10) % 10; if (rotations) // rot around J { RotMatrix.I.x = RotMatrix.I.y = 0; RotMatrix.I.z = -1; RotMatrix.J.x = RotMatrix.J.z = 0; RotMatrix.J.y = 1; RotMatrix.K.y = RotMatrix.K.z = 0; RotMatrix.K.x = 1; while (rotations--) AxeMatrix *= RotMatrix; } rotations = (axeInversion/100) % 10; if (rotations) // rot around K { RotMatrix.I.x = RotMatrix.I.z = 0; RotMatrix.I.y = -1; RotMatrix.J.y = RotMatrix.J.z = 0; RotMatrix.J.x = 1; RotMatrix.K.x = RotMatrix.K.y = 0; RotMatrix.K.z = 1; while (rotations--) AxeMatrix *= RotMatrix; } AxeMatrix.Inverse(AxeMatrixInv); AxeMatrix *= *TMatrix; AxeMatrix *= AxeMatrixInv; if (Affect & 1) { Translation = AxeMatrix.T; } if (Affect & 2) { *TMatrix = AxeMatrix; } TMatrix->T = Translation; } void WORLD::ComputeSkinning(SmallScene *SmSc,Mesh *RenderMesh,MATRIX *InverseRootMat , u32 ModeInverse) { if (RenderMesh->ulNumberOfSkins) { u32 ulNumberOfSkins; Skin *MeshSkin; u32 MustCompute; if (ComputingBufferSize2 < RenderMesh->NumberOfPoints) { if (ComputingBuffer2) CC_free(ComputingBuffer2); ComputingBuffer2 = (Vector*)CC_malloc(sizeof(Vector) * RenderMesh->NumberOfPoints); ComputingBufferSize2 = RenderMesh->NumberOfPoints; } memset(ComputingBuffer2 , 0 , sizeof(Vector) * RenderMesh->NumberOfPoints); if (ComputingBufferSize_Normales < RenderMesh->NumberOfPoints) { if (ComputingBuffer_Normales) CC_free(ComputingBuffer_Normales); ComputingBuffer_Normales = (Vector*)CC_malloc(sizeof(Vector) * RenderMesh->NumberOfPoints); ComputingBufferSize_Normales = RenderMesh->NumberOfPoints; } memset(ComputingBuffer_Normales , 0 , sizeof(Vector) * RenderMesh->NumberOfPoints); Skin *pSkin = RenderMesh->MeshSkin; for (u32 W = 0 ; W < RenderMesh->ulNumberOfSkins ; W++ ,pSkin++) { MATRIX TransMat,InvG; InvG = SmSc->ObjectsPtrs[pSkin->ObjectIndex]->GlobalMatrix; InvG *= *InverseRootMat ; TransMat = pSkin->Flash; TransMat *= InvG; if (ModeInverse) { TransMat.Inverse(InvG); TransMat = InvG; } Ponderation *pPond,*pPondLast; pPond = pSkin->WeightList; pPondLast = pPond + pSkin->WeightNumber; while (pPond < pPondLast) { *(ComputingBuffer2 + pPond->VIndex) += (TransMat * *(RenderMesh->Points + pPond->VIndex)) * pPond->Weight; pPond++; } pPond = pSkin->WeightList; pPondLast = pPond + pSkin->WeightNumber; TransMat.T = Vector(0,0,0); TransMat.I.Normalize(); TransMat.J.Normalize(); TransMat.K.Normalize();//*/ while (pPond < pPondLast) { *(ComputingBuffer_Normales + pPond->VIndex) += (TransMat * *(RenderMesh->PointsN + pPond->VIndex)) * pPond->Weight; pPond++; } } if (ModeInverse) { memcpy(RenderMesh->Points,ComputingBuffer2,sizeof(Vector) * RenderMesh->NumberOfPoints); CC_free(ComputingBuffer2); ComputingBuffer2 = NULL; ComputingBufferSize2 = 0; memcpy(RenderMesh->PointsN,ComputingBuffer_Normales,sizeof(Vector) * RenderMesh->NumberOfPoints); CC_free(ComputingBuffer_Normales); ComputingBuffer_Normales = NULL; ComputingBufferSize_Normales = 0; } else { RenderMesh->Points = ComputingBuffer2; RenderMesh->PointsN = ComputingBuffer_Normales; } RenderMesh->UpdateTopologie(); } } void WORLD::ComputeMorphing(SmallScene *SmSc,Mesh *RenderMesh ) { if (RenderMesh->ulNumberOfTarget) { u32 MustCompute; if (ComputingBufferSize < RenderMesh->NumberOfPoints) { if (ComputingBuffer) CC_free(ComputingBuffer); ComputingBuffer = (Vector*)CC_malloc(sizeof(Vector) * RenderMesh->NumberOfPoints); ComputingBufferSize = RenderMesh->NumberOfPoints; } memcpy(ComputingBuffer , RenderMesh->Points , sizeof(Vector) * RenderMesh->NumberOfPoints); RenderMesh->Points = ComputingBuffer; if (ComputingBufferSize_UV < RenderMesh->NumberOfPointsUV) { if (ComputingBuffer_UV) CC_free(ComputingBuffer_UV); ComputingBuffer_UV = (Vector*)CC_malloc(sizeof(Vector) * RenderMesh->NumberOfPointsUV); ComputingBufferSize_UV = RenderMesh->NumberOfPointsUV; } memcpy(ComputingBuffer_UV , RenderMesh->PointsUV , sizeof(Vector) * RenderMesh->NumberOfPointsUV); RenderMesh->PointsUV = ComputingBuffer_UV; for (u32 W = 0 ; W < RenderMesh->ulNumberOfTarget ; W++) { float Weight = RenderMesh->MorphTargets[W].Weight; if (Weight) { Morphing *MorphListB,*MorphListE; MorphListB = RenderMesh->MorphTargets[W].MorphList; MorphListE = MorphListB + RenderMesh->MorphTargets[W].MorphNumber; while (MorphListB < MorphListE) { *(ComputingBuffer + MorphListB->VIndex) += MorphListB->Move * Weight; MorphListB++; } MorphListB = RenderMesh->MorphTargets[W].MorphList_UV; MorphListE = MorphListB + RenderMesh->MorphTargets[W].MorphNumber_UV; while (MorphListB < MorphListE) { *(ComputingBuffer_UV + MorphListB->VIndex) += MorphListB->Move * Weight; MorphListB++; } } } RenderMesh->UpdateTopologie(); } } void WORLD::TouchSmallScene(char *Name) { SmallScene *SmSc; char NameParser[2048]; u32 NameBase; NameBase = 0; while (*Name) { NameParser[NameBase] = *Name; if ((*Name == ':')|| (*Name == '\\')|| (*Name == '/')) { UnicID SceneID; if (NameBase) { NameParser[NameBase] = 0; SceneID = SmallSceneDico.IsExist(NameParser); if (SceneID != -1) { SmSc = pSmallScenes[SmallSceneDico.mpst_Dico[SceneID].AssociatedValue]; SmSc->ulMustBeReload ++; } } NameBase = 0; } else NameBase++; Name++; } //ulMustBeReload; } char *pForcedDirectory = NULL; // Used to force Current .scc directory to be used with GetSceneFileHanler // If == null then do nbothing u32 GetSceneFileName(char *Name, char *NewName) { char ForcedName[2048]; if (pForcedDirectory != NULL) { char *LastBackSlash,*Parse,SaveLsb; Parse = LastBackSlash = Name; while (*Parse) { if ((*Parse == '\\') || (*Parse == '/')) LastBackSlash = Parse+1; Parse++; } sprintf(ForcedName,"%s%s",pForcedDirectory,LastBackSlash); } else strcpy(ForcedName, Name); FILE *F; char Directory[2048],FileName[2048]; char *LastBackSlash,*Parse,SaveLsb; Parse = LastBackSlash = ForcedName; while (*Parse) { if ((*Parse == '\\') || (*Parse == '/')) LastBackSlash = Parse+1; Parse++; } if (*LastBackSlash) { SaveLsb = *LastBackSlash; sprintf(FileName,"%s",LastBackSlash); Parse = ForcedName; while (Parse != LastBackSlash) { Directory[Parse-ForcedName] = *Parse; Parse++; } Directory[Parse-ForcedName] = 0; sprintf(NewName,"%sModified\\%s",Directory,FileName); F = CC_fopen(NewName,"rb"); if (F) { CC_fclose(F); return 1; } } strcpy(NewName, ForcedName); F = CC_fopen(ForcedName,"rb"); if (F) { CC_fclose(F); return 1; } return 0; } FILE *GetSceneFileHanler_LOADSAVE(char *Name,u32 ModeSave) { FILE *F; char Directory[2048],FileName[2048],NewName[2048]; char *LastBackSlash,*Parse,SaveLsb; Parse = LastBackSlash = Name; while (*Parse) { if ((*Parse == '\\') || (*Parse == '/')) LastBackSlash = Parse+1; Parse++; } if (*LastBackSlash) { SaveLsb = *LastBackSlash; sprintf(FileName,"%s",LastBackSlash); Parse = Name; while (Parse != LastBackSlash) { Directory[Parse-Name] = *Parse; Parse++; } Directory[Parse-Name] = 0; sprintf(NewName,"%sModified\\%s",Directory,FileName); F = CC_fopen(NewName,"rb"); if (F) { if (ModeSave) { CC_fclose(F); F = CC_fopen(NewName,"wb"); } return F; } } F = CC_fopen(Name,"rb"); if (F && ModeSave) { CC_fclose(F); F = CC_fopen(Name,"wb"); return F; } return F; } #ifndef SKIMMED_NET BOOL HTTP_GetFile (HINTERNET IN hOpen, // Handle from InternetOpen() char *szUrl, // Full URL char *szFileName) // Local file name { DWORD dwSize; CHAR szHead[] = "Accept: */*\r\n\r\n"; VOID * szTemp[25]; HINTERNET hConnect; FILE * pFile; if ( !(hConnect = InternetOpenUrl ( hOpen, szUrl, szHead, lstrlen (szHead), INTERNET_FLAG_DONT_CACHE, 0))) { //cerr << "Error !" << endl; return FALSE; } if ( !(pFile = CC_fopen (szFileName, "wb" ) ) ) { //cerr << "Error !" << endl; return FALSE; } do { // Keep coping in 25 bytes chunks, while file has any data left. // Note: bigger buffer will greatly improve performance. if (!InternetReadFile (hConnect, szTemp, 50, &dwSize) ) { CC_fclose (pFile); //cerr << "Error !" << endl; return FALSE; } if (!dwSize) break; // Condition of dwSize=0 indicate EOF. Stop. else fwrite(szTemp, sizeof (char), dwSize , pFile); } // do while (TRUE); fflush (pFile); CC_fclose (pFile); return TRUE; } #endif char *SmScGetFileName(char *FileName) { char *Current; Current = FileName; while (*Current) { if ((*Current == '\\') || (*Current == '/')) FileName = Current+1; Current++; } return FileName; } char *SmScGetHTTPSiteName(char *FileName,char *SiteName) { char *Current; Current = FileName + strlen("http://"); while (*Current && (*Current != '\\') && (*Current != '/') ) { *(SiteName++) = *(Current++); } *SiteName = 0; return SiteName; } // Creates the directory structure for the specified path or filename // This function temporarily modifies the input string, but reverts it back to original void REC_CreateDirectory(char *Name) { char LName[2048]; strcpy(LName,Name); char *Parse = LName; while (*Parse) { if ((*Parse == '\\') || (*Parse == '/')) { char SNP1; SNP1 = *(Parse+1); *(Parse+1) = 0; CreateDirectory(LName,NULL); *(Parse+1) = SNP1; } Parse++; } } FILE *GetSceneFileHanler(char *Name) { //char Name[2048]; //sprintf (Name,"http://media9.xboxyde.com/secdl/8a0e316db63ab9026b0baf528d9d6a71/471f3e68/naruto_prvw_gp1a.avi"); #ifndef SKIMMED_NET if ((Upper(Name[0]) == 'H') && (Upper(Name[1]) == 'T') && (Upper(Name[2]) == 'T') && (Upper(Name[3]) == 'P')) { FILE *Ret; char CACHENAME[2048]; char SITENAME[2048]; SmScGetHTTPSiteName(Name,SITENAME); HINTERNET hOpen; sprintf(CACHENAME,".\\NETCache\\%s\\%s",SITENAME,SmScGetFileName(Name)); Ret = GetSceneFileHanler_LOADSAVE(CACHENAME,0); if (!Ret) { REC_CreateDirectory(CACHENAME); hOpen = InternetOpen("My connect", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if (HTTP_GetFile (hOpen,Name,CACHENAME)) // Local file name Ret = GetSceneFileHanler_LOADSAVE(CACHENAME,0); else Ret = NULL; InternetCloseHandle(hOpen); } return Ret; } #endif if (pForcedDirectory != NULL) { char ForcedName[2048]; char *LastBackSlash,*Parse,SaveLsb; Parse = LastBackSlash = Name; while (*Parse) { if ((*Parse == '\\') || (*Parse == '/')) LastBackSlash = Parse+1; Parse++; } sprintf(ForcedName,"%s%s",pForcedDirectory,LastBackSlash); FILE *F; F = GetSceneFileHanler_LOADSAVE(ForcedName,0); if (F) return F; // else standard way } return GetSceneFileHanler_LOADSAVE(Name,0); } FILE *GetSceneFileHanler_SAVE(char *Name) { return GetSceneFileHanler_LOADSAVE(Name,1); } void WORLD::ReLoadSmSc(SmallScene *SmSc) { if (SmSc) for (u32 MaterialC = 0 ; MaterialC < SmSc->ulNumberOfMaterials ; MaterialC++) { for (u32 LayerC = 0 ; LayerC < SmSc->MaterialsPtrs[MaterialC]->NumberOfLayers ; LayerC++) { u32 MediaIndex; MediaIndex = SmSc->MaterialsPtrs[MaterialC]->Layers[LayerC].TextureMediaIndex; if (MediaIndex != -1) { MediaIndex = MediaDico.mpst_Dico[MediaIndex].AssociatedValue; } if ((MediaIndex != -1) && ID_MEDIA[MediaIndex]) { ID_MEDIA[MediaIndex]->VirtuallyDestroyed = 0; ID_MEDIA[MediaIndex]->nbReferences++; } } } } int IKPatchInitToObj(SmallScene *Smsc, int forceRealloc) { if (!Smsc->IK) return 0; if (!Smsc->IK->ulInitNumberOfPatchs) { Smsc->IK->ulNumberOfPatchs = 0; return 0; } if (!Smsc->IK->pObjPatchs) Smsc->IK->pObjPatchs = (IK_ObjectPatch *)CC_malloc(sizeof(IK_ObjectPatch) * Smsc->ulNumberOfObjects); if (forceRealloc) Smsc->IK->pObjPatchs = (IK_ObjectPatch *)CC_realloc(Smsc->IK->pObjPatchs, sizeof(IK_ObjectPatch) * Smsc->ulNumberOfObjects); Smsc->IK->ulNumberOfPatchs = Smsc->IK->ulInitNumberOfPatchs; memset(Smsc->IK->pObjPatchs, 0, sizeof(IK_ObjectPatch) * Smsc->ulNumberOfObjects); memcpy(Smsc->IK->pObjPatchs, Smsc->IK->pInitObjPatchs, sizeof(IK_ObjectPatch)*Smsc->IK->ulInitNumberOfPatchs); return 1; } int IKPatchObjToInit(SmallScene *Smsc, int forceRealloc) { if (!Smsc->IK) return 0; if (!Smsc->IK->ulNumberOfPatchs) { Smsc->IK->ulInitNumberOfPatchs = 0; return 0; } if (!Smsc->IK->pInitObjPatchs) Smsc->IK->pInitObjPatchs = (IK_ObjectPatch *)CC_malloc(sizeof(IK_ObjectPatch) * Smsc->ulNumberOfObjects); if (forceRealloc) Smsc->IK->pInitObjPatchs = (IK_ObjectPatch *)CC_realloc(Smsc->IK->pInitObjPatchs, sizeof(IK_ObjectPatch) * Smsc->ulNumberOfObjects); Smsc->IK->ulInitNumberOfPatchs = Smsc->IK->ulNumberOfPatchs; memset(Smsc->IK->pInitObjPatchs, 0, sizeof(IK_ObjectPatch) * Smsc->ulNumberOfObjects); memcpy(Smsc->IK->pInitObjPatchs, Smsc->IK->pObjPatchs, sizeof(IK_ObjectPatch)*Smsc->IK->ulNumberOfPatchs); return 1; } void IKPatchProcess(SmallScene *Smsc, int forceRealloc) { if (Smsc->IK->ulInitNumberOfPatchs == 0) { FreeSmallScene_IK(Smsc->IK); CC_free(Smsc->IK); Smsc->IK = NULL; return; } u32 NewNumberOfPatch; /* Clean IK */ if (!Smsc->IK->pObjPatchs) Smsc->IK->pObjPatchs = (IK_ObjectPatch *)CC_malloc(sizeof(IK_ObjectPatch) * Smsc->ulNumberOfObjects); if (forceRealloc) Smsc->IK->pObjPatchs = (IK_ObjectPatch *)CC_realloc(Smsc->IK->pObjPatchs, sizeof(IK_ObjectPatch) * Smsc->ulNumberOfObjects); memset(Smsc->IK->pObjPatchs, 0,sizeof(IK_ObjectPatch) * Smsc->ulNumberOfObjects); //for (int IK = 0 ; IK < Smsc->IK->ulNumberOfPatchs ; IK++) for (int IK = 0 ; IK < Smsc->IK->ulInitNumberOfPatchs ; IK++) { Smsc->IK->pObjPatchs[Smsc->IK->pInitObjPatchs[IK].ObjectRefIndex] = Smsc->IK->pInitObjPatchs[IK]; } /* Treat heritage (flag = 2) */ for (int IK = 0 ; IK < Smsc->ulNumberOfObjects ; IK++) { if ((Smsc->ObjectsPtrs[IK]->FatherIndex != -1) && (Smsc->IK->pObjPatchs[Smsc->ObjectsPtrs[IK]->FatherIndex].ulFlags == 2)) { Smsc->IK->pObjPatchs[IK] = Smsc->IK->pObjPatchs[Smsc->ObjectsPtrs[IK]->FatherIndex]; if (Smsc->IK->pObjPatchs[IK].HeritageStart) Smsc->IK->pObjPatchs[IK].HeritageStart--; } Smsc->IK->pObjPatchs[IK].ObjectRefIndex = IK; } for (int IK = 0 ; IK < Smsc->ulNumberOfObjects ; IK++) { if (Smsc->IK->pObjPatchs[IK].ulFlags == 2) { if (Smsc->IK->pObjPatchs[IK].HeritageStart) Smsc->IK->pObjPatchs[IK].ulFlags = 0; } } NewNumberOfPatch = 0; for (int IK = 0 ; IK < Smsc->ulNumberOfObjects ; IK++) { if (Smsc->IK->pObjPatchs[IK].ulFlags) { Smsc->IK->pObjPatchs[NewNumberOfPatch++] = Smsc->IK->pObjPatchs[IK]; } } Smsc->IK->ulNumberOfPatchs = NewNumberOfPatch; } /** changed by WAQAS AHAMD ahmad.waqas@ubisoft.com, 21/10/2008 changes: 1. checks if NameSmSC.mad exists in the ./mads/ folder, mad is opened 2. checks if NameSmSC.dae exists in the ./daes/ folder, dae is opened 3. if both exist, user is asked a question ... */ int WORLD::LoadSmSc(char *NameSmSC) { char NewName[2048]; char NewNameFull[2048]; char ForcedDirectoryName[2048]; UnicID SmScID; SmallScene *Ret; Ret = (SmallScene*)CC_malloc(sizeof(SmallScene)); memset(Ret,0,sizeof(SmallScene)); bool bMadFile = false; bool bDaeFile = false; SmScID = SmallSceneDico.IsExist(NameSmSC); // added by waqas // // check whether its mad or dae// #ifdef _ENABLE_COLLADA_IMPORT_ if (SmScID == -1) { std::string strFileName; strFileName = std::string(".\\Mads\\") + NameSmSC + ".mad"; FILE *pFileMad = fopen(strFileName.c_str(), "r"); if (pFileMad) { bMadFile = true; fclose(pFileMad); } std::string strFileNameDae; strFileName = std::string(".\\Daes\\") + NameSmSC + ".dae"; FILE* pFileDae = fopen(strFileName.c_str(), "r"); if(pFileDae) { bDaeFile = true; fclose(pFileDae); } if (bMadFile && bDaeFile) // both files exist // { int iRet = 0; iRet = MessageBox(NULL, "Mad and Dae of same name exist, Do you want to open Mad?", "Warning", MB_YESNOCANCEL); if (iRet == IDCANCEL) return 0; if(iRet == IDYES) { bDaeFile = false; bMadFile = true; } if (iRet == IDNO ) { bDaeFile = true; bMadFile = false; } } } #endif // end of Waqas's code// if (SmScID == -1) { #ifdef _ENABLE_COLLADA_IMPORT_ if (!bDaeFile) { #endif sprintf(NewName,".\\mads\\%s.mad",NameSmSC); extern u32 MAD_2_CAMCAM(char *FileName); MAD_2_CAMCAM(NewName); #ifdef _ENABLE_COLLADA_IMPORT_ } else { sprintf(NewName,".\\daes\\%s.dae",NameSmSC); extern void Collada_2_CamCam(char* pszFileName); try { Collada_2_CamCam(NewName); } catch (std::exception& e) { MessageBox(NULL, e.what(), NULL, MB_OK); return -1; } } #endif } else { SmallScene *RetIn = pSmallScenes[SmallSceneDico.mpst_Dico[SmScID].AssociatedValue]; DestroySmSc(RetIn); pSmallScenes[SmallSceneDico.mpst_Dico[SmScID].AssociatedValue] = NULL; } sprintf(NewName,".\\media\\%s\\SmSc.Ssc",NameSmSC); if (GetSceneFileName(NewName, NewNameFull)) { UNIC_Dico Dico; UnicID NULL_ID,TRACK0_ID; Dico.Init(); Dico.GetUnic(&NULL_ID,"NULL"); Dico.GetUnic(&TRACK0_ID,"TRACK0"); sprintf(ForcedDirectoryName,".\\media\\%s\\",NameSmSC); pForcedDirectory = ForcedDirectoryName; LoadSmallScene(&Ret,NewNameFull,&Dico); Ret->IODico = Dico; Ret->CameraPosition_Save = Ret->CameraPosition; Ret->ObjectNameDico.Init(); Ret->MaterialNameDico.Init(); Ret->MultiMaterialNameDico.Init(); Ret->RootMatrix.Identity(); Ret->ObjectsBuffer = (_3D_Object*)CC_malloc(sizeof(_3D_Object)*Ret->ulNumberOfObjects); for (int i = 0 ; i < Ret->ulNumberOfObjects ; i++ ) { char Name2[2048]; Ret->IODico.GetName(&Ret->ObjectsIDs[i],Name2); Ret->ObjectsPtrs[i] = Ret->ObjectsBuffer + i; //Ret->ObjectsPtrs[i] = (_3D_Object*)CC_malloc(sizeof(_3D_Object)); memset(Ret->ObjectsPtrs[i],0,sizeof(_3D_Object)); if (GetSceneFileName(Name2, NewNameFull)) { Load_3D_Object(&Ret->ObjectsPtrs[i],NewNameFull,&Ret->IODico); } UnicID ObjectID; Ret->ObjectNameDico.GetUnic(&ObjectID,SmScGetFileName(Name2)); if (ObjectID != -1) Ret->ObjectNameDico.mpst_Dico[ObjectID].AssociatedValue = i; } //ComputeSmallSceneHierarchie(Ret); for (int i = 0 ; i < Ret->ulNumberOfObjects ; i++ ) { if (Ret->ObjectsPtrs[i]) { Ret->ObjectsPtrs[i]->OriginalGlobalMatrix = Ret->ObjectsPtrs[i]->GlobalMatrix; Ret->ObjectsPtrs[i]->OriginalLocalMatrix = Ret->ObjectsPtrs[i]->LocalMatrix; } } for (int i = 0 ; i < Ret->ulNumberOfMaterials; i++ ) { char Name2[2048]; Ret->IODico.GetName(&Ret->MaterialsIDs[i],Name2); Ret->MaterialsPtrs[i] = (_3D_Material*)CC_malloc(sizeof(_3D_Material)); memset(Ret->MaterialsPtrs[i],0,sizeof(_3D_Material)); if (GetSceneFileName(Name2, NewNameFull)) Load_3D_Material(&Ret->MaterialsPtrs[i],NewNameFull,&Ret->IODico); Ret->MaterialNameDico.GetUnic(&Ret->MaterialsPtrs[i]->MaterialNameID,SmScGetFileName(Name2)); if (Ret->MaterialsPtrs[i]->MaterialNameID != -1) Ret->MaterialNameDico.mpst_Dico[Ret->MaterialsPtrs[i]->MaterialNameID].AssociatedValue = i; } for (u32 Redir = 0;Redir < Ret->ulNumberOfMaterials ; Redir++) Ret->MaterialsRedirs[Redir] = Redir; /* Load Textures */ for (int i = 0 ; i < Ret->ulNumberOfMaterials ; i++ ) { for (int j = 0 ; j < Ret->MaterialsPtrs[i]->NumberOfLayers ; j++ ) { char Name2[2048]; Ret->IODico.GetName(&Ret->MaterialsPtrs[i]->Layers[j].TextureID,Name2); pForcedDirectory = NULL; CreateMedia(Name2,0); pForcedDirectory = ForcedDirectoryName; MediaDico.GetUnic(&Ret->MaterialsPtrs[i]->Layers[j].TextureMediaIndex,Name2); MediaDico.GetName(&Ret->MaterialsPtrs[i]->Layers[j].TextureMediaIndex,Name2); // Trying this ... Ret->MaterialsPtrs[i]->Layers[j].TextureID = Ret->MaterialsPtrs[i]->Layers[j].TextureMediaIndex; } } /* Multimaterals */ for (int i = 0 ; i < Ret->ulNumberOfMultiMats; i++ ) { char Name2[2048]; Ret->IODico.GetName(&Ret->MultiMaterialsIDs[i],Name2); Ret->MultiMaterialsPtrs[i] = (_3D_MultiMaterial*)CC_malloc(sizeof(_3D_MultiMaterial)); memset(Ret->MultiMaterialsPtrs[i],0,sizeof(_3D_MultiMaterial)); if (GetSceneFileName(Name2, NewNameFull)) { Load_3D_MultiMaterial(&Ret->MultiMaterialsPtrs[i],NewNameFull,&Ret->IODico); } } /* Lights */ for (int i = 0 ; i < Ret->ulNumberOfLights; i++ ) { char Name2[2048]; Ret->IODico.GetName(&Ret->LightsIDs[i],Name2); Ret->LightsPtrs[i] = (_3D_Light*)CC_malloc(sizeof(_3D_Light)); memset(Ret->LightsPtrs[i],0,sizeof(_3D_Light)); if (GetSceneFileName(Name2, NewNameFull)) { Load_3D_Light(&Ret->LightsPtrs[i],NewNameFull,&Ret->IODico); } } /* Meshes */ for (int i = 0 ; i < Ret->ulNumberOfMeshes; i++ ) { char Name2[2048]; Ret->IODico.GetName(&Ret->MeshesIDs[i],Name2); Ret->MeshesPtrs[i] = new Mesh(); if (GetSceneFileName(Name2, NewNameFull)) { LoadMesh(&Ret->MeshesPtrs[i],NewNameFull,&Ret->IODico); Ret->MeshesPtrs[i]->ComputeBV(); Ret->MeshesPtrs[i]->Optimize(); } } Ret->IODico.mpst_Dico[NULL_ID].AssociatedValue = -1; Ret->IODico.mpst_Dico[TRACK0_ID].AssociatedValue = -2; /* Compute Indexes in objects */ for (int i = 0 ; i < Ret->ulNumberOfObjects ; i++ ) { Ret->ObjectsPtrs[i]->FatherIndex = Ret->IODico.mpst_Dico[Ret->ObjectsPtrs[i]->FatherID].AssociatedValue; Ret->ObjectsPtrs[i]->MaterialIndex = Ret->IODico.mpst_Dico[Ret->ObjectsPtrs[i]->MaterialID].AssociatedValue; Ret->ObjectsPtrs[i]->MeshIndex = Ret->IODico.mpst_Dico[Ret->ObjectsPtrs[i]->MeshID].AssociatedValue; Ret->ObjectsPtrs[i]->MultiMaterialIndex = Ret->IODico.mpst_Dico[Ret->ObjectsPtrs[i]->MultiMaterialID].AssociatedValue; if (Ret->ObjectsPtrs[i]->FatherIndex == -1) Ret->ObjectsPtrs[i]->LocalMatrix = Ret->ObjectsPtrs[i]->GlobalMatrix; } /* Compute Indexes in Mmt */ for (int i = 0 ; i < Ret->ulNumberOfMultiMats ; i++ ) { for (int j = 0 ; j < Ret->MultiMaterialsPtrs[i]->ulNumberOfMaterials ; j++ ) { Ret->MultiMaterialsPtrs[i]->pMaterialsIndexes[j] = Ret->IODico.mpst_Dico[Ret->MultiMaterialsPtrs[i]->pMaterialsIDS[j]].AssociatedValue; } } /* Compute Indexes in light */ for (int i = 0 ; i < Ret->ulNumberOfLights ; i++ ) { Ret->LightsPtrs[i]->ObjectIndex = Ret->IODico.mpst_Dico[Ret->LightsPtrs[i]->ObjectID].AssociatedValue; } /* Compute Indexes in Skins */ for (int i = 0 ; i < Ret->ulNumberOfMeshes ; i++ ) { for (int j = 0 ; j < Ret->MeshesPtrs[i]->ulNumberOfSkins ; j++ ) { Ret->MeshesPtrs[i]->MeshSkin[j].ObjectIndex = Ret->IODico.mpst_Dico[Ret->MeshesPtrs[i]->MeshSkin[j].ObjectID].AssociatedValue; } } { // IK Solver ************************************************************************************************ char NameIK[2048]; char NameIKFull[2048]; Ret->IK = (SmallScene_IK *)CC_malloc(sizeof(SmallScene_IK)); memset(Ret->IK, 0, sizeof(SmallScene_IK)); sprintf(NameIK,".\\media\\%s\\SmSc.IKM",NameSmSC); if (GetSceneFileName(NameIK, NameIKFull)) { LoadSmallScene_IK(&Ret->IK,NameIKFull,&Ret->IODico); Ret->IK->pPI = NULL; Ret->IK->ulNumberOfInstance = 0; Ret->IK->pInitObjPatchs = NULL; Ret->IK->ulInitNumberOfPatchs = 0; u32 NewNumberOfPatch; NewNumberOfPatch = 0; for (int IK = 0 ; IK < Ret->IK->ulNumberOfPatchs ; IK++) { if ((Ret->IK->pObjPatchs[IK].ObjectID != 0) && (Ret->IK->pObjPatchs[IK].ObjectID != -1) && (Ret->IK->pObjPatchs[IK].ulFlags != 0)) { Ret->IK->pObjPatchs[IK].ObjectRefIndex = Ret->IODico.mpst_Dico[Ret->IK->pObjPatchs[IK].ObjectID].AssociatedValue; if (Ret->IK->pObjPatchs[IK].ObjectRefIndex < Ret->ulNumberOfObjects) Ret->IK->pObjPatchs[NewNumberOfPatch++] = Ret->IK->pObjPatchs[IK]; } } for (int IK = 0 ; IK < Ret->IK->ulNumberOfCollider ; IK++) { if ((Ret->IK->pColliders[IK].ObjectID != 0) && (Ret->IK->pColliders[IK].ObjectID != -1)) { Ret->IK->pColliders[IK].ObjectRefIndex = Ret->IODico.mpst_Dico[Ret->IK->pColliders[IK].ObjectID].AssociatedValue; } } Ret->IK->ulNumberOfPatchs = NewNumberOfPatch; IKPatchObjToInit(Ret); IKPatchProcess(Ret, true); } } // IK end ***************************************************************************************************** if (Ret->MustComputeInverseSkinning && Ret->ulNumberOfMeshes > 0) { // ComputeSmallSceneHierarchie(Ret); u32 *meshesProceeded = (u32 *)CC_malloc(Ret->ulNumberOfMeshes*sizeof(u32)); int meshesProceededNb = 0; for (int i = 0 ; i < Ret->ulNumberOfObjects; i++ ) { if (Ret->ObjectsPtrs[i]->MeshIndex != -1) { bool proceedMesh = true; for (int j = 0; proceedMesh && j < meshesProceededNb; j++) if (Ret->ObjectsPtrs[i]->MeshIndex == meshesProceeded[j]) proceedMesh = false; if (proceedMesh) { MATRIX InvO; Ret->ObjectsPtrs[i]->GlobalMatrix.Inverse(InvO); ComputeSkinning(Ret,Ret->MeshesPtrs[Ret->ObjectsPtrs[i]->MeshIndex],&InvO, 1); meshesProceeded[meshesProceededNb++] = Ret->ObjectsPtrs[i]->MeshIndex; } } }//*/ CC_free(meshesProceeded); } //Dico.Destroy(); SmallSceneDico.GetUnic(&SmScID,NameSmSC); pSmallScenes[SmScCreateID] = Ret; SmallSceneDico.mpst_Dico[SmScID].AssociatedValue = SmScCreateID; SmScCreateID = 0; ComputeLastSon(Ret); while (pSmallScenes[SmScCreateID] && (SmScCreateID < MAX_SmallSCenes)) {SmScCreateID++;}; if (SmScCreateID == MAX_SmallSCenes) *((u32 *)0) = *((u32 *)4); //<- CRASH !! pForcedDirectory = NULL; return SmScID; } pForcedDirectory = NULL; return -1; } void WORLD::DeleteSmSc(char *smallSceneName) { UnicID SceneID; SmallScene *Smsc; SceneID = SmallSceneDico.IsExist(smallSceneName); if (SceneID == -1) return; Smsc = pSmallScenes[SmallSceneDico.mpst_Dico[SceneID].AssociatedValue]; if (Smsc) { DestroySmSc(Smsc); pSmallScenes[SmallSceneDico.mpst_Dico[SceneID].AssociatedValue] = NULL; } SmallSceneDico.DelWord(smallSceneName); } void WORLD::DestroyAllSMSC() { u32 Counter = MAX_SmallSCenes; while (Counter--) { SmallScene *Smsc; Smsc = pSmallScenes[Counter]; if (Smsc) { DestroySmSc(Smsc); pSmallScenes[Counter] = NULL; } } SmallSceneDico.Destroy(); } void WORLD::DestroySmSc(SmallScene *Ret) { UNIC_Dico Dico; Dico.Init(); for (int i = 0 ; i < Ret->ulNumberOfObjects ; i++ ) { Free_3D_Object(Ret->ObjectsPtrs[i],&Dico); //CC_free(Ret->ObjectsPtrs[i]); Ret->ObjectsPtrs[i] = NULL; } CC_free(Ret->ObjectsBuffer); for (int i = 0 ; i < Ret->ulNumberOfMaterials; i++ ) { if ( MediaDico.mpst_Dico) { for (int j=0; jMaterialsPtrs[i]->NumberOfLayers; j++) { u32 MediaIndex = Ret->MaterialsPtrs[i]->Layers[j].TextureMediaIndex; if (MediaIndex != -1) MediaIndex = MediaDico.mpst_Dico[MediaIndex].AssociatedValue; if (MediaIndex != -1) DestroyMedia(MediaIndex, 2); } } Free_3D_Material(Ret->MaterialsPtrs[i],&Dico); CC_free(Ret->MaterialsPtrs[i]); Ret->MaterialsPtrs[i] = NULL; } for (int i = 0 ; i < Ret->ulNumberOfMultiMats; i++ ) { Free_3D_MultiMaterial(Ret->MultiMaterialsPtrs[i],&Dico); CC_free(Ret->MultiMaterialsPtrs[i]); Ret->MultiMaterialsPtrs[i] = NULL; } for (int i = 0 ; i < Ret->ulNumberOfLights; i++ ) { Free_3D_Light(Ret->LightsPtrs[i],&Dico); CC_free(Ret->LightsPtrs[i]); Ret->LightsPtrs[i] = NULL; } for (int i = 0 ; i < Ret->ulNumberOfMeshes; i++ ) { FreeMesh(Ret->MeshesPtrs[i],&Dico); CC_free(Ret->MeshesPtrs[i]); Ret->MeshesPtrs[i] = NULL; } for (int i = 0 ; i < MAX_STATES; i++ ) { SmallScene_ObjectStateFree(Ret, i); } if (Ret->IK) { for (int K = 0 ; K < Ret->IK->ulNumberOfInstance ; K++) { if (Ret->IK->pPI[K]) CC_free(Ret->IK->pPI[K]); Ret->IK->pPI[K] = NULL; } if (Ret->IK->pPI) CC_free(Ret->IK->pPI); Ret->IK->pPI = NULL; Ret->IK->ulNumberOfInstance = 0; FreeSmallScene_IK(Ret->IK,&Dico); CC_free(Ret->IK); Ret->IK = NULL; } Ret->ObjectNameDico.Destroy(); Ret->MaterialNameDico.Destroy(); FreeSmallScene(Ret,&Dico); CC_free(Ret); Dico.Destroy(); } SmallScene *WORLD::SmallNameToScene(char *Name) { UnicID SceneID; SceneID = SmallSceneDico.IsExist(Name); if (SceneID == -1) return NULL; return pSmallScenes[SmallSceneDico.mpst_Dico[SceneID].AssociatedValue]; } _3D_Material *WORLD::MaterialNameToMaterial(SmallScene *Smsc, char *Name) { UnicID MatID; MatID = Smsc->MaterialNameDico.IsExist(Name); if (MatID == -1) { char MaterialNameMAT[2048]; sprintf(MaterialNameMAT, "%s.MAT", Name); MatID = Smsc->MaterialNameDico.IsExist(MaterialNameMAT); } if ((MatID != -1) && (MatID = Smsc->MaterialNameDico.mpst_Dico[MatID].AssociatedValue) != -1) return Smsc->MaterialsPtrs[MatID]; return NULL; } int WORLD::ConcatMaterial(char *SmscName, char *MatName, char *SmscNameToAdd, char *MatToAddName) { char NewName[1024]; SmallScene *Smsc = SmallNameToScene(SmscName); if (!Smsc) return 0; _3D_Material *Mat = MaterialNameToMaterial(Smsc, MatName); _3D_Material *MatToAdd; char ForcedDirectoryName[2048]; sprintf(ForcedDirectoryName,".\\media\\%s\\",SmscNameToAdd); pForcedDirectory = ForcedDirectoryName; if (!GetSceneFileName(MatToAddName, NewName)) return 0; MatToAdd = (_3D_Material*)CC_malloc(sizeof(_3D_Material)); memset(MatToAdd,0,sizeof(_3D_Material)); UNIC_Dico Dico; Dico.Init(); Load_3D_Material(&MatToAdd,NewName,&Dico); for (int j = 0 ; j < MatToAdd->NumberOfLayers ; j++ ) { char Name2[2048]; Dico.GetName(&MatToAdd->Layers[j].TextureID,Name2); pForcedDirectory = NULL; CreateMedia(Name2,0); pForcedDirectory = ForcedDirectoryName; MediaDico.GetUnic(&MatToAdd->Layers[j].TextureMediaIndex,Name2); MediaDico.GetName(&MatToAdd->Layers[j].TextureMediaIndex,Name2); Mat->Layers[Mat->NumberOfLayers++] = MatToAdd->Layers[j]; // Trying this ... MatToAdd->Layers[j].TextureID = MatToAdd->Layers[j].TextureMediaIndex; } CC_free(MatToAdd); pForcedDirectory = NULL; return 1; } int WORLD::SaveMaterial(_3D_Material *Mat, char *SmscName, char *MatName) { char ForcedDirectoryName[2048]; UNIC_Dico Dico; Dico.Init(); sprintf(ForcedDirectoryName,".\\media\\%s\\Modified\\%s",SmscName, MatName); Save_3D_Material(Mat,ForcedDirectoryName,&MediaDico); return 1; } int WORLD::LightNameToIndex(SmallScene *Smsc, char *LightName) { char ObjectNameOBJ[2048]; UnicID ObjectID; sprintf(ObjectNameOBJ, "%s.OBJ", LightName); ObjectID = Smsc->ObjectNameDico.IsExist(ObjectNameOBJ); if (ObjectID == -1) return -1; for (int lightIdx = 0; lightIdx < Smsc->ulNumberOfLights; lightIdx++) { if (Smsc->LightsPtrs[lightIdx]->ObjectID == ObjectID) return lightIdx; } return -1; } int WORLD::MediaSetMatrix(SmallScene *SmSc,u32 MediaIndex,u32 TrackNum, u32 status, u32 useTimeLineCorrection) { u32 FrameKey = 0; if (SmSc) { SmSc->RootMatrix .T . z = -10000.0f; SmSc->fFocalToUseForNextRender = 0.0f; } if ((MediaIndex != -1) && (ID_MEDIA[MediaIndex]) && (ID_MEDIA[MediaIndex]->Tracks)) { if (SmSc && (TrackNum < ID_MEDIA[MediaIndex]->Tracks->ulNumberOfTracks)) { { TrackPlayer_Stream *pTRK; Vector Scale; MATRIX DecompressedMat; u32 Valid; pTRK = &ID_MEDIA[MediaIndex]->Tracks->TracksPtrs[TrackNum]; // HARD change Try; //if (useTimeLineCorrection) // FrameKey = ID_MEDIA[MediaIndex]->Tracks->GetTimeLine(ID_MEDIA[MediaIndex]->ulCurrentFrame + ID_MEDIA[MediaIndex]->lCurrentTrackOffset, &ID_MEDIA[MediaIndex]->Image); //else // FrameKey = ID_MEDIA[MediaIndex]->ulCurrentFrame; //ID_MEDIA[MediaIndex]->lCurrentTrackOffset = FrameKey - ID_MEDIA[MediaIndex]->ulCurrentFrame; //if (useTimeLineCorrection) // FrameKey = ID_MEDIA[MediaIndex]->Tracks->GetTimeLine(ID_MEDIA[MediaIndex]->ulCurrentFrame, &ID_MEDIA[MediaIndex]->Image); //else // FrameKey = ID_MEDIA[MediaIndex]->ulCurrentFrame; /* Decompress matrix */ DecompressedMat.Identity(); DecompressedMat.T = Vector(0,0,-10.0f); FrameKey = TIME_TO_FRAME(ID_MEDIA[MediaIndex]->dCurrentTime, ID_MEDIA[MediaIndex]->dAvgFramePerSecond); //Valid = pTRK->Get(FrameKey,&DecompressedMat); Valid = pTRK->Get(ID_MEDIA[MediaIndex]->dCurrentTime*ID_MEDIA[MediaIndex]->dAvgFramePerSecond,&DecompressedMat); ID_MEDIA[MediaIndex]->Tracks->GetScale(TrackNum,&Scale); if (Valid != -1) { if ((Valid & ~status) == 0) { if (DecompressedMat.T.SqrNorm() != 0.0f) AffectTrackMatrixToSmallScene(0, SmSc,3,&DecompressedMat); } else { DecompressedMat.T.z = -1000.0f; AffectTrackMatrixToSmallScene(0, SmSc,3,&DecompressedMat); } AffectTrackScaleToSmallScene(SmSc,&Scale); } TrackPlayer_Descriptors *pTDesc = ID_MEDIA[MediaIndex]->Tracks->GetDescriptor(FrameKey); if (pTDesc->CurrentFocal == 0.0f) SmSc->fFocalToUseForNextRender = ID_MEDIA[MediaIndex]->MediaFocale; else SmSc->fFocalToUseForNextRender = pTDesc->CurrentFocal; } } } return FrameKey; } void WORLD::AffectTrackMatrixToSmallScene(int SmoothNumber, SmallScene *Smsc,u32 Affect,MATRIX *pTrckMatrix) { if (Smsc ) { if (Affect & 1) /* Trans */ { Smsc->RootMatrix.T = Smsc->CameraPosition.T; Smsc->RootMatrix.T -= Smsc->CameraPosition.K * (pTrckMatrix->T.z / 100.0f); Smsc->RootMatrix.T += Smsc->CameraPosition.I * (pTrckMatrix->T.x / 100.0f); Smsc->RootMatrix.T += Smsc->CameraPosition.J * (pTrckMatrix->T.y / 100.0f); } if (Affect & 2) /* Rot */ { Vector SaveRootMatrixT = Smsc->RootMatrix.T; MATRIX TMatrix = *pTrckMatrix; Vector Swap; if ((FrmFactorRotation != 0.0 && FrmFactorRotation != 1.0) || FrmFactorRotationLimit > 0) MatrixStretchAngle(&TMatrix, FrmFactorRotation, FrmFactorRotationLimit); Swap = TMatrix.K; TMatrix.K = TMatrix.J; TMatrix.J = Swap; TMatrix.Transp(); TMatrix.K *= -1.0f; TMatrix.Transp(); Smsc->RootMatrix = TMatrix; Smsc->RootMatrix *= Smsc->CameraPosition; Smsc->RootMatrix.T = SaveRootMatrixT; } SetSmoothMatrix(SmoothNumber, &Smsc->RootMatrix, Affect, 0); } } void WORLD::AffectTrackSubMatrixToSmallScene(int SmoothNumber, SmallScene *SmSc, char *ObjName,u32 Affect,MATRIX *pTrckMatrix, int axeInversion) { u32 objIdx; _3D_Object *pObj; int rotations; int ObjectIndex = 0; if (ObjName) { ObjectIndex = SmSc->ObjectNameDico.IsExist(ObjName); if (ObjectIndex == -1) { char ObjNameIn[256]; sprintf(ObjNameIn, "%s.OBJ", ObjName); ObjectIndex = SmSc->ObjectNameDico.IsExist(ObjNameIn); } if (ObjectIndex != -1) { ObjectIndex = SmSc->ObjectNameDico.mpst_Dico[ObjectIndex].AssociatedValue; } if (ObjectIndex == -1) ObjectIndex = 0; } pObj = SmSc->ObjectsPtrs[ObjectIndex]; u32 Fi = pObj->FatherIndex; if (Fi != -1) { Vector AffectMatrixT(0,0,0); MATRIX AffectMatrix; if (Affect & 1) { AffectMatrixT = pTrckMatrix->T * (1.0f/100); if (FrmFactorTranslation != 0.0 && FrmFactorTranslation != 1.0) AffectMatrixT *= FrmFactorTranslation; } if (Affect & 2) { AffectMatrix = *pTrckMatrix; if ((FrmFactorRotation != 0.0 && FrmFactorRotation != 1.0) || FrmFactorRotationLimit > 0) MatrixStretchAngle(&AffectMatrix, FrmFactorRotation, FrmFactorRotationLimit); } AffectMatrix.T = AffectMatrixT; SetSmoothMatrix(SmoothNumber, &AffectMatrix, Affect, axeInversion); AffectMatrix *= pObj->LocalMatrix; pObj->LocalMatrix = AffectMatrix; ComputeSmallSceneHierarchie(SmSc); } } void WORLD::AffectTrackScaleToSmallScene(SmallScene *Smsc,Vector *Scale) { if (Smsc ) { Smsc->RootMatrix.I.Normalize(); Smsc->RootMatrix.J.Normalize(); Smsc->RootMatrix.K.Normalize(); Smsc->RootMatrix.I *= Scale->x; Smsc->RootMatrix.J *= Scale->z; Smsc->RootMatrix.K *= Scale->y; } } void WORLD::MoveSceneCamera(int SmoothNumber, SmallScene *SmSc, int Affect, IDFX *idFX) { MATRIX mCalc; Vector local; Vector trackInT; MATRIX *pTrckMatrix= &idFX->CurrentMatrix_U; if (Affect == 0) { BaseTranslate.x = -1; //prevMatrix[index]->angle = 0.0; return; } if (BaseTranslate.x == -1 || !idFX->SF_U.CamPlaced) { BaseTranslate = pTrckMatrix->T; idFX->SF_U.CamPlaced = 1; } trackInT = pTrckMatrix->T - BaseTranslate; if (Affect & 1) { mCalc.T = SmSc->CameraPosition.T; mCalc.T -= SmSc->CameraPosition.K * (trackInT.z / 100.0f); mCalc.T += SmSc->CameraPosition.I * (trackInT.x / 100.0f); mCalc.T += SmSc->CameraPosition.J * (trackInT.y / 100.0f); local = SmSc->CameraPosition.T - mCalc.T; local.y = -local.y; if ((FrmFactorRotation != 0.0 && FrmFactorRotation != 1.0) || FrmFactorRotationLimit > 0) local *= FrmFactorRotation; SmSc->CameraPosition.T = SmSc->CameraPosition.T - local; } if (Affect & 2) { Vector saveMCalcT; MATRIX TMatrix; MATRIX TMatrixInv; saveMCalcT = SmSc->CameraPosition.T; TMatrix = *pTrckMatrix; if ((FrmFactorRotation != 0.0 && FrmFactorRotation != 1.0) || FrmFactorRotationLimit > 0) MatrixStretchAngle(&TMatrix, FrmFactorRotation, FrmFactorRotationLimit); mCalc = TMatrix; mCalc*= SmSc->CameraPosition; SmSc->CameraPosition = mCalc; SmSc->CameraPosition.T = saveMCalcT; } SetSmoothMatrix(SmoothNumber, &SmSc->CameraPosition, Affect, 0); } //#pragma optimize("",off) void WORLD::ComputeLastSon(SmallScene *SmSc) { /* _3D_Object **pObj = SmSc->ObjectsPtrs; // Compute hierarchie for (int ObjectIndex=0; ObjectIndexulNumberOfObjects ; ObjectIndex++) { SmSc->ObjectsPtrs[ObjectIndex]->Flags.UPDATE = 1; pObj = SmSc->ObjectsPtrs + ObjectIndex + 1; s32 LastSon = ObjectIndex; for ( int i = ObjectIndex + 1; i < SmSc->ulNumberOfObjects ; i++ , pObj++) { u32 Father; Father = (*pObj)->FatherIndex; if ((Father != -1) && SmSc->ObjectsPtrs[Father]->Flags.UPDATE) { (*pObj)->Flags.UPDATE = 1; LastSon = i; } } pObj = SmSc->ObjectsPtrs + ObjectIndex; (*pObj)->LastSonIndex = LastSon; for ( int i = ObjectIndex; i <= LastSon; i++ , pObj++) (*pObj)->Flags.UPDATE = 0; } */ for (int ObjectIndex=0; ObjectIndexulNumberOfObjects ; ObjectIndex++) SmSc->ObjectsPtrs[ObjectIndex]->LastSonIndex = ObjectIndex; for (int ObjectIndex=SmSc->ulNumberOfObjects-1; ObjectIndex>=0; ObjectIndex--) { u32 Father = SmSc->ObjectsPtrs[ObjectIndex]->FatherIndex; if (Father != -1) SmSc->ObjectsPtrs[Father]->LastSonIndex = max(SmSc->ObjectsPtrs[Father]->LastSonIndex, SmSc->ObjectsPtrs[ObjectIndex]->LastSonIndex); } int toto = 1; } void WORLD::SmallScene_HideObject(SmallScene *SmSc,u32 ObjectIndex,u32 Hide, u32 AffectChildren) { _3D_Object **pObj = SmSc->ObjectsPtrs; /* Compute hierarchie */ SmSc->ObjectsPtrs[ObjectIndex]->Flags.HIDEN = Hide; SmSc->ObjectsPtrs[ObjectIndex]->Flags.UPDATE = AffectChildren; if (AffectChildren) { pObj += ObjectIndex + 1; s32 LastSon = SmSc->ObjectsPtrs[ObjectIndex]->LastSonIndex; for ( int i = ObjectIndex + 1; i <= LastSon; i++ , pObj++) { u32 Father; Father = (*pObj)->FatherIndex; if ((Father != -1) && SmSc->ObjectsPtrs[Father]->Flags.UPDATE) { (*pObj)->Flags = SmSc->ObjectsPtrs[Father]->Flags; } } pObj = SmSc->ObjectsPtrs + ObjectIndex; for ( int i = ObjectIndex; i <= LastSon; i++ , pObj++) { (*pObj)->Flags.UPDATE = 0; } } } void WORLD::SmallScene_RestoreInitialPosition(SmallScene *SmSc,u32 ObjectIndex) { _3D_Object **pObj = SmSc->ObjectsPtrs; /* Compute hierarchie */ SmSc->ObjectsPtrs[ObjectIndex]->Flags.UPDATE = 1; for ( int i = 0 ; i < SmSc->ulNumberOfObjects ; i++ , pObj++) { u32 Father; Father = (*pObj)->FatherIndex; if ((Father != -1) && SmSc->ObjectsPtrs[Father]->Flags.UPDATE) { (*pObj)->Flags.UPDATE = 1; } } pObj = SmSc->ObjectsPtrs; for ( int i = 0 ; i < SmSc->ulNumberOfObjects ; i++ , pObj++) { if ((*pObj)->Flags.UPDATE) { (*pObj)->LocalMatrix = (*pObj)->OriginalLocalMatrix; } (*pObj)->Flags.UPDATE = 0; } } void WORLD::ComputeSmallSceneObjectLookAt(SmallScene *Smsc,u32 Affect,u32 ObjectREF,u32 ObjectRefLA) { MATRIX RM; MATRIX LAM; MATRIX IRM; Vector Scale; ComputeSmallSceneHierarchie(Smsc,ObjectREF); if (ObjectRefLA != -1) { ComputeSmallSceneHierarchie(Smsc,ObjectRefLA); LAM = Smsc->ObjectsPtrs[ObjectRefLA]->GlobalMatrix; } else LAM = Smsc->CameraPosition; RM = Smsc->ObjectsPtrs[ObjectREF]->GlobalMatrix; RM.GetScale(Scale); RM.SetScale(Vector(1,1,1)); LAM.T = IRM.T = RM.T = Vector(0,0,0); RM.Inverse(IRM); IRM *= LAM; if ((Affect != -1)&&(Affect & (32 + 64 + 128))) { Quat RQ; Vector V; RQ.ComputeFromMatrix(&IRM); RQ.TransforToVector(V); if (Affect & 32) V.x = 0.0f; if (Affect & 64) V.y = 0.0f; if (Affect & 128) V.z = 0.0f; RQ = V; RQ.TransforToMatrix(&IRM); } Vector SaveT = Smsc->ObjectsPtrs[ObjectREF]->GlobalMatrix.T; Smsc->ObjectsPtrs[ObjectREF]->GlobalMatrix *= IRM; Smsc->ObjectsPtrs[ObjectREF]->GlobalMatrix.T = SaveT; ComputeSmallSceneHierarchie_Local(Smsc,ObjectREF); } void WORLD::ComputeSmallSceneHierarchie(SmallScene *SmSc,u32 ObjectIndex) { _3D_Object **pObj = SmSc->ObjectsPtrs; /* Compute hierarchie */ if (ObjectIndex != -1) { u32 Father,Current; pObj += ObjectIndex; Father = (*pObj)->FatherIndex; if (Father != -1) { ComputeSmallSceneHierarchie(SmSc,Father); (*pObj)->GlobalMatrix = (*pObj)->LocalMatrix; (*pObj)->GlobalMatrix *= SmSc->ObjectsPtrs[Father]->GlobalMatrix; } else { (*pObj)->GlobalMatrix = (*pObj)->LocalMatrix; (*pObj)->GlobalMatrix *= SmSc->RootMatrix; } } else for ( int i = 0 ; i < SmSc->ulNumberOfObjects ; i++ , pObj++) { u32 Father,Current; Father = (*pObj)->FatherIndex; if (Father != -1) { (*pObj)->GlobalMatrix = (*pObj)->LocalMatrix; (*pObj)->GlobalMatrix *= SmSc->ObjectsPtrs[Father]->GlobalMatrix; } else { (*pObj)->GlobalMatrix = (*pObj)->LocalMatrix; (*pObj)->GlobalMatrix *= SmSc->RootMatrix; } } } void WORLD::ComputeSmallSceneHierarchie_Local(SmallScene *SmSc,u32 ObjectIndex) { _3D_Object **pObj = SmSc->ObjectsPtrs; /* Compute hierarchie */ if (ObjectIndex != -1) { u32 Father,Current; pObj += ObjectIndex; Father = (*pObj)->FatherIndex; if (Father != -1) { MATRIX mFi; ComputeSmallSceneHierarchie_Local(SmSc,Father); SmSc->ObjectsPtrs[Father]->GlobalMatrix.Inverse(mFi); (*pObj)->LocalMatrix = (*pObj)->GlobalMatrix ; (*pObj)->LocalMatrix *= mFi; } else { MATRIX mFi; SmSc->RootMatrix.Inverse(mFi); (*pObj)->LocalMatrix = (*pObj)->GlobalMatrix ; (*pObj)->LocalMatrix *= mFi; } } else { for ( int i = 0 ; i < SmSc->ulNumberOfObjects ; i++ , pObj++) { u32 Father,Current; Father = (*pObj)->FatherIndex; if (Father != -1) { MATRIX mFi; SmSc->ObjectsPtrs[Father]->GlobalMatrix.Inverse(mFi); (*pObj)->LocalMatrix = (*pObj)->GlobalMatrix ; (*pObj)->LocalMatrix *= mFi; } else { MATRIX mFi; SmSc->RootMatrix.Inverse(mFi); (*pObj)->LocalMatrix = (*pObj)->GlobalMatrix ; (*pObj)->LocalMatrix *= mFi; } } } } void WORLD::GetBVSon(MATRIX *matrix, Vector *BVSonMin, Vector *BVSonMax) { Vector globalBounds[8]; for (int i=0; i<8; i++) { globalBounds[i].x = (i & 1) ? BVSonMax->x : BVSonMin->x; globalBounds[i].y = (i & 2) ? BVSonMax->y : BVSonMin->y; globalBounds[i].z = (i & 4) ? BVSonMax->z : BVSonMin->z; globalBounds[i] = *matrix*globalBounds[i]; } *BVSonMin = *globalBounds; *BVSonMax = *globalBounds; for (int i=1; i<8; i++) { BVSonMin->Min(globalBounds[i]); BVSonMax->Max(globalBounds[i]); } } void SetBV(_3D_Object *pObj, Vector *BVMin, Vector *BVMax) { if (pObj->BVMin.SqrNorm() == 0 && pObj->BVMax.SqrNorm() == 0) { pObj->BVMin = *BVMin; pObj->BVMax = *BVMax; } else { pObj->BVMin.Min(*BVMin); pObj->BVMax.Max(*BVMax); } } void WORLD::ComputeSmallSceneBV(SmallScene *SmSc) { _3D_Object **pObj = SmSc->ObjectsPtrs; Vector BVMin, BVMax; for (int i=0; iulNumberOfObjects; i++) { memset(&pObj[i]->BVMin, 0, sizeof(Vector)); memset(&pObj[i]->BVMax, 0, sizeof(Vector)); } int Counter = SmSc->ulNumberOfObjects; while (Counter--) { if (pObj[Counter]->MeshIndex != -1) { BVMin = SmSc->MeshesPtrs[pObj[Counter]->MeshIndex]->BVMin; BVMax = SmSc->MeshesPtrs[pObj[Counter]->MeshIndex]->BVMax; SetBV(pObj[Counter], &BVMin, &BVMax); } if ((pObj[Counter]->BVMin.SqrNorm() != 0 || pObj[Counter]->BVMax.SqrNorm() != 0) && pObj[Counter]->FatherIndex != -1) { BVMin = pObj[Counter]->BVMin; BVMax = pObj[Counter]->BVMax; GetBVSon(&pObj[Counter]->LocalMatrix, &BVMin, &BVMax); SetBV(pObj[pObj[Counter]->FatherIndex], &BVMin, &BVMax); } } } u32 COL_MulColor(u32 A,u32 B) { u32 Com[4]; Com[0] = ((u32)(A & 0xff) * (u32)(B & 0xff))>>8; A >>= 8;B >>= 8; Com[1] = ((u32)(A & 0xff) * (u32)(B & 0xff))>>8; A >>= 8;B >>= 8; Com[2] = ((u32)(A & 0xff) * (u32)(B & 0xff))>>8; A >>= 8;B >>= 8; Com[3] = ((u32)(A & 0xff) * (u32)(B & 0xff))>>8; A >>= 8;B >>= 8; return Com[0] + (Com[1] << 8) + (Com[2] << 16) + (Com[3] << 24); } static int __cdecl pObject_Compare(const void *elem1, const void *elem2 ) { _3D_Object *O1,*O2; O1 = *(_3D_Object **)elem1; O2 = *(_3D_Object **)elem2; if (O1->DrawOrder == O2->DrawOrder) return 0; if (O1->DrawOrder < O2->DrawOrder) return -1; else return 1; } u32 WORLD::RenderSmallScene(char *Name,u32 DrawMode) { /* Compute hierarchie */ MATRIX MatrixToSet,CP; u32 FakeMaterialIndex; float Current_focale; SmallScene *SmSc; //MATRIX InverseRootMat; SmSc = SmallNameToScene(Name); if (SmSc == NULL) return false; if (SmSc->fFocalToUseForNextRender == 0) Current_focale = GetCurrentFocale(); else Current_focale = SmSc->fFocalToUseForNextRender; if (SmSc->HoloGraphicWindowWidth) DI->Holographic(&SmSc->HoloGraphicVector,SmSc->HoloGraphicWindowWidth); else DI->Perspective(Current_focale); if (SmSc->ulMustBeReload) { UnicID SceneID; LoadSmSc(Name); SceneID = SmallSceneDico.IsExist(Name); if (SceneID == -1) return false; SmSc = pSmallScenes[SmallSceneDico.mpst_Dico[SceneID].AssociatedValue]; SmSc->ulMustBeReload = 0; TouchFur(NULL); } _3D_MultiMaterial stFakeMmt; MatrixToSet.Identity(); static int Axis = 0; static float Angle = 0; Vector Swap; u32 invertBackface; CP = SmSc->CameraPosition; if (((CP.I^CP.J)*CP.K) > 0) invertBackface = false; else invertBackface = true; CP.K *= -1.0f; CP.Inverse(MatrixToSet);//*/ stFakeMmt.pMaterialsIndexes = &FakeMaterialIndex; //SmSc->RootMatrix.Inverse(InverseRootMat); /* picking preparation Begin */ if (*PickReportCurrent.PickingClass) { strcpy(PickReportCurrent.CollidedSmallSceneName,Name); } /* picking preparation end */ ComputeSmallSceneHierarchie(SmSc); if (RenderDrawSortNumberMax < SmSc->ulNumberOfObjects) { if (pRenderDrawSort) CC_free(pRenderDrawSort); pRenderDrawSort = (_3D_Object **)CC_malloc(SmSc->ulNumberOfObjects*sizeof(_3D_Object **)); RenderDrawSortNumberMax = SmSc->ulNumberOfObjects; } memcpy(pRenderDrawSort,SmSc->ObjectsPtrs,SmSc->ulNumberOfObjects*sizeof(_3D_Object **)); qsort(pRenderDrawSort,SmSc->ulNumberOfObjects,sizeof(_3D_Object **),pObject_Compare); _3D_Object **pObj = pRenderDrawSort; for ( int i = 0 ; i < SmSc->ulNumberOfObjects ; i++ , pObj++) { u32 Current; Mesh *RenderMesh; if (((*pObj)->MeshIndex != -1) && (!(*pObj)->Flags.HIDEN)) { RenderMesh = SmSc->MeshesPtrs[(*pObj)->MeshIndex]; } else continue; _3D_MultiMaterial *pUsedMmt; if ((*pObj)->MaterialIndex != -1) { /* Render with SingleMaterial */ stFakeMmt.ulNumberOfMaterials = 1; FakeMaterialIndex = (*pObj)->MaterialIndex; pUsedMmt = &stFakeMmt; } else if (SmSc->MultiMaterialsPtrs && (*pObj)->MultiMaterialIndex != -1 && (*pObj)->MultiMaterialIndex < SmSc->ulNumberOfMultiMats) { /* Render with MultiMaterial */ pUsedMmt = SmSc->MultiMaterialsPtrs[(*pObj)->MultiMaterialIndex]; } else { /* Render with SingleMaterial */ stFakeMmt.ulNumberOfMaterials = 1; FakeMaterialIndex = (*pObj)->MaterialIndex; pUsedMmt = &stFakeMmt; } MATRIX WM; WM = (*pObj)->GlobalMatrix; WM.T += (*pObj)->GlobalMatrix.I * (*pObj)->Pivot.x; WM.T += (*pObj)->GlobalMatrix.J * (*pObj)->Pivot.y; WM.T += (*pObj)->GlobalMatrix.K * (*pObj)->Pivot.z; WM *= MatrixToSet; DI->Matrix(&WM); /* Save original points */ Vector *OriginalPoints,*OriginalPointsN,*OriginalPointsUV; OriginalPoints = RenderMesh->Points; OriginalPointsUV = RenderMesh->PointsUV; OriginalPointsN = RenderMesh->PointsN; /* Morphing *******************************************************************************************************/ if (!(SkipFunctions & SKIP_SKINNING)) ComputeMorphing(SmSc, RenderMesh); /* Skining *******************************************************************************************************/ if (!(SkipFunctions & SKIP_SKINNING)) if (RenderMesh->ulNumberOfSkins) { MATRIX invo; (*pObj)->GlobalMatrix.Inverse(invo); ComputeSkinning(SmSc, RenderMesh,&invo); } /* Particules Process ******************************************************************************************/ if (CollisionOn) ComputeCollision(Name, i, RenderMesh, (*pObj)->GlobalMatrix); if (ParticuleFromMesh) ComputeMeshParticules(Name, *pObj, RenderMesh, &(*pObj)->GlobalMatrix); if (1) //YTEST ComputeMeshFur(Name, *pObj, RenderMesh, &(*pObj)->GlobalMatrix); /* Move linked objects ******************************************************************************************/ if (SmSc->ulNumberOfLinks) { for (int linkIdx=0; linkIdxulNumberOfLinks; linkIdx++) { if (SmSc->pLink[linkIdx].done && SmSc->pLink[linkIdx].MeshIndex == (*pObj)->MeshIndex) { // translation only for the moment, if not, matrix compute needed Vector NewPos = (*pObj)->GlobalMatrix * RenderMesh->Points[SmSc->pLink[linkIdx].MeshPointIndex]; SmSc->ObjectsPtrs[SmSc->pLink[linkIdx].ObjectIndex]->GlobalMatrix.T = NewPos; ComputeSmallSceneHierarchie_Local(SmSc, SmSc->pLink[linkIdx].ObjectIndex); /*/ Force Original position ... SmSc->ObjectsPtrs[SmSc->pLink[linkIdx].ObjectIndex]->OriginalGlobalMatrix.T = SmSc->ObjectsPtrs[SmSc->pLink[linkIdx].ObjectIndex]->GlobalMatrix.T; SmSc->ObjectsPtrs[SmSc->pLink[linkIdx].ObjectIndex]->OriginalLocalMatrix.T = SmSc->ObjectsPtrs[SmSc->pLink[linkIdx].ObjectIndex]->LocalMatrix.T; //*/ } } } /* ****************************************************************************************************************/ /* Render *******************************************************************************************************/ /* ****************************************************************************************************************/ /*pCompressed[0] = (u16)CompressedNumber; pCompressed[1] = (u16)CompressedSubIndex;*/ u32 Base,ulNumberOfSubObjects; u16 FakeCompressed[2]; u16 *pCompressed; Base = 0; ulNumberOfSubObjects = RenderMesh->ulNumberOfSubObjects; pCompressed = (u16*)RenderMesh->FaceSubObjectIndexes; if (ulNumberOfSubObjects == 0) { RenderMesh->CompressSubObjects(); // YTEST ulNumberOfSubObjects = RenderMesh->ulNumberOfSubObjects; if (ulNumberOfSubObjects == 0) { FakeCompressed[0] = RenderMesh->NumberOfFaces; FakeCompressed[1] = 0; pCompressed = FakeCompressed; ulNumberOfSubObjects = 1; } } for (int Sub = 0 ; Sub < ulNumberOfSubObjects ; Sub++) { _3D_Material *pCurrentMat; _3D_Material FakeMat; u32 MaterialID; MaterialID = pCompressed[1]; if (MaterialID >= pUsedMmt->ulNumberOfMaterials) MaterialID = pUsedMmt->ulNumberOfMaterials - 1; MaterialID = pUsedMmt->pMaterialsIndexes[MaterialID]; if (MaterialID == -1) { pCurrentMat = &FakeMat; FakeMat.NumberOfLayers = 1; FakeMat.Layers[0].TextureID = -1; FakeMat.Layers[0].TextureMediaIndex = -1; GLOB_SetDefaultRS(&FakeMat.Layers[0].RenderState); FakeMat.Layers[0].ColorMultiplier = -1; } else { MaterialID = SmSc->MaterialsRedirs[MaterialID]; if (MaterialID < SmSc->ulNumberOfMaterials) pCurrentMat = SmSc->MaterialsPtrs[MaterialID]; else pCurrentMat = SmSc->MaterialsPtrs[0]; } u32 CurrentColor,MulColor; CurrentColor = DI->GetCurrentColor(); if ((SmSc->ulNumberOfLights) && (DrawMode != 2) && (!(SkipFunctions & SKIP_LIGHTING))) { MATRIX InvO; (*pObj)->GlobalMatrix.Inverse(InvO); for (int LC = 0;LC < SmSc->ulNumberOfLights ; LC++) { if (SmSc->LightsPtrs[LC] && SmSc->LightsPtrs[LC]->IsOn && (SmSc->LightsPtrs[LC]->ObjectIndex < SmSc->ulNumberOfObjects)) { MATRIX AInB; Vector Position; Vector Direction; if (!SmSc->ObjectsPtrs[SmSc->LightsPtrs[LC]->ObjectIndex]->Flags.HIDEN) { AInB = SmSc->ObjectsPtrs[SmSc->LightsPtrs[LC]->ObjectIndex]->GlobalMatrix; AInB *= InvO ; Position = AInB.T ; Direction= AInB.K ; DI->AddALight(SmSc->LightsPtrs[LC],&Position,&Direction); } } } } for (int SubLvl = 0 ; SubLvl < pCurrentMat->NumberOfLayers; SubLvl++) { u32 MediaIndex,OGLIndex; if (( pCurrentMat->Layers[SubLvl].RenderState.SKIPLAYER & MaterialAnd.RenderState.SKIPLAYER) | MaterialOr.RenderState.SKIPLAYER) continue; MulColor = COL_MulColor(CurrentColor,pCurrentMat->Layers[SubLvl].ColorMultiplier); DI->SetCurrentColor(MulColor); OGLIndex = -1; MediaIndex = pCurrentMat->Layers[SubLvl].TextureMediaIndex; if (MediaIndex != -1) { MediaIndex = MediaDico.mpst_Dico[pCurrentMat->Layers[SubLvl].TextureMediaIndex].AssociatedValue; if (MediaIndex != -1 && ID_MEDIA[MediaIndex]) { if (ID_MEDIA[MediaIndex]->ulMediaRedirectValue != -1) { MediaIndex = ID_MEDIA[MediaIndex]->ulMediaRedirectValue; } if (*PickReportCurrent.PickingClass) { strcpy((char*)PickReportCurrent.CollidedMediaName,(char*)ID_MEDIA[MediaIndex]->MediaName); strcpy((char*)PickReportCurrent.CollidedMediaNickname,(char*)ID_MEDIA[MediaIndex]->Nickname); } OGLIndex = ID_MEDIA[MediaIndex]->ulAssociatedTextureIndex; } } RS RSToUse; RS *RSToUsePtr; RSToUse = pCurrentMat->Layers[SubLvl].RenderState; if (ulForceWireFrame) { RSToUse.WIRED = 1; DI->SetCurrentColor(0xff000000); } if (invertBackface) RSToUse.BACKFACE_INVERT = !RSToUse.BACKFACE_INVERT; DI->SetRS(&RSToUse,OGLIndex); /* if (ulForceWireFrame) { RS WiredRS; WiredRS = pCurrentMat->Layers[SubLvl].RenderState; WiredRS.WIRED = 1; DI->SetRS(&WiredRS,OGLIndex); } else DI->SetRS(&pCurrentMat->Layers[SubLvl].RenderState,OGLIndex); */ PickReportCurrent.PickFrozed += 1^RSToUse.PICKABLE; if (*PickReportCurrent.PickingClass) { strcpy((char*)PickReportCurrent.CollidedSmallSceneGameObjectName,(char*)(*pObj)->pObjectName); PickReportCurrent.CurrentGlobalMatrix = (*pObj)->GlobalMatrix; PickReportCurrent.CollidedSmallSceneMaterialIndex = MaterialID; if(SmSc->MaterialNameDico.GetName(&pCurrentMat->MaterialNameID,PickReportCurrent.CollidedSmallMaterialName)) PickReportCurrent.CollidedSmallMaterialName[0] = 0; } if (DrawMode == 2) { DI->SetCurrentColor(0xff000000); } if (DrawMode == 1) DI->ReverseRenderMesh(RenderMesh,OGLIndex,pCompressed[0]/* Num */,Base/* Base */); else { DI->RenderMesh(RenderMesh,pCompressed[0]/* Num */,Base/* Base */); } DI->SetCurrentColor(CurrentColor); PickReportCurrent.PickFrozed -= 1^RSToUse.PICKABLE; if (DrawMode == 2) { break; } } DI->ClearLight(); Base += pCompressed[0]; pCompressed+=2; /* RS LineRS; Vector A,B; GLOB_SetDefaultRS(&LineRS); DI->SetRS(&LineRS,-1); for (int SubLvl = 0 ; SubLvl < RenderMesh->NumberOfPoints ; SubLvl++) { A = *(RenderMesh->Points + SubLvl); B = *(RenderMesh->PointsN + SubLvl) * 0.1; B += A; DI->DrawLine(0xff,&A,&B); }*/ } /* Morphing Restore */ RenderMesh->Points = OriginalPoints; RenderMesh->PointsUV = OriginalPointsUV; RenderMesh->PointsN = OriginalPointsN; } /* DEBUG DRAW OBJECTS */ if(bShowSceneInfo) { ComputeSmallSceneBV(SmSc); pObj = SmSc->ObjectsPtrs; for ( int i = 0 ; i < SmSc->ulNumberOfObjects ; i++ , pObj++) { u32 Father,Current; RS LineRS; Vector A,B; Father = (*pObj)->FatherIndex; // DRAW OBJECT BV if (((*pObj)->BVMin.SqrNorm() != 0 || (*pObj)->BVMax.SqrNorm()) && (*pObj)->MeshIndex != -1) { MATRIX WM; Vector Center = ((*pObj)->BVMin + (*pObj)->BVMax)*0.5; Vector MidLen = ((*pObj)->BVMax - (*pObj)->BVMin)*0.5; WM = (*pObj)->GlobalMatrix; WM.T += (*pObj)->GlobalMatrix.I * Center.x; WM.T += (*pObj)->GlobalMatrix.J * Center.y; WM.T += (*pObj)->GlobalMatrix.K * Center.z; WM *= MatrixToSet; GLOB_SetDefaultRS(&LineRS); DI->Matrix(&WM); if (SmSc->HoloGraphicWindowWidth) DI->Holographic(&SmSc->HoloGraphicVector,SmSc->HoloGraphicWindowWidth); else DI->Perspective(Current_focale); LineRS.NOZTEST = 1; DI->SetRS(&LineRS,-1); for (u32 bvIdx=0; bvIdx<8; bvIdx++) { for (u32 bvIdxIn=bvIdx+1; bvIdxIn<8; bvIdxIn++) { if (GetBitNumber(bvIdxIn ^ bvIdx) == 1) { A = Vector( bvIdx & 1 ? MidLen.x : -MidLen.x, bvIdx & 2 ? MidLen.y : -MidLen.y, bvIdx & 4 ? MidLen.z : -MidLen.z); B = Vector( bvIdxIn & 1 ? MidLen.x : -MidLen.x, bvIdxIn & 2 ? MidLen.y : -MidLen.y, bvIdxIn & 4 ? MidLen.z : -MidLen.z); DI->DrawLine(0xff00ff,&A,&B); } } } } MATRIX WM; WM = (*pObj)->GlobalMatrix; WM.T += (*pObj)->GlobalMatrix.I * (*pObj)->Pivot.x; WM.T += (*pObj)->GlobalMatrix.J * (*pObj)->Pivot.y; WM.T += (*pObj)->GlobalMatrix.K * (*pObj)->Pivot.z; WM *= MatrixToSet; GLOB_SetDefaultRS(&LineRS); DI->Matrix(&WM); if (SmSc->HoloGraphicWindowWidth) DI->Holographic(&SmSc->HoloGraphicVector,SmSc->HoloGraphicWindowWidth); else DI->Perspective(Current_focale); LineRS.NOZTEST = 1; DI->SetRS(&LineRS,-1); Father = (*pObj)->FatherIndex; if ((Father != -1) && (Father > 1)) { MATRIX WM2,WMI; WM2 = SmSc->ObjectsPtrs[Father]->GlobalMatrix; WM2.T += SmSc->ObjectsPtrs[Father]->GlobalMatrix.I * SmSc->ObjectsPtrs[Father]->Pivot.x; WM2.T += SmSc->ObjectsPtrs[Father]->GlobalMatrix.J * SmSc->ObjectsPtrs[Father]->Pivot.y; WM2.T += SmSc->ObjectsPtrs[Father]->GlobalMatrix.K * SmSc->ObjectsPtrs[Father]->Pivot.z; WM2 *= MatrixToSet; WM.Inverse(WMI); WM2 *= WMI; B = WM2.T; Vector Ap,Bp,Cp; if ((B - A).Norm() > 0.001f) { Cp = (B - A)*(0.02f / (B - A).Norm()); Ap = A + Cp; Bp = B - Cp; DI->DrawLine(0xffffff,&Ap,&Bp); } } if (((*pObj)->MeshIndex != -1)) { Mesh *RenderMesh; RenderMesh = SmSc->MeshesPtrs[(*pObj)->MeshIndex]; if (RenderMesh->ulNumberOfSkins) { for (int U = 0 ; U < RenderMesh->ulNumberOfSkins ; U ++) { MATRIX Flashed; MATRIX WMI; RenderMesh->MeshSkin[U].Flash.Inverse(WMI); Flashed = WMI; Flashed *= (*pObj)->GlobalMatrix ; WM.Inverse(WMI); Flashed *= MatrixToSet; Flashed *= WMI; A = Flashed.T; B = Flashed.T + Flashed.I * 0.05f; DI->DrawLine(0xff,&A,&B); B = Flashed.T + Flashed.J * 0.05f; DI->DrawLine(0xff00,&A,&B); B = Flashed.T + Flashed.K * 0.05f; DI->DrawLine(0xff0000,&A,&B); } } } A = Vector(0,0,0); B = Vector(WM.T.z * 0.02f,0,0); DI->DrawLine(0xff,&A,&B); B = Vector(0,WM.T.z * 0.02f,0); DI->DrawLine(0xff00,&A,&B); B = Vector(0,0,WM.T.z * 0.02f); DI->DrawLine(0xff0000,&A,&B); Vector Center,Center2D; Center = WM.T;// * (*pObj)->GlobalMatrix.T; if (Center.z > 0.0f || Current_focale < 0) { char TEXT[2048]; if (Current_focale > 0) { Center2D.x = 0.5f * XSize + 0.5f * XSize * Center.x * Current_focale / Center.z; Center2D.y = 0.5f * YSize + ( (float)XSize / (float)YSize ) * 0.5f * YSize * Center.y * Current_focale / Center.z; } else { Center2D.x = 0.5f * XSize - XSize * Center.x / Current_focale; Center2D.y = 0.5f * YSize - ( (float)XSize / (float)YSize ) * YSize * Center.y / Current_focale; } if ((*pObj)->pObjectName && *(*pObj)->pObjectName) sprintf(TEXT,"%s",(*pObj)->pObjectName); else sprintf(TEXT,"%d",i); if (!(*pObj)->Flags.HIDEN) DI->DrawText((unsigned char *)TEXT,Center2D.x, Center2D.y, 1.0f, 1.0f, 0xffff0000);//*/ } } if (SmSc->HoloGraphicWindowWidth) DI->Holographic(&SmSc->HoloGraphicVector,SmSc->HoloGraphicWindowWidth); else DI->Perspective(Current_focale); DrawSmallSceneIK(SmSc); } /* restore material redirection */ for (u32 Redir = 0;Redir < SmSc->ulNumberOfMaterials ; Redir++) SmSc->MaterialsRedirs[Redir] = Redir; /* Restore Camera*/ // SmSc->CameraPosition = SmSc->CameraPosition_Save; PickReportCurrent.CollidedSmallSceneGameObjectName[0] = 0; PickReportCurrent.CollidedSmallSceneName[0] = 0; PickReportCurrent.CollidedMediaName[0] = 0; PickReportCurrent.CollidedMediaNickname[0] = 0; PickReportCurrent.CollidedSmallMaterialName[0] = 0; return true; } void WORLD::RestoreAllSmallScene(BOOL onlyIK) { SmallScene *SmSc,**pSmSc,**pSmScLast; pSmSc = pSmallScenes; /* restore eventual previous IK */ for (pSmScLast = pSmSc + MAX_SmallSCenes; pSmSc < pSmScLast; pSmSc++) { SmSc = *pSmSc; if (!SmSc) continue; if (onlyIK && !SmSc->IK) continue; if (SmSc->NoAutoReinit) continue; for (u32 Rstr = 0;Rstr < SmSc->ulNumberOfObjects; Rstr++) { SmSc->ObjectsPtrs[Rstr]->LocalMatrix = SmSc->ObjectsPtrs[Rstr]->OriginalLocalMatrix; SmSc->ObjectsPtrs[Rstr]->GlobalMatrix = SmSc->ObjectsPtrs[Rstr]->OriginalGlobalMatrix; } } } void WORLD::RenderTriangle(SmallScene *SmSc, int MediaIndex, Vector *A, Vector *B, Vector *C, Vector *UV1, Vector *UV2, Vector *UV3, int BlendMode) { RS LocalRS; GLOB_SetDefaultRS(&LocalRS); LocalRS.BlendingMode = BlendMode; LocalRS.BACKFACE = 1; if (SmSc) { float Current_focale; if (SmSc->fFocalToUseForNextRender == 0) Current_focale = GetCurrentFocale(); else Current_focale = SmSc->fFocalToUseForNextRender; if (SmSc->HoloGraphicWindowWidth) DI->Holographic(&SmSc->HoloGraphicVector,SmSc->HoloGraphicWindowWidth); else DI->Perspective(Current_focale); MATRIX CP, WM, MatrixToSet; CP = SmSc->CameraPosition; CP.K *= -1.0f; CP.Inverse(MatrixToSet); WM = SmSc->RootMatrix; WM *= MatrixToSet; DI->Matrix(&WM); } else { DI->Process2DProjection(); DI->Process2DRotation(1); DI->Process2DRotation(0, A->x, B->x, A->y, B->y); LocalRS.NOZWRITE = 1; LocalRS.NOZTEST = 1; } DI->SetRS(&LocalRS, ID_MEDIA[MediaIndex]->ulAssociatedTextureIndex); Mesh TriangleMesh; Vector PointTab[3]; Vector UVTab[3]; FaceIndex FaceIdx; PointTab[0] = *A; PointTab[1] = *B; PointTab[2] = *C; TriangleMesh.NumberOfPoints = 3; TriangleMesh.Points = PointTab; UVTab[0] = *UV1; UVTab[1] = *UV2; UVTab[2] = *UV3; TriangleMesh.PointsUV = UVTab; TriangleMesh.NumberOfPointsUV = 3; FaceIdx.I[0] = 0; FaceIdx.I[1] = 1; FaceIdx.I[2] = 2; TriangleMesh.NumberOfFaces = 1; TriangleMesh.Indexes = &FaceIdx; TriangleMesh.Indexes_UV = &FaceIdx; DI->RenderMesh(&TriangleMesh); } u32 GetObjectIndex(SmallScene *Smsc, char *ObjectName) { UnicID ObjectREF; char ObjectNameOBJ[2048]; ObjectREF = Smsc->ObjectNameDico.IsExist(ObjectName); if (ObjectREF == -1) { sprintf(ObjectNameOBJ,"%s.OBJ",ObjectName); ObjectREF = Smsc->ObjectNameDico.IsExist(ObjectNameOBJ); } if (ObjectREF == -1) return -1; ObjectREF = Smsc->ObjectNameDico.mpst_Dico[ObjectREF].AssociatedValue; return ObjectREF; } int WORLD::AffectObjectToVertex(SmallScene *Smsc, int index, char *ObjectNameSrc, char *ObjectNameDst, bool force) { UnicID ObjectREFSrc; UnicID ObjectREFDst; Vector *currentPt; Vector PosSrc; Vector PosDst; Vector Diff; float DiffNorm; Mesh *MeshDst; if (index >= MAX_LINKS) return 0; if (Smsc->pLink[index].done && !force) return 1; ComputeSmallSceneHierarchie(Smsc); ObjectREFSrc = GetObjectIndex(Smsc, ObjectNameSrc); ObjectREFDst = GetObjectIndex(Smsc, ObjectNameDst); if (ObjectREFSrc == -1 || ObjectREFDst == -1) return 0; if (Smsc->ObjectsPtrs[ObjectREFDst]->MeshIndex == -1) return 0; PosSrc = Smsc->ObjectsPtrs[ObjectREFSrc]->OriginalGlobalMatrix.T; PosDst = Smsc->ObjectsPtrs[ObjectREFDst]->OriginalGlobalMatrix.T; MeshDst = Smsc->MeshesPtrs[Smsc->ObjectsPtrs[ObjectREFDst]->MeshIndex]; currentPt = MeshDst->Points; float MinDst = 0.001f; int MinIdx = -1; for (int meshPtIdx=0; meshPtIdx < MeshDst->NumberOfPoints; meshPtIdx++, currentPt++) { Diff = Smsc->ObjectsPtrs[ObjectREFDst]->OriginalGlobalMatrix**currentPt - PosSrc; //+ PosDst - PosSrc; Diff.Clean(); DiffNorm = Diff.Norm(); if (DiffNorm < MinDst) { MinDst = DiffNorm; MinIdx = meshPtIdx; } } if (MinIdx != -1) { Smsc->pLink[index].ObjectIndex = ObjectREFSrc; Smsc->pLink[index].MeshIndex = Smsc->ObjectsPtrs[ObjectREFDst]->MeshIndex; Smsc->pLink[index].MeshPointIndex = MinIdx; Smsc->pLink[index].done = 1; if (index >= Smsc->ulNumberOfLinks) Smsc->ulNumberOfLinks = index + 1; return 1; } return 0; } int WORLD::ObjectLinkSnap(SmallScene *Smsc, char *DummySnapSrc, char *DummySnapDst) { UnicID DummySnapREFSrc; UnicID DummySnapREFDst; DummySnapREFSrc = GetObjectIndex(Smsc, DummySnapSrc); DummySnapREFDst = GetObjectIndex(Smsc, DummySnapDst); if (DummySnapREFSrc == -1 || DummySnapREFDst == -1) return 0; ComputeSmallSceneHierarchie(Smsc); Smsc->ObjectsPtrs[DummySnapREFSrc]->GlobalMatrix.T = Smsc->ObjectsPtrs[DummySnapREFDst]->GlobalMatrix.T; ComputeSmallSceneHierarchie_Local(Smsc, DummySnapREFSrc); return 1; } int WORLD::ObjectLinkScale(SmallScene *Smsc, char *DummySnapSrc1, char *DummySrc2, char *DummySnapDst1, char *DummyDst2, int axe, u32 mode) { UnicID DummySnapREFSrc1,DummyREFSrc2; UnicID DummySnapREFDst1,DummyREFDst2; Vector DummySrcVect; Vector DummyDstVect; float scaleFactor[4]; MATRIX SrcMatrix; MATRIX DstMatrix; ComputeSmallSceneHierarchie(Smsc); DummySnapREFSrc1= GetObjectIndex(Smsc, DummySnapSrc1); DummyREFSrc2 = GetObjectIndex(Smsc, DummySrc2); DummySnapREFDst1= GetObjectIndex(Smsc, DummySnapDst1); DummyREFDst2 = GetObjectIndex(Smsc, DummyDst2); if (DummySnapREFSrc1 == -1 || DummyREFSrc2 == -1 || DummySnapREFDst1 == -1 || DummyREFDst2 == -1) return 0; SrcMatrix = Smsc->ObjectsPtrs[DummySnapREFSrc1]->GlobalMatrix; SrcMatrix.I.Normalize(); SrcMatrix.J.Normalize(); SrcMatrix.K.Normalize(); DstMatrix = Smsc->ObjectsPtrs[DummySnapREFDst1]->GlobalMatrix; DstMatrix.I.Normalize(); DstMatrix.J.Normalize(); DstMatrix.K.Normalize(); DummyDstVect = Smsc->ObjectsPtrs[DummyREFDst2]->GlobalMatrix.T - Smsc->ObjectsPtrs[DummySnapREFDst1]->GlobalMatrix.T; DummySrcVect = Smsc->ObjectsPtrs[DummyREFSrc2]->GlobalMatrix.T - Smsc->ObjectsPtrs[DummySnapREFSrc1]->GlobalMatrix.T; memset(scaleFactor, 0, sizeof(scaleFactor)); if ((axe & 1) && (SrcMatrix.I * DummySrcVect) != 0) { //scaleFactor[0] = (DstMatrix.I * DummyDstVect) / (SrcMatrix.I * DummySrcVect); scaleFactor[0] = (SrcMatrix.I * DummyDstVect) / (SrcMatrix.I * DummySrcVect); } if ((axe & 2) && (SrcMatrix.J * DummySrcVect) != 0) { //scaleFactor[1] = (DstMatrix.J * DummyDstVect) / (SrcMatrix.J * DummySrcVect); scaleFactor[1] = (SrcMatrix.J * DummyDstVect) / (SrcMatrix.J * DummySrcVect); } if ((axe & 4) && (SrcMatrix.K * DummySrcVect) != 0) { //scaleFactor[2] = (DstMatrix.K * DummyDstVect) / (SrcMatrix.K * DummySrcVect); scaleFactor[2] = (SrcMatrix.K * DummyDstVect) / (SrcMatrix.K * DummySrcVect); } // calc scales ... float scaleSum = 0; int scaleNbr = 0; for (int i=0; i<3; i++) { if (scaleFactor[i] != 0) { scaleSum += scaleFactor[i]; scaleNbr ++; } } if (scaleNbr == 0) return 0; scaleSum /= scaleNbr; if (mode == 0) mode = axe; if (mode & 1) { if (scaleFactor[0] != 0) Smsc->ObjectsPtrs[DummySnapREFSrc1]->GlobalMatrix.I = SrcMatrix.I*scaleFactor[0]; else Smsc->ObjectsPtrs[DummySnapREFSrc1]->GlobalMatrix.I = SrcMatrix.I*scaleSum; } if (mode & 2) { if (scaleFactor[1] != 0) Smsc->ObjectsPtrs[DummySnapREFSrc1]->GlobalMatrix.J = SrcMatrix.J*scaleFactor[1]; else Smsc->ObjectsPtrs[DummySnapREFSrc1]->GlobalMatrix.J = SrcMatrix.J*scaleSum; } if (mode & 4) { if (scaleFactor[2] != 0) Smsc->ObjectsPtrs[DummySnapREFSrc1]->GlobalMatrix.K = SrcMatrix.K*scaleFactor[2]; else Smsc->ObjectsPtrs[DummySnapREFSrc1]->GlobalMatrix.K = SrcMatrix.K*scaleSum; } Smsc->ObjectsPtrs[DummySnapREFSrc1]->GlobalMatrix.T = Smsc->ObjectsPtrs[DummySnapREFDst1]->GlobalMatrix.T; ComputeSmallSceneHierarchie_Local(Smsc, DummySnapREFSrc1); return 1; } Vector WORLD::GetScaleVector(MATRIX *SrcMatrix, Vector *SrcDummy, MATRIX *DstMatrix, Vector *DstDummy, int axe, u32 mode) { float scaleFactor[3]; Vector DummySrcVect; Vector DummyDstVect; SrcMatrix->I.Normalize(); SrcMatrix->J.Normalize(); SrcMatrix->K.Normalize(); DstMatrix->I.Normalize(); DstMatrix->J.Normalize(); DstMatrix->K.Normalize(); DummyDstVect = *DstDummy - DstMatrix->T; DummySrcVect = *SrcDummy - SrcMatrix->T; memset(scaleFactor, 0, sizeof(scaleFactor)); if ((axe & 1) && (SrcMatrix->I * DummySrcVect) != 0) scaleFactor[0] = (SrcMatrix->I * DummyDstVect) / (SrcMatrix->I * DummySrcVect); if ((axe & 2) && (SrcMatrix->J * DummySrcVect) != 0) scaleFactor[1] = (SrcMatrix->J * DummyDstVect) / (SrcMatrix->J * DummySrcVect); if ((axe & 4) && (SrcMatrix->K * DummySrcVect) != 0) scaleFactor[2] = (SrcMatrix->K * DummyDstVect) / (SrcMatrix->K * DummySrcVect); // calc scales ... float scaleSum = 0; int scaleNbr = 0; for (int i=0; i<3; i++) { if (scaleFactor[i] != 0) { scaleSum += scaleFactor[i]; scaleNbr ++; } } if (scaleNbr == 0) return Vector(0,0,0); scaleSum /= scaleNbr; if (mode == 0) mode = axe; if ((mode & 1) && scaleFactor[0] == 0) scaleFactor[0] = scaleSum; if ((mode & 2) && scaleFactor[1] == 0) scaleFactor[1] = scaleSum; if ((mode & 4) && scaleFactor[2] == 0) scaleFactor[2] = scaleSum; return Vector(scaleFactor[0], scaleFactor[1], scaleFactor[2]); } Vector WORLD::ScreenPointToScene(SmallScene *Smsc, Vector ScreenPoint) { Vector PointV; PointV.x = ScreenPoint.x - XSize/2.0f; PointV.y = (YSize - ScreenPoint.y) - YSize/2.0f; PointV.z = ScreenPoint.z; PointV.x *= 1.0f / XSize ; PointV.y *= 1.0f / XSize ; if (Smsc->fFocalToUseForNextRender < 0.0f) { /* Ortho mode */ PointV.x *= -Smsc->fFocalToUseForNextRender; PointV.y *= -Smsc->fFocalToUseForNextRender; } else { float FocaleToUse; if (Smsc->fFocalToUseForNextRender == 0) FocaleToUse = GetCurrentFocale(); else FocaleToUse = Smsc->fFocalToUseForNextRender; /* Perspectiv mode */ PointV.x *= -2.0f * ScreenPoint.z / FocaleToUse; PointV.y *= -2.0f * ScreenPoint.z / FocaleToUse; } return Smsc->CameraPosition * PointV ; } Vector WORLD::ScenePointToScreen(SmallScene *Smsc, Vector ScenePoint) { Vector PointV; MATRIX CameraInv; float focale = GetCurrentFocale(); Smsc->CameraPosition.Inverse(CameraInv); ScenePoint = CameraInv*ScenePoint; ScenePoint.z = -ScenePoint.z; if (Smsc->fFocalToUseForNextRender != 0) SetCurrentFocale(Smsc->fFocalToUseForNextRender); PointV = Project_2_Screen(ScenePoint, &FrameBufferResult); if (Smsc->fFocalToUseForNextRender != 0) SetCurrentFocale(focale); return PointV; } //**************************************************** //** Scene State save //**************************************************** //*** Actual State saved : typedef struct _StateSaveElmt { MATRIX LocalMatrix; OBJECT_FLAGS Flags; s32 DrawOrder; // } StateSaveElmt; typedef struct _StateSave { StateSaveElmt * list; s32 nbElmt; } StateSave; void WORLD::SmallScene_ObjectStateSave(SmallScene *Smsc, u32 ObjectIndex, int index, DWORD stateMask) { StateSave *pState; StateSaveElmt *pStateElmt; _3D_Object **pObj; u32 nbElemts; if (ObjectIndex == -1) ObjectIndex = 0; Smsc->ObjectsPtrs[ObjectIndex]->Flags.UPDATE = 1; nbElemts = 1; pObj = Smsc->ObjectsPtrs; for ( int i = 0 ; i < Smsc->ulNumberOfObjects ; i++ , pObj++) { u32 Father = (*pObj)->FatherIndex; if ((Father != -1) && Smsc->ObjectsPtrs[Father]->Flags.UPDATE) { (*pObj)->Flags.UPDATE = Smsc->ObjectsPtrs[Father]->Flags.UPDATE; nbElemts++; } } pObj = Smsc->ObjectsPtrs; for ( int i = 0 ; i < Smsc->ulNumberOfObjects ; i++ , pObj++) (*pObj)->Flags.UPDATE = 0; if (!Smsc->StateTable[index]) { Smsc->StateTable[index] = (StateSave *)CC_malloc(sizeof(StateSave)); memset(Smsc->StateTable[index], 0, sizeof(StateSave)); ((StateSave *)Smsc->StateTable[index])->list = (StateSaveElmt *)CC_malloc(sizeof(StateSaveElmt)*nbElemts); ((StateSave *)Smsc->StateTable[index])->nbElmt = nbElemts; } pState = (StateSave *)Smsc->StateTable[index]; if (pState->nbElmt != nbElemts) { pState->list = (StateSaveElmt *)CC_realloc(pState->list, sizeof(StateSaveElmt)*nbElemts); pState->nbElmt = nbElemts; } pObj = Smsc->ObjectsPtrs; pStateElmt = pState->list; for (int i=0; iulNumberOfObjects; i++, pObj++) { u32 Father = (*pObj)->FatherIndex; if ((i == ObjectIndex) || ((Father != -1) && Smsc->ObjectsPtrs[Father]->Flags.UPDATE)) { (*pObj)->Flags.UPDATE = 1; if (stateMask & 1) // Flags pStateElmt->Flags.HIDEN = (*pObj)->Flags.HIDEN; if (stateMask & 2) // LocalMatrix pStateElmt->LocalMatrix = (*pObj)->LocalMatrix; if (stateMask & 4) // DrawOrder pStateElmt->DrawOrder = (*pObj)->DrawOrder; pStateElmt++; } } pObj = Smsc->ObjectsPtrs; for ( int i = 0 ; i < Smsc->ulNumberOfObjects ; i++ , pObj++) (*pObj)->Flags.UPDATE = 0; } s32 WORLD::SmallScene_ObjectStateRestore(SmallScene *Smsc, u32 ObjectIndex, int index, DWORD stateMask) { StateSave *pState; StateSaveElmt *pStateElmt; _3D_Object **pObj; u32 nbElemts; if (!Smsc->StateTable[index]) return 0; if (ObjectIndex == -1) ObjectIndex = 0; Smsc->ObjectsPtrs[ObjectIndex]->Flags.UPDATE = 1; nbElemts = 1; pObj = Smsc->ObjectsPtrs; for ( int i = 0 ; i < Smsc->ulNumberOfObjects ; i++ , pObj++) { u32 Father = (*pObj)->FatherIndex; if ((Father != -1) && Smsc->ObjectsPtrs[Father]->Flags.UPDATE) { (*pObj)->Flags.UPDATE = Smsc->ObjectsPtrs[Father]->Flags.UPDATE; nbElemts++; } } pObj = Smsc->ObjectsPtrs; for ( int i = 0 ; i < Smsc->ulNumberOfObjects ; i++ , pObj++) (*pObj)->Flags.UPDATE = 0; pState = (StateSave *)Smsc->StateTable[index]; if (pState->nbElmt != nbElemts) return 0; pObj = Smsc->ObjectsPtrs; pStateElmt = pState->list; for (int i=0; iulNumberOfObjects; i++, pObj++) { u32 Father = (*pObj)->FatherIndex; if ((i == ObjectIndex) || (Father != -1) && Smsc->ObjectsPtrs[Father]->Flags.UPDATE) { (*pObj)->Flags.UPDATE = 1; if (stateMask & 1) // Flags (*pObj)->Flags.HIDEN = pStateElmt->Flags.HIDEN; if (stateMask & 2) // LocalMatrix (*pObj)->LocalMatrix = pStateElmt->LocalMatrix; if (stateMask & 4) // DrawOrder (*pObj)->DrawOrder = pStateElmt->DrawOrder; pStateElmt++; } } pObj = Smsc->ObjectsPtrs; for ( int i = 0 ; i < Smsc->ulNumberOfObjects ; i++ , pObj++) (*pObj)->Flags.UPDATE = 0; return 0; } void WORLD::SmallScene_ObjectStateFree(SmallScene *Smsc, int index) { StateSave *pState; if (Smsc->StateTable[index]) { if (((StateSave *)Smsc->StateTable[index])->list) CC_free(((StateSave *)Smsc->StateTable[index])->list); CC_free(Smsc->StateTable[index]); Smsc->StateTable[index] = NULL; } } ///***************************************************************************** ///***************************************************************************** ///***************************************************************************** /* Define to use byte-size values for joystick axes, else dword size */ #undef UCHAR_AXES #define PPJOY_AXIS_MIN 1 #ifdef UCHAR_AXES #define PPJOY_AXIS_MAX 127 #else #define PPJOY_AXIS_MAX 32767 #endif #define FILE_DEVICE_PPORTJOY FILE_DEVICE_UNKNOWN #define PPORTJOY_IOCTL(_index_) \ CTL_CODE (FILE_DEVICE_PPORTJOY, _index_, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_PPORTJOY_SET_STATE PPORTJOY_IOCTL (0x0) #define JOYSTICK_STATE_V1 0x53544143 typedef struct { ULONG Version; UCHAR Data[1]; } JOYSTICK_SET_STATE, *PJOYSTICK_SET_STATE; #define NUM_ANALOG 8 /* Number of analog values which we will provide */ #define NUM_DIGITAL 16 /* Number of digital values which we will provide */ #pragma pack(push,1) /* All fields in structure must be byte aligned. */ typedef struct { unsigned long Signature; /* Signature to identify packet to PPJoy IOCTL */ char NumAnalog; /* Num of analog values we pass */ long Analog[NUM_ANALOG]; /* Analog values */ char NumDigital; /* Num of digital values we pass */ char Digital[NUM_DIGITAL]; /* Digital values */ } JOYSTICK_STATE; #pragma pack(pop) void HandlePad(int SmoothNumber, int Affect, MATRIX *pTrckMatrix, float maxAngle, char *error) { HANDLE h; JOYSTICK_STATE JoyState; long *Analog; char *Digital; char *DevName; DWORD RetSize; DWORD rc; long AMPLITUD = ((PPJOY_AXIS_MIN+PPJOY_AXIS_MAX)/2); DevName= "\\\\.\\PPJoyIOCTL1"; h= CreateFile(DevName,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL); *error = 0; if (h==INVALID_HANDLE_VALUE) { sprintf (error, "CreateFile failed with error code %d trying to open %s device\n",GetLastError(),DevName); return; } JoyState.Signature = JOYSTICK_STATE_V1; JoyState.NumAnalog = NUM_ANALOG; /* Number of analog values */ Analog = JoyState.Analog; /* Keep a pointer to the analog array for easy updating */ JoyState.NumDigital = NUM_DIGITAL; /* Number of digital values */ Digital = JoyState.Digital; /* Digital array */ memset(Digital, 0, NUM_DIGITAL); for (int i=0; iT.x > 0; Digital[1] = pTrckMatrix->T.x < 0; Digital[2] = pTrckMatrix->T.y > 0; Digital[3] = pTrckMatrix->T.y < 0; Digital[4] = pTrckMatrix->T.z > 0; Digital[5] = pTrckMatrix->T.z < 0; } if (Affect & 2) { MATRIX TMatrix; Vector eulerVect; TMatrix = *pTrckMatrix; if (SmoothNumber) FactorSmoothMatrix(SmoothNumber, &TMatrix, 0); TMatrix.ToEuler(eulerVect); eulerVect *= 45 / atan(1.0); Analog[6] += eulerVect.x * AMPLITUD / maxAngle; Analog[7] += eulerVect.y * AMPLITUD / maxAngle; Analog[3] += eulerVect.z * AMPLITUD / maxAngle; for (int i=0; i<=2; i++) { if (Analog[i] < PPJOY_AXIS_MIN) Analog[i] = PPJOY_AXIS_MIN; if (Analog[i] > PPJOY_AXIS_MAX) Analog[i] = PPJOY_AXIS_MAX; } } if (!DeviceIoControl(h,IOCTL_PPORTJOY_SET_STATE,&JoyState,sizeof(JoyState),NULL,0,&RetSize,NULL)) { rc = GetLastError(); if (rc == 2) { sprintf (error, "Underlying joystick device deleted. Exiting read loop\n"); } else sprintf (error, "DeviceIoControl error %d\n",rc); } CloseHandle(h); } int faceIndexFromUV(Mesh* mesh, float U, float V) { for(int i=0; iNumberOfFaces; i++) { Vector *p0; Vector *p1; Vector *p2; p0 = (mesh->PointsUV + (mesh->Indexes_UV+i)->I[0]); p1 = (mesh->PointsUV + (mesh->Indexes_UV+i)->I[1]); p2 = (mesh->PointsUV + (mesh->Indexes_UV+i)->I[2]); Vector uv(U, V, 0); if((uv.isRightXY(*p0, *p1) && uv.isRightXY(*p1, *p2) && uv.isRightXY(*p2, *p0)) ||(!uv.isRightXY(*p0, *p1) && !uv.isRightXY(*p1, *p2) && !uv.isRightXY(*p2, *p0))) { return i; } } return -1; } u32 WORLD::GetSmScSize(SmallScene *Ret) { UNIC_Dico Dico; Dico.Init(); u32 ReturnV = 0; for (int i = 0 ; i < Ret->ulNumberOfObjects ; i++ ) {ReturnV += sizeof(_3D_Object);ReturnV += strlen((char*)Ret->ObjectsPtrs[i]->pObjectName);}; ReturnV += Ret->ulNumberOfObjects * 4 ; for (int i = 0 ; i < Ret->ulNumberOfMaterials; i++ ) ReturnV += sizeof(_3D_Material); ReturnV += Ret->ulNumberOfMaterials * 4 ; for (int i = 0 ; i < Ret->ulNumberOfMultiMats; i++ ) ReturnV += sizeof(_3D_MultiMaterial); ReturnV += Ret->ulNumberOfMultiMats * 4 ; for (int i = 0 ; i < Ret->ulNumberOfLights; i++ ) ReturnV += sizeof(_3D_Light); ReturnV += Ret->ulNumberOfLights * 4 ; for (int i = 0 ; i < Ret->ulNumberOfMeshes; i++ ) ReturnV += SizeMesh(Ret->MeshesPtrs[i],&Dico); ReturnV += Ret->ulNumberOfMeshes * 4 ; for (int index = 0 ; index < MAX_STATES; index++ ) { if (Ret->StateTable[index]) { ReturnV += sizeof(StateSave); if (((StateSave *)Ret->StateTable[index])->list) ReturnV += sizeof(StateSaveElmt) * ((StateSave *)Ret->StateTable[index])->nbElmt; } } ReturnV += MAX_STATES * 4 ; ReturnV += sizeof(*Ret); Dico.Destroy(); return ReturnV; }