JD2022-TU1/main/extern/Camcam/LIBS/Mixer/SmallScene.cpp

3240 lines
No EOL
87 KiB
C++

#include "SCENE.h"
#include "Wininet.h"
#include "xmmintrin.h"
#include <string>
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; i<MAX_ID; i++, prevMatrixPtr++, prevTranslationPtr++, prevQuatPtr++)
{
if (*prevMatrixPtr)
{
CC_free(*prevMatrixPtr);
*prevMatrixPtr = NULL;
}
if (*prevTranslationPtr)
{
CC_free(*prevTranslationPtr);
*prevTranslationPtr = NULL;
}
if (*prevQuatPtr)
{
CC_free(*prevQuatPtr);
*prevQuatPtr = NULL;
}
}
}
void SmoothFuncVectorAngle(int index, Vector *xyz, float *angle, float rotationSmooth) {
BOOL isNear = 1;
float ANorm;
if (rotationSmooth == 0)
rotationSmooth = DEFAULT_ROTATION_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 (prevMatrix[index] == NULL)
{
prevMatrix[index] = (QuatInfo*)CC_malloc(sizeof(QuatInfo));
prevMatrix[index]->xyz = *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; j<Ret->MaterialsPtrs[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; ObjectIndex<SmSc->ulNumberOfObjects ; 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; ObjectIndex<SmSc->ulNumberOfObjects ; 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; i<SmSc->ulNumberOfObjects; 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; linkIdx<SmSc->ulNumberOfLinks; 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; i<Smsc->ulNumberOfObjects; 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; i<Smsc->ulNumberOfObjects; 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; i<NUM_ANALOG; i++)
Analog[i] = AMPLITUD;
if (Affect & 1)
{
Digital[0] = pTrckMatrix->T.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; i<mesh->NumberOfFaces; 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;
}