3240 lines
No EOL
87 KiB
C++
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;
|
|
} |