1177 lines
32 KiB
C++
1177 lines
32 KiB
C++
|
|
#include "SCENE.h"
|
|
|
|
u32 COL_MulColor(u32 A,u32 B);
|
|
|
|
#define FLOAT_RAND (2*((float)rand() - RAND_MAX/2)/RAND_MAX)
|
|
#define VAL_RAND(x,y) (x*(1+y*FLOAT_RAND))
|
|
|
|
#define BARYCENTER(x,y,c,n) (((x)*((n)-(c))+(y)*(c))/(n))
|
|
|
|
#define EPSILON 0.0001
|
|
#define RATIO 32
|
|
|
|
typedef float M33[3][3];
|
|
|
|
void MuliplyM(M33 *M1, M33 *M2, M33 *M)
|
|
{
|
|
int i, j, k;
|
|
for (i=0; i<3; i++)
|
|
{
|
|
for (j=0; j<3; j++)
|
|
{
|
|
(*M)[i][j] = 0.0f;
|
|
for (k=0; k<3; k++)
|
|
{
|
|
(*M)[i][j] += (*M1)[i][k]*(*M2)[k][j];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ZeroM(M33 *M)
|
|
{
|
|
int i, j;
|
|
for (i=0; i<3; i++)
|
|
{
|
|
for (j=0; j<3; j++)
|
|
{
|
|
(*M)[i][j] = 0.0f;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CopyM(M33 *MSRC, M33 *MDST)
|
|
{
|
|
int i, j;
|
|
for (i=0; i<3; i++)
|
|
{
|
|
for (j=0; j<3; j++)
|
|
{
|
|
(*MDST)[i][j] = (*MSRC)[i][j];
|
|
}
|
|
}
|
|
}
|
|
|
|
Vector RotateVector(Vector v, float angle)
|
|
{
|
|
float angleR;
|
|
Vector resV;
|
|
M33 M;
|
|
M33 M1;
|
|
M33 M2;
|
|
|
|
angleR = angle*FLOAT_RAND;
|
|
ZeroM(&M);
|
|
M[0][0] = 1.0f;
|
|
M[1][1] = cos(angleR);
|
|
M[1][2] = -sin(angleR);
|
|
M[2][1] = -M[1][2];
|
|
M[2][2] = M[1][1];
|
|
|
|
CopyM(&M, &M2);
|
|
angleR = angle*FLOAT_RAND;
|
|
ZeroM(&M1);
|
|
M1[0][0] = cos(angleR);
|
|
M1[0][2] = -sin(angleR);
|
|
M1[1][1] = 1.0f;
|
|
M1[2][0] = -M1[0][2];
|
|
M1[2][2] = M1[0][0];
|
|
|
|
MuliplyM(&M1, &M2, &M);
|
|
|
|
CopyM(&M, &M2);
|
|
angleR = angle*FLOAT_RAND;
|
|
ZeroM(&M1);
|
|
M1[0][0] = cos(angleR);
|
|
M1[0][1] = -sin(angleR);
|
|
M1[1][0] = -M1[0][1];
|
|
M1[1][1] = M1[0][0];
|
|
M1[2][2] = 1.0f;
|
|
|
|
MuliplyM(&M1, &M2, &M);
|
|
|
|
resV.x = M[0][0]*v.x + M[0][1]*v.y + M[0][2]*v.z;
|
|
resV.y = M[1][0]*v.x + M[1][1]*v.y + M[1][2]*v.z;
|
|
resV.z = M[2][0]*v.x + M[2][1]*v.y + M[2][2]*v.z;
|
|
|
|
return resV;
|
|
}
|
|
|
|
|
|
|
|
BOOL SegmentCollision(Vector *ptSrc, Vector *ptDst, Vector *speed);
|
|
|
|
|
|
#define NB_RAND_ELMTS (2*1024) // 2* -> X,Y
|
|
|
|
static BOOL RandInit = 0;
|
|
static float RandTab[NB_RAND_ELMTS];
|
|
|
|
inline void GetPointMass(Mesh *mesh, MAP *massTexture, int faceIdx, int ptIdx, float *massR)
|
|
{
|
|
int xPos, yPos;
|
|
|
|
xPos = mesh->PointsUV[mesh->Indexes_UV[faceIdx].I[ptIdx]].x * (massTexture->SX - 1);
|
|
xPos = xPos % massTexture->SX;
|
|
yPos = mesh->PointsUV[mesh->Indexes_UV[faceIdx].I[ptIdx]].y * (massTexture->SY - 1);
|
|
yPos = yPos % massTexture->SY;
|
|
|
|
if (massR)
|
|
*massR= ((float)((massTexture->GetValue(xPos + yPos*massTexture->PITCH) >> 16) & 255))/255.0f;
|
|
}
|
|
|
|
inline float GetFaceMass(Mesh *mesh, MAP *massTexture, int faceIdx, float *massPointOut)
|
|
{
|
|
float massPt[3];
|
|
float massFace;
|
|
float *massPoint;
|
|
|
|
if (massPointOut == NULL)
|
|
{
|
|
massPoint = massPt;
|
|
for (int ptIdx=0; ptIdx<3; ptIdx++)
|
|
{
|
|
GetPointMass(mesh, massTexture, faceIdx, ptIdx, &massPoint[ptIdx]);
|
|
massPoint[ptIdx] *= 8;
|
|
}
|
|
} else {
|
|
massPoint = massPointOut;
|
|
}
|
|
|
|
// We test Here the best mass compute method
|
|
massFace = (massPoint[0]+massPoint[1]+massPoint[2])/3;
|
|
/********* LINEAR *********
|
|
return massFace;
|
|
/********* LINEAR *********/
|
|
/******** QUADRIC *********/
|
|
return massFace*massFace;
|
|
/******** QUADRIC *********/
|
|
/******* GEOMETRIC ********
|
|
return pow(massPoint[0]*massPoint[1]*massPoint[2], 1.0f/3);
|
|
/******* GEOMETRIC ********/
|
|
}
|
|
|
|
float GetMeshSurface(Mesh *mesh, MATRIX *global, float *surfaceList, MAP *massTexture)
|
|
{
|
|
u32 faceIdx, ptIdx;
|
|
FaceIndex *Indexes = mesh->Indexes;
|
|
Vector pts[3];
|
|
float surface = 0;
|
|
float face;
|
|
float ptsMass;
|
|
|
|
ptsMass = 1.0f;
|
|
for (faceIdx = 0; faceIdx<mesh->NumberOfFaces; faceIdx++, Indexes++)
|
|
{
|
|
if (global)
|
|
{
|
|
for (ptIdx=0; ptIdx<3; ptIdx++)
|
|
pts[ptIdx] = *global**(mesh->Points + Indexes->I[ptIdx]);
|
|
} else
|
|
{
|
|
for (ptIdx=0; ptIdx<3; ptIdx++)
|
|
pts[ptIdx] = *(mesh->Points + Indexes->I[ptIdx]);
|
|
}
|
|
if (massTexture)
|
|
ptsMass = GetFaceMass(mesh, massTexture, faceIdx, NULL);
|
|
|
|
face = ((pts[1] - pts[0])^(pts[2] - pts[0])).Norm()*ptsMass/2.0f;
|
|
if (surfaceList)
|
|
surfaceList[faceIdx] = face;
|
|
surface += face;
|
|
}
|
|
return surface;
|
|
}
|
|
|
|
int GetPointRepartition(Vector *points, Vector *normals, Vector *ulist, Vector *uvtList, int number, Mesh *mesh, MATRIX *global, float density, float *surfaceList, MAP *massTexture, int initFace, int initRand, u32 seed)
|
|
{
|
|
u32 faceIdx, ptIdx;
|
|
FaceIndex *Indexes;
|
|
Vector pts[3];
|
|
Vector ptsW[3];
|
|
Vector ptsU[3];
|
|
Vector ptsUV[3];
|
|
float globalSurface = 0;
|
|
float stepSurface = 0;
|
|
Vector faceNormal;
|
|
u32 currentFace = initFace;
|
|
float ptsMass[3];
|
|
Vector ptsMassUV[3];
|
|
float scaleFactor;
|
|
|
|
if (currentFace >= mesh->NumberOfFaces)
|
|
currentFace = 0;
|
|
Indexes = mesh->Indexes + currentFace;
|
|
|
|
if (!RandInit)
|
|
{
|
|
float *randTabPtr = RandTab;
|
|
|
|
if (seed != -1) srand(seed);
|
|
else srand(timeGetTime());
|
|
for (int rdIdx = 0; rdIdx<NB_RAND_ELMTS; rdIdx+=2, randTabPtr+=2)
|
|
{
|
|
*randTabPtr = ((float)rand())/RAND_MAX;
|
|
*(randTabPtr+1) = ((float)rand())/RAND_MAX;
|
|
if ((*randTabPtr + *(randTabPtr+1)) > 1.0)
|
|
{
|
|
*randTabPtr = 1.0f - *randTabPtr;
|
|
*(randTabPtr+1) = 1.0f - *(randTabPtr+1);
|
|
}
|
|
}
|
|
RandInit = 1;
|
|
}
|
|
|
|
int randPos = initRand;
|
|
int currentPoint = 0;
|
|
|
|
ptsMass[0] = ptsMass[1] = ptsMass[2] = 1.0f;
|
|
for (faceIdx = 0; faceIdx<mesh->NumberOfFaces; faceIdx++, Indexes++, currentFace++)
|
|
{
|
|
if (currentFace >= mesh->NumberOfFaces)
|
|
{
|
|
currentFace = 0;
|
|
Indexes = mesh->Indexes;
|
|
}
|
|
|
|
|
|
for (ptIdx=0; ptIdx<3; ptIdx++)
|
|
{
|
|
ptsMassUV[ptIdx] = mesh->PointsUV[mesh->Indexes_UV[faceIdx].I[ptIdx]];
|
|
}
|
|
if (massTexture)
|
|
{
|
|
for (ptIdx=0; ptIdx<3; ptIdx++)
|
|
{
|
|
GetPointMass(mesh, massTexture, faceIdx, ptIdx, &ptsMass[ptIdx]);// + 1; // !!!! +1 pour eviter les effets de bord
|
|
ptsMass[ptIdx] *= 8;
|
|
}
|
|
}
|
|
globalSurface += surfaceList[currentFace];
|
|
if (stepSurface < globalSurface)
|
|
{
|
|
for (ptIdx=0; ptIdx<3; ptIdx++)
|
|
{
|
|
pts[ptIdx] = *global**(mesh->Points + Indexes->I[ptIdx]);
|
|
ptsW[ptIdx]= pts[ptIdx]*ptsMass[ptIdx];
|
|
ptsUV[ptIdx]= ptsMassUV[ptIdx]*ptsMass[ptIdx];
|
|
}
|
|
if (ulist)
|
|
{
|
|
for (ptIdx=0; ptIdx<3; ptIdx++)
|
|
ptsU[ptIdx] = *(mesh->PointsUV + Indexes->I[ptIdx]);
|
|
}
|
|
faceNormal = (pts[1] - pts[0])^(pts[2] - pts[0]);
|
|
faceNormal.Normalize();
|
|
while (stepSurface < globalSurface)
|
|
{
|
|
scaleFactor = 1.0f/(ptsMass[0] + ((ptsMass[1]-ptsMass[0])*RandTab[randPos]) + ((ptsMass[2]-ptsMass[0])*RandTab[randPos+1]));
|
|
points[currentPoint] = ptsW[0] + ((ptsW[1]-ptsW[0])*RandTab[randPos]) + ((ptsW[2]-ptsW[0])*RandTab[randPos+1]);
|
|
points[currentPoint] *= scaleFactor;
|
|
normals[currentPoint] = faceNormal;
|
|
if (uvtList)
|
|
{
|
|
uvtList[currentPoint] = ptsUV[0] + ((ptsUV[1]-ptsUV[0])*RandTab[randPos]) + ((ptsUV[2]-ptsUV[0])*RandTab[randPos+1]);
|
|
uvtList[currentPoint] *= scaleFactor;
|
|
}
|
|
|
|
if (ulist)
|
|
{
|
|
Vector newFaceNormal = (pts[1] - pts[0])*(ptsU[1].y - ptsU[0].y) + (pts[2] - pts[0])*(ptsU[2].y - ptsU[0].y);
|
|
newFaceNormal.Normalize();
|
|
if (newFaceNormal.x != 0 || newFaceNormal.y != 0 || newFaceNormal.z != 0)
|
|
newFaceNormal.Normalize();
|
|
else
|
|
newFaceNormal = Vector(1,0,0);
|
|
ulist[currentPoint] = newFaceNormal;
|
|
}
|
|
|
|
if (randPos >= NB_RAND_ELMTS) randPos = 0;
|
|
|
|
currentPoint++;
|
|
randPos+=2;
|
|
stepSurface += density;
|
|
if (currentPoint >= number)
|
|
return currentPoint;
|
|
}
|
|
}
|
|
}
|
|
return currentPoint;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void PGENERATOR_OBJ::ProcessParticuleSon(Particules *particulePtr)
|
|
{
|
|
if (sonMode == 0) return;
|
|
|
|
if (sonMode == 1 /* On Diing */ &&
|
|
particulePtr->alive) return;
|
|
|
|
if (sonMode == 2 /* On Collide */ &&
|
|
!particulePtr->collide) return;
|
|
|
|
if (!particuleSonPtr) return;
|
|
|
|
particuleSonPtr->Origin = particulePtr->coordsDest;
|
|
particuleSonPtr->Direction = particulePtr->speedDest;
|
|
particuleSonPtr->Direction.Normalize();
|
|
|
|
particuleSonPtr->GenerateFix(1, 0);
|
|
}
|
|
|
|
|
|
BOOL PGENERATOR_OBJ::ProcessParticule(int time, Particules *particule)
|
|
{
|
|
Vector v;
|
|
int ParticuleCurLife;
|
|
Vector dstCoord;
|
|
Vector dstCoordIn;
|
|
|
|
if (!particule->alive) return false;
|
|
if (time <= 0) return true;
|
|
|
|
if (curTime < particule->creationTime)
|
|
ParticuleCurLife = 0;
|
|
else
|
|
ParticuleCurLife = curTime - particule->creationTime;
|
|
|
|
if (particule->life != -1 && ParticuleCurLife > particule->life)
|
|
goto onDiing;
|
|
|
|
|
|
if (particule->collide)
|
|
{
|
|
if (forces.collisionFriction != 1.0f)
|
|
{
|
|
if (forces.collisionFriction < 0)
|
|
goto onDiing;
|
|
|
|
particule->speed *= forces.collisionFriction;
|
|
}
|
|
if (forces.collisionRandAngle != 0)
|
|
{
|
|
particule->speed = RotateVector(particule->speed, forces.collisionRandAngle);
|
|
}
|
|
ProcessParticuleSon(particule);
|
|
}
|
|
|
|
if (forces.Gravity.x != 0 || forces.Gravity.y != 0 || forces.Gravity.z != 0)
|
|
{
|
|
particule->speed += forces.Gravity*((float)time/1000);
|
|
}
|
|
if (forces.Frictions != 0.0f)
|
|
{
|
|
particule->speed *= pow((double)(1-forces.Frictions), (double)time);
|
|
}
|
|
if (forces.WindForce != 0.0f &&
|
|
(forces.WindDirection.x != 0 || forces.WindDirection.y != 0 || forces.WindDirection.z != 0))
|
|
{
|
|
memset(&v, 0, sizeof(v));
|
|
if (forces.WindDirection.x > 0.0f && particule->speed.x < forces.WindDirection.x)
|
|
{
|
|
v.x = forces.WindForce*time*forces.WindDirection.x;
|
|
if (v.x > forces.WindDirection.x - particule->speed.x)
|
|
v.x = forces.WindDirection.x - particule->speed.x;
|
|
}
|
|
if (forces.WindDirection.x < 0.0f && particule->speed.x > forces.WindDirection.x)
|
|
{
|
|
v.x = forces.WindForce*time*forces.WindDirection.x;
|
|
if (v.x < forces.WindDirection.x - particule->speed.x)
|
|
v.x = forces.WindDirection.x - particule->speed.x;
|
|
}
|
|
if (forces.WindDirection.y > 0.0f && particule->speed.y < forces.WindDirection.y)
|
|
{
|
|
v.y = forces.WindForce*time*forces.WindDirection.y;
|
|
if (v.y > forces.WindDirection.y - particule->speed.y)
|
|
v.y = forces.WindDirection.y - particule->speed.y;
|
|
}
|
|
if (forces.WindDirection.y < 0.0f && particule->speed.y > forces.WindDirection.y)
|
|
{
|
|
v.y = forces.WindForce*time*forces.WindDirection.y;
|
|
if (v.y < forces.WindDirection.y - particule->speed.y)
|
|
v.y = forces.WindDirection.y - particule->speed.y;
|
|
}
|
|
if (forces.WindDirection.z > 0.0f && particule->speed.z < forces.WindDirection.z)
|
|
{
|
|
v.z = forces.WindForce*time*forces.WindDirection.z;
|
|
if (v.z > forces.WindDirection.z - particule->speed.z)
|
|
v.z = forces.WindDirection.z - particule->speed.z;
|
|
}
|
|
if (forces.WindDirection.z < 0.0f && particule->speed.z > forces.WindDirection.z)
|
|
{
|
|
v.z = forces.WindForce*time*forces.WindDirection.z;
|
|
if (v.z < forces.WindDirection.z - particule->speed.z)
|
|
v.z = forces.WindDirection.z - particule->speed.z;
|
|
}
|
|
particule->speed += v;
|
|
}
|
|
|
|
if (forces.RotationSpeed != 0.0f || forces.RotationRand != 0.0f)
|
|
{
|
|
particule->rotAngle += time*VAL_RAND(forces.RotationSpeed, forces.RotationRand)/1000;
|
|
if (particule->rotAngle < 0)
|
|
particule->rotAngle = particule->rotAngle + 360;
|
|
}
|
|
|
|
if (forces.GrowFor != 0 && ParticuleCurLife < forces.GrowFor)
|
|
{
|
|
particule->scaleFactor = BARYCENTER(forces.GrowForInit, forces.GrowForEnd, ParticuleCurLife, forces.GrowFor);
|
|
} else if (forces.FadeFor != 0 && particule->life > 0 && (particule->life - ParticuleCurLife) < forces.FadeFor)
|
|
{
|
|
int TimeToDie = (particule->life - ParticuleCurLife);
|
|
particule->scaleFactor = BARYCENTER(forces.FadeForEnd, forces.FadeForInit, TimeToDie, forces.FadeFor);
|
|
} else if (forces.GrowForEnd != forces.FadeForInit)
|
|
{
|
|
int TimeTotal = particule->life - forces.GrowFor - forces.FadeFor;
|
|
int TimeElapsed = ParticuleCurLife - forces.GrowFor;
|
|
if (TimeTotal > 0 && TimeElapsed < TimeTotal)
|
|
particule->scaleFactor = BARYCENTER(forces.GrowForEnd, forces.FadeForInit, TimeElapsed, TimeTotal);
|
|
else
|
|
particule->scaleFactor = forces.GrowForEnd;
|
|
} else
|
|
particule->scaleFactor = 1.0f;
|
|
|
|
if (forces.GrowForColor != 0 && ParticuleCurLife < forces.GrowForColor)
|
|
{
|
|
particule->RGBA = BARYCENTER( forces.GrowForColorInit & 0xFF, forces.GrowForColorEnd & 0xFF, ParticuleCurLife, forces.GrowForColor) << 24 |
|
|
(BARYCENTER((forces.GrowForColorInit >> 8) & 0xFF, (forces.GrowForColorEnd >> 8) & 0xFF, ParticuleCurLife, forces.GrowForColor) << 16) |
|
|
(BARYCENTER((forces.GrowForColorInit >> 16) & 0xFF, (forces.GrowForColorEnd >> 16) & 0xFF, ParticuleCurLife, forces.GrowForColor) << 8) |
|
|
(BARYCENTER((forces.GrowForColorInit >> 24) & 0xFF, (forces.GrowForColorEnd >> 24) & 0xFF, ParticuleCurLife, forces.GrowForColor) << 0);
|
|
} else if (forces.FadeForColor != 0 && particule->life > 0 && (particule->life - ParticuleCurLife) < forces.FadeForColor)
|
|
{
|
|
int TimeToDie = (particule->life - ParticuleCurLife);
|
|
particule->RGBA = BARYCENTER( forces.FadeForColorEnd & 0xFF, forces.FadeForColorInit & 0xFF, TimeToDie, forces.FadeForColor) << 24 |
|
|
(BARYCENTER((forces.FadeForColorEnd >> 8) & 0xFF, (forces.FadeForColorInit >> 8) & 0xFF, TimeToDie, forces.FadeForColor) << 16) |
|
|
(BARYCENTER((forces.FadeForColorEnd >> 16) & 0xFF, (forces.FadeForColorInit >> 16) & 0xFF, TimeToDie, forces.FadeForColor) << 8) |
|
|
(BARYCENTER((forces.FadeForColorEnd >> 24) & 0xFF, (forces.FadeForColorInit >> 24) & 0xFF, TimeToDie, forces.FadeForColor) << 0);
|
|
} else if (forces.GrowForColorEnd != forces.FadeForColorInit)
|
|
{
|
|
int TimeTotal = particule->life - forces.GrowForColor - forces.FadeForColor;
|
|
int TimeElapsed = ParticuleCurLife - forces.GrowForColor;
|
|
if (TimeTotal > 0 && TimeElapsed < TimeTotal)
|
|
particule->RGBA = BARYCENTER( forces.GrowForColorEnd & 0xFF, forces.FadeForColorInit & 0xFF, TimeElapsed, TimeTotal) << 24 |
|
|
(BARYCENTER((forces.GrowForColorEnd >> 8) & 0xFF, (forces.FadeForColorInit >> 8) & 0xFF, TimeElapsed, TimeTotal) << 16) |
|
|
(BARYCENTER((forces.GrowForColorEnd >> 16) & 0xFF, (forces.FadeForColorInit >> 16) & 0xFF, TimeElapsed, TimeTotal) << 8) |
|
|
(BARYCENTER((forces.GrowForColorEnd >> 24) & 0xFF, (forces.FadeForColorInit >> 24) & 0xFF, TimeElapsed, TimeTotal) << 0);
|
|
else
|
|
particule->scaleFactor = -1;
|
|
} else
|
|
particule->RGBA = (((forces.GrowForColorEnd ) & 0xFF) << 24) |
|
|
(((forces.GrowForColorEnd >> 8 ) & 0xFF) << 16) |
|
|
(((forces.GrowForColorEnd >> 16) & 0xFF) << 8 ) |
|
|
(((forces.GrowForColorEnd >> 24) & 0xFF) << 0 ) ;
|
|
|
|
|
|
if (forces.AnimSpeed != 0)
|
|
{
|
|
particule->textureIdx = particule->textureIdxBase + (curTime - particule->creationTime)/forces.AnimSpeed;
|
|
if (particule->textureIdx >= nbInGrid)
|
|
{
|
|
if (forces.AnimRepeat)
|
|
particule->textureIdx = particule->textureIdx % nbInGrid;
|
|
else
|
|
particule->textureIdx = nbInGrid - 1;
|
|
}
|
|
}
|
|
|
|
particule->coordsDest = particule->coords + particule->speed*(((float)time)/1000);
|
|
particule->speedDest = particule->speed;
|
|
particule->collide = 0;
|
|
return true;
|
|
|
|
onDiing:
|
|
particule->alive = 0;
|
|
ProcessParticuleSon(particule);
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
void PGENERATOR_OBJ::Init()
|
|
{
|
|
for (int i=0; i<nbParticules; i++)
|
|
if (particulesTab[i].luaCollideCallBack)
|
|
CC_free(particulesTab[i].luaCollideCallBack);
|
|
if (particulesTab)
|
|
CC_free(particulesTab);
|
|
particulesTab = NULL;
|
|
if (OriginList)
|
|
CC_free(OriginList);
|
|
OriginList = NULL;
|
|
if (DirectionList)
|
|
CC_free(DirectionList);
|
|
DirectionList = NULL;
|
|
|
|
particulesTab = (Particules *)CC_malloc(maxParticules*sizeof(Particules));
|
|
memset(particulesTab, 0, maxParticules*sizeof(Particules));
|
|
|
|
if (options & 8)
|
|
{
|
|
OriginList = (Vector *)CC_malloc(genNumber*sizeof(Vector));
|
|
DirectionList = (Vector *)CC_malloc(genNumber*sizeof(Vector));
|
|
}
|
|
|
|
nbParticules = 0;
|
|
curParticule = -1;
|
|
pgTime = timeGetTime();
|
|
pgTimeUnused = 0;
|
|
particuleSonPtr = NULL;
|
|
nbInGrid = TextureGrid.cx*TextureGrid.cy;
|
|
}
|
|
|
|
|
|
void PGENERATOR_OBJ::Process(int elapsedTime)
|
|
{
|
|
int partIdx;
|
|
Particules *currentPart;
|
|
|
|
if (!alive) return;
|
|
alive = false;
|
|
currentPart = particulesTab;
|
|
for (partIdx=0; partIdx<nbParticules; partIdx++, currentPart++)
|
|
{
|
|
if (ProcessParticule(elapsedTime, currentPart))
|
|
alive = true;
|
|
}
|
|
}
|
|
|
|
int PGENERATOR_OBJ::GenerateSingle(Vector center, Vector direction, int elapsedTime)
|
|
{
|
|
Particules *currentPart;
|
|
|
|
curParticule = (curParticule + 1) % maxParticules;
|
|
if (nbParticules < maxParticules) nbParticules++;
|
|
|
|
currentPart = particulesTab + curParticule;
|
|
|
|
currentPart->alive = 1;
|
|
if (particuleLife < 0)
|
|
currentPart->life = -1;
|
|
else
|
|
currentPart->life = VAL_RAND(particuleLife, particuleLifeRand);
|
|
currentPart->creationTime = curTime - elapsedTime;
|
|
currentPart->coords = center;
|
|
currentPart->speed = RotateVector(direction, genAngleAllowed)*VAL_RAND(genPower, genPowerRand);
|
|
if (genSizeRand >= 0 || !genWidth)
|
|
{
|
|
currentPart->width = VAL_RAND(genWidth, genSizeRand);
|
|
currentPart->height = VAL_RAND(genHeight, genSizeRand);
|
|
} else
|
|
{
|
|
currentPart->width = VAL_RAND(genWidth, -genSizeRand);
|
|
currentPart->height = currentPart->width*genHeight/genWidth;
|
|
}
|
|
currentPart->collide= 0;
|
|
|
|
if (forces.AnimInit != 0)
|
|
{
|
|
if (forces.AnimInit == -1)
|
|
{
|
|
currentPart->textureIdx = nbInGrid*rand()/RAND_MAX;
|
|
} else {
|
|
TextureIdx += forces.AnimInit;
|
|
if (TextureIdx >= nbInGrid)
|
|
TextureIdx = TextureIdx % nbInGrid;
|
|
currentPart->textureIdx = TextureIdx;
|
|
}
|
|
currentPart->textureIdxBase = currentPart->textureIdx;
|
|
} else
|
|
currentPart->textureIdxBase = 0;
|
|
|
|
currentPart->rotAngle = forces.RotationInit;
|
|
currentPart->rotAngle += (forces.RotationInit2 - forces.RotationInit)*rand()/RAND_MAX;
|
|
|
|
ProcessParticule(elapsedTime, currentPart);
|
|
return curParticule;
|
|
}
|
|
|
|
void PGENERATOR_OBJ::GenerateFix(int nbPToMake, int life)
|
|
{
|
|
int partIdx, partIdxIn;
|
|
BOOL fromMesh = options & 8;
|
|
|
|
alive = true;
|
|
|
|
if (nbPToMake*genNumber > maxParticules)
|
|
nbPToMake = maxParticules/genNumber;
|
|
|
|
for (partIdx=0; partIdx<nbPToMake; partIdx++)
|
|
{
|
|
for (partIdxIn=0; partIdxIn<genNumber; partIdxIn++)
|
|
{
|
|
if (fromMesh)
|
|
GenerateSingle(OriginList[partIdxIn], DirectionList[partIdxIn], life);
|
|
else
|
|
GenerateSingle(Origin, Direction, life);
|
|
}
|
|
}
|
|
}
|
|
|
|
void PGENERATOR_OBJ::GenerateDyn(int elapsedTime)
|
|
{
|
|
int partIdx, partIdxIn;
|
|
float genSpeedIn;
|
|
int nbPToMake;
|
|
int elapsedTimeIn;
|
|
int elapsedTimeGen = elapsedTime + pgTimeUnused;
|
|
BOOL fromMesh = options & 8;
|
|
|
|
if (particuleRepeat || nbParticules < maxParticules)
|
|
{
|
|
genSpeedIn = VAL_RAND(genSpeed, genSpeedRand);
|
|
nbPToMake = (int)(elapsedTimeGen * genSpeedIn / 1000);
|
|
pgTimeUnused = elapsedTimeGen - ((float)nbPToMake * 1000 / genSpeedIn);
|
|
|
|
if (nbPToMake*genNumber > maxParticules)
|
|
{
|
|
nbPToMake = maxParticules/genNumber;
|
|
elapsedTime = nbPToMake*1000/genSpeedIn;
|
|
}
|
|
alive = true;
|
|
} else
|
|
return;
|
|
|
|
if (!particuleRepeat && (nbParticules + nbPToMake) > maxParticules)
|
|
{
|
|
nbPToMake = maxParticules - nbParticules;
|
|
elapsedTime = nbPToMake*1000/genSpeedIn;
|
|
}
|
|
|
|
for (partIdx=0; partIdx<nbPToMake; partIdx++)
|
|
{
|
|
elapsedTimeIn = (nbPToMake-partIdx)*elapsedTime/nbPToMake;
|
|
for (partIdxIn=0; partIdxIn<genNumber; partIdxIn++)
|
|
{
|
|
if (fromMesh)
|
|
GenerateSingle(OriginList[partIdxIn], DirectionList[partIdxIn], elapsedTimeIn);
|
|
else
|
|
GenerateSingle(Origin, Direction, elapsedTimeIn);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
BOOL SetOriginDirection(PGENERATOR_OBJ *PGen, SmallScene *SmSc, float IVal, float JVal, float KVal)
|
|
{
|
|
MATRIX WM;
|
|
int ObjectREF = 0;
|
|
_3D_Object *pObj;
|
|
|
|
if (SmSc == NULL)
|
|
return false;
|
|
|
|
if (PGen->ObjectName[0])
|
|
{
|
|
ObjectREF = SmSc->ObjectNameDico.IsExist(PGen->ObjectName);
|
|
if (ObjectREF == -1 && !strstr(PGen->ObjectName, ".OBJ"))
|
|
{
|
|
strcat(PGen->ObjectName, ".OBJ");
|
|
ObjectREF = SmSc->ObjectNameDico.IsExist(PGen->ObjectName);
|
|
}
|
|
if (ObjectREF != -1)
|
|
{
|
|
ObjectREF = SmSc->ObjectNameDico.mpst_Dico[ObjectREF].AssociatedValue;
|
|
}
|
|
if (ObjectREF == -1)
|
|
ObjectREF = 0;
|
|
}
|
|
|
|
pObj = SmSc->ObjectsPtrs[ObjectREF];
|
|
WM = pObj->GlobalMatrix;
|
|
|
|
PGen->Origin = WM.T;
|
|
PGen->Origin += pObj->GlobalMatrix.I * pObj->Pivot.x;
|
|
PGen->Origin += pObj->GlobalMatrix.J * pObj->Pivot.y;
|
|
PGen->Origin += pObj->GlobalMatrix.K * pObj->Pivot.z;
|
|
|
|
if (IVal == 0 && JVal == 0 && KVal == 0)
|
|
PGen->Direction = WM.I;
|
|
else
|
|
PGen->Direction = WM.I*IVal + WM.J*JVal + WM.K*KVal;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
u32 WORLD::LoadPGenerator(s8 *Name, s8 *fileName, s8 *SceneName, s8 *ObjectName, s8 *MassTextureName)
|
|
{
|
|
u32 ID;
|
|
UnicID mUID;
|
|
char PGenNameFile[MAX_PATH];
|
|
|
|
if (PGeneratorDico.IsExist(Name) != -1)
|
|
{
|
|
PGeneratorDico.GetUnic(&mUID,Name);
|
|
ID = PGeneratorDico.mpst_Dico[mUID].AssociatedValue;
|
|
if (ID_PGENERATOR[ID])
|
|
{
|
|
delete ID_PGENERATOR[ID];
|
|
ID_PGENERATOR[ID] = NULL;
|
|
}
|
|
} else
|
|
{
|
|
PGeneratorDico.GetUnic(&mUID,Name);
|
|
ID = PGeneratorCreateID++;
|
|
if (ID > MAX_INPMED) return -1;
|
|
PGeneratorDico.mpst_Dico[mUID].AssociatedValue = ID;
|
|
}
|
|
|
|
sprintf(PGenNameFile, ".\\Particles\\%s", fileName);
|
|
if (GetFileNameExtend(fileName) != '.PGR')
|
|
strcat(fileName, ".PGR");
|
|
|
|
ID_PGENERATOR[ID] = new PGENERATOR_OBJ();
|
|
if (LoadPGENERATOR_OBJ(&ID_PGENERATOR[ID],PGenNameFile))
|
|
return -1;
|
|
ID_PGENERATOR[ID]->alive = true;
|
|
strcpy(ID_PGENERATOR[ID]->Name, Name);
|
|
strcpy(ID_PGENERATOR[ID]->GeneratorName, fileName);
|
|
strcpy(ID_PGENERATOR[ID]->SceneName, SceneName);
|
|
strcpy(ID_PGENERATOR[ID]->ObjectName, ObjectName);
|
|
strcpy(ID_PGENERATOR[ID]->MassTextureName, MassTextureName);
|
|
if (*ID_PGENERATOR[ID]->MassTextureName)
|
|
CreateMedia(ID_PGENERATOR[ID]->MassTextureName, 0);
|
|
|
|
// Code For .MAT in Particles, ABONDONNED
|
|
//if (GetFileNameExtend(ID_PGENERATOR[ID]->MediaName) == '.MAT')
|
|
//{
|
|
// ID_PGENERATOR[ID]->MaterialPtr = (_3D_Material*)CC_malloc(sizeof(_3D_Material));
|
|
// memset(ID_PGENERATOR[ID]->MaterialPtr,0,sizeof(_3D_Material));
|
|
// FILE *F = fopen(ID_PGENERATOR[ID]->MediaName, "rb");
|
|
// if (F)
|
|
// {
|
|
// UNIC_Dico Dico;
|
|
// Dico.Init();
|
|
|
|
// Load_3D_Material(&ID_PGENERATOR[ID]->MaterialPtr,F, &Dico);
|
|
// for (int j = 0 ; j < ID_PGENERATOR[ID]->MaterialPtr->NumberOfLayers ; j++ )
|
|
// {
|
|
// char Name2[2048];
|
|
// Dico.GetName(&ID_PGENERATOR[ID]->MaterialPtr->Layers[j].TextureID,Name2);
|
|
// CreateMedia(Name2,0);
|
|
// MediaDico.GetUnic(&ID_PGENERATOR[ID]->MaterialPtr->Layers[j].TextureMediaIndex,Name2);
|
|
// MediaDico.GetName(&ID_PGENERATOR[ID]->MaterialPtr->Layers[j].TextureMediaIndex,Name2);
|
|
|
|
// // Trying this ...
|
|
// ID_PGENERATOR[ID]->MaterialPtr->Layers[j].TextureID = ID_PGENERATOR[ID]->MaterialPtr->Layers[j].TextureMediaIndex;
|
|
// }
|
|
// CC_fclose(F);
|
|
// } else
|
|
// {
|
|
// CC_free(ID_PGENERATOR[ID]->MaterialPtr);
|
|
// ID_PGENERATOR[ID]->MaterialPtr = NULL;
|
|
// }
|
|
//} else
|
|
//{
|
|
// ID_PGENERATOR[ID]->MaterialPtr = NULL;
|
|
CreateMedia(ID_PGENERATOR[ID]->MediaName, 0);
|
|
//}
|
|
|
|
|
|
ID_PGENERATOR[ID]->ThisID = ID;
|
|
ID_PGENERATOR[ID]->Init();
|
|
ComputeParticleOptions(ID_PGENERATOR[ID]);
|
|
return ID;
|
|
}
|
|
|
|
void WORLD::DeletePGenerator(s8 *Name)
|
|
{
|
|
u32 ID;
|
|
UnicID mUID;
|
|
|
|
if (PGeneratorDico.IsExist(Name) == -1)
|
|
return;
|
|
|
|
PGeneratorDico.GetUnic(&mUID,Name);
|
|
ID = PGeneratorDico.mpst_Dico[mUID].AssociatedValue;
|
|
if (ID_PGENERATOR[ID])
|
|
{
|
|
u32 mediaIndex;
|
|
if (GetMediaFromString(ID_PGENERATOR[ID]->MediaName, &mediaIndex))
|
|
DestroyMedia(mediaIndex);
|
|
if (*ID_PGENERATOR[ID]->MassTextureName && GetMediaFromString(ID_PGENERATOR[ID]->MassTextureName, &mediaIndex))
|
|
DestroyMedia(mediaIndex);
|
|
delete ID_PGENERATOR[ID];
|
|
ID_PGENERATOR[ID] = NULL;
|
|
}
|
|
PGeneratorDico.DelWord(Name);
|
|
}
|
|
|
|
void WORLD::TouchPGenerator(s8 *BaseName)
|
|
{
|
|
for (; *BaseName; BaseName++)
|
|
{
|
|
for (int ID=0; ID<MAX_PGENERATOR; ID++)
|
|
{
|
|
if (!ID_PGENERATOR[ID]) continue;
|
|
if (!strcmp(ID_PGENERATOR[ID]->GeneratorName, BaseName))
|
|
{
|
|
char Name[MAX_PATH];
|
|
char SceneName[MAX_PATH];
|
|
char ObjectName[MAX_PATH];
|
|
char MassTextureName[MAX_PATH];
|
|
|
|
strcpy(Name, ID_PGENERATOR[ID]->Name);
|
|
strcpy(SceneName, ID_PGENERATOR[ID]->SceneName);
|
|
strcpy(ObjectName, ID_PGENERATOR[ID]->ObjectName);
|
|
strcpy(MassTextureName, ID_PGENERATOR[ID]->MassTextureName);
|
|
|
|
DeletePGenerator(Name);
|
|
LoadPGenerator(Name, BaseName, SceneName, ObjectName, MassTextureName);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void WORLD::SavePGenerator(s8 *Name, s8 *fileName)
|
|
{
|
|
u32 ID;
|
|
UnicID mUID;
|
|
|
|
if (PGeneratorDico.IsExist(Name) == -1)
|
|
return;
|
|
|
|
PGeneratorDico.GetUnic(&mUID,Name);
|
|
ID = PGeneratorDico.mpst_Dico[mUID].AssociatedValue;
|
|
if (ID_PGENERATOR[ID])
|
|
{
|
|
char PGenNameFile[256];
|
|
if (fileName && *fileName)
|
|
sprintf(PGenNameFile, ".\\Particles\\%s", fileName);
|
|
else
|
|
sprintf(PGenNameFile, ".\\Particles\\%s", ID_PGENERATOR[ID]->GeneratorName);
|
|
|
|
if (GetFileNameExtend(PGenNameFile) != '.PGR')
|
|
strcat(PGenNameFile, ".PGR");
|
|
|
|
SavePGENERATOR_OBJ(ID_PGENERATOR[ID],PGenNameFile);
|
|
}
|
|
}
|
|
|
|
void WORLD::ComputeParticleOptions(PGENERATOR_OBJ *PGen)
|
|
{
|
|
if (PGen->sonMode != 0)
|
|
{
|
|
char sonName[MAX_PATH];
|
|
char empty = 0;
|
|
u32 sonID;
|
|
sprintf(sonName, "%s_Son", PGen->Name);
|
|
|
|
sonID = LoadPGenerator(sonName, PGen->son, &empty, &empty, &empty);
|
|
if (sonID != -1)
|
|
PGen->particuleSonPtr = ID_PGENERATOR[sonID];
|
|
}
|
|
|
|
|
|
if (PGen->options & 8)
|
|
{
|
|
SmallScene *SmSc = SmallNameToScene(PGen->SceneName);
|
|
if (SmSc != NULL &&
|
|
PGen->ObjectName[0])
|
|
{
|
|
u32 ObjectREF = SmSc->ObjectNameDico.IsExist(PGen->ObjectName);
|
|
if (ObjectREF == -1)
|
|
{
|
|
strcat(PGen->ObjectName, ".OBJ");
|
|
ObjectREF = SmSc->ObjectNameDico.IsExist(PGen->ObjectName);
|
|
}
|
|
if (ObjectREF != -1)
|
|
ObjectREF = SmSc->ObjectNameDico.mpst_Dico[ObjectREF].AssociatedValue;
|
|
if (ObjectREF != -1)
|
|
{
|
|
_3D_Object *pObj = SmSc->ObjectsPtrs[ObjectREF];
|
|
if (pObj->MeshIndex != -1)
|
|
{
|
|
Mesh *RenderMesh = SmSc->MeshesPtrs[pObj->MeshIndex];
|
|
MAP *massTexture = NULL;
|
|
|
|
if (*PGen->MassTextureName)
|
|
{
|
|
int MediaIndex = MediaDico.IsExist(PGen->MassTextureName);
|
|
if (MediaIndex != -1)
|
|
{
|
|
MediaIndex = MediaDico.mpst_Dico[MediaIndex].AssociatedValue;
|
|
if (MediaIndex != -1)
|
|
{
|
|
massTexture = &ID_MEDIA[MediaIndex]->Image;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (PGen->MeshSurfaceList != NULL)
|
|
CC_free(PGen->MeshSurfaceList);
|
|
PGen->MeshFaces = RenderMesh->NumberOfFaces;
|
|
PGen->MeshSurfaceList = (float *)CC_malloc(RenderMesh->NumberOfFaces*sizeof(float));
|
|
PGen->MeshSurface = GetMeshSurface(RenderMesh, NULL, PGen->MeshSurfaceList, massTexture);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ParticuleFromMesh = 0;
|
|
for (int partIdx = 0; partIdx<MAX_PGENERATOR; partIdx++)
|
|
{
|
|
if (ID_PGENERATOR[partIdx] && (ID_PGENERATOR[partIdx]->options & 8))
|
|
{
|
|
ParticuleFromMesh = 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void WORLD::ProcessParticules(PGENERATOR_OBJ *PGen, bool ProcessOnly, float IVal, float JVal, float KVal)
|
|
{
|
|
START_RASTER(ParticuleProcess);
|
|
|
|
PGen->Collision = CollisionOn;
|
|
PGen->curTime = timeGetTime();
|
|
PGen->Process(PGen->curTime - PGen->pgTime);
|
|
|
|
if (!ProcessOnly)
|
|
{
|
|
if (*PGen->SceneName &&
|
|
SetOriginDirection(PGen, SmallNameToScene(PGen->SceneName), IVal, JVal, KVal))
|
|
{
|
|
PGen->GenerateDyn(PGen->curTime - PGen->pgTime);
|
|
}
|
|
}
|
|
|
|
PGen->pgTime = PGen->curTime;
|
|
STOP_RASTER(ParticuleProcess);
|
|
}
|
|
|
|
int WORLD::EmitParticule(PGENERATOR_OBJ *PGen, int life, float IVal, float JVal, float KVal, Vector *origin, Vector *direction)
|
|
{
|
|
if (PGen->options & 8)
|
|
{
|
|
PGen->GenerateFix(1, life);
|
|
return -1;
|
|
}
|
|
|
|
if (origin != NULL && direction != NULL)
|
|
{
|
|
PGen->Origin = *origin;
|
|
PGen->Direction = *direction;
|
|
} else
|
|
{
|
|
if (!*PGen->SceneName ||
|
|
!SetOriginDirection(PGen, SmallNameToScene(PGen->SceneName), IVal, JVal, KVal))
|
|
return -1;
|
|
}
|
|
|
|
return PGen->GenerateSingle(PGen->Origin, PGen->Direction, life);
|
|
}
|
|
|
|
|
|
|
|
void WORLD::RenderParticules(PGENERATOR_OBJ *PGen, char *SceneName)
|
|
{
|
|
if (!PGen->alive) return;
|
|
|
|
SmallScene *SmSc;
|
|
MATRIX MatrixToSet,CP;
|
|
float Current_focale;
|
|
RS RSToUse;
|
|
|
|
if (SceneName == NULL || *SceneName == 0)
|
|
SmSc = SmallNameToScene(PGen->SceneName);
|
|
else
|
|
SmSc = SmallNameToScene(SceneName);
|
|
if (SmSc == NULL) return;
|
|
|
|
if (SmSc->fFocalToUseForNextRender == 0)
|
|
Current_focale = GetCurrentFocale();
|
|
else
|
|
Current_focale = SmSc->fFocalToUseForNextRender;
|
|
DI->Perspective(Current_focale);
|
|
|
|
CP = SmSc->CameraPosition;
|
|
CP.K *= -1.0f;
|
|
CP.Inverse(MatrixToSet);
|
|
|
|
DI->Matrix(&MatrixToSet);
|
|
|
|
|
|
START_RASTER(ParticuleRender);
|
|
|
|
Particules *partPtr;
|
|
int partIdx;
|
|
for (partIdx=0, partPtr=PGen->particulesTab; partIdx<PGen->nbParticules; partIdx++, partPtr++)
|
|
{
|
|
partPtr->coords = partPtr->coordsDest;
|
|
partPtr->speed = partPtr->speedDest;
|
|
}
|
|
|
|
|
|
// Code For .MAT in Particles, ABONDONNED
|
|
//if (!PGen->MaterialPtr)
|
|
//{
|
|
int MediaIndex = MediaDico.IsExist((char *)PGen->MediaName);
|
|
if (MediaIndex != -1) MediaIndex = MediaDico.mpst_Dico[MediaIndex].AssociatedValue;
|
|
if (MediaIndex == -1 || !ID_MEDIA[MediaIndex])
|
|
return;
|
|
|
|
GLOB_SetDefaultRS(&RSToUse);
|
|
RSToUse.BACKFACE = 0;
|
|
RSToUse.BlendingMode = PGen->BlendMode;
|
|
|
|
if (PGen->AlphaThreshold < 0)
|
|
{
|
|
RSToUse.AlphaThreshold = -PGen->AlphaThreshold - 1;
|
|
RSToUse.NOZWRITE = 1;
|
|
} else
|
|
{
|
|
RSToUse.AlphaThreshold = PGen->AlphaThreshold;
|
|
RSToUse.NOZWRITE = 0;
|
|
}
|
|
|
|
// Force no Z test and ZWrite
|
|
RSToUse.NOZWRITE = 0;
|
|
RSToUse.ZPASS = 1;
|
|
|
|
DI->DrawParticules(PGen->particulesTab, PGen->nbParticules, ID_MEDIA[MediaIndex]->ulAssociatedTextureIndex, PGen->TextureGrid, &RSToUse, SmSc->CameraPosition);
|
|
|
|
// Code For .MAT in Particles, ABONDONNED
|
|
//} else
|
|
//{
|
|
// u32 CurrentColor,MulColor;
|
|
// CurrentColor = DI->GetCurrentColor();
|
|
|
|
// for (int SubLvl = 0 ; SubLvl < PGen->MaterialPtr->NumberOfLayers; SubLvl++)
|
|
// {
|
|
// u32 MediaIndex,OGLIndex;
|
|
// if (PGen->MaterialPtr->Layers[SubLvl].RenderState.SKIPLAYER) continue;
|
|
|
|
// MulColor = COL_MulColor(CurrentColor,PGen->MaterialPtr->Layers[SubLvl].ColorMultiplier);
|
|
// DI->SetCurrentColor(MulColor);
|
|
// OGLIndex = -1;
|
|
// MediaIndex = PGen->MaterialPtr->Layers[SubLvl].TextureMediaIndex;
|
|
// if (MediaIndex != -1)
|
|
// {
|
|
// MediaIndex = MediaDico.mpst_Dico[PGen->MaterialPtr->Layers[SubLvl].TextureMediaIndex].AssociatedValue;
|
|
// if (MediaIndex != -1 && ID_MEDIA[MediaIndex])
|
|
// {
|
|
// if (ID_MEDIA[MediaIndex]->ulMediaRedirectValue != -1)
|
|
// {
|
|
// MediaIndex = ID_MEDIA[MediaIndex]->ulMediaRedirectValue;
|
|
// }
|
|
// OGLIndex = ID_MEDIA[MediaIndex]->ulAssociatedTextureIndex;
|
|
// }
|
|
// }
|
|
// RSToUse = PGen->MaterialPtr->Layers[SubLvl].RenderState;
|
|
// DI->SetRS(&RSToUse,OGLIndex);
|
|
// DI->DrawParticules(PGen->particulesTab, PGen->nbParticules, ID_MEDIA[MediaIndex]->ulAssociatedTextureIndex, PGen->TextureGrid, &RSToUse, SmSc->CameraPosition);
|
|
// DI->SetCurrentColor(CurrentColor);
|
|
// }
|
|
//}
|
|
|
|
STOP_RASTER(ParticuleRender);
|
|
}
|
|
|
|
|
|
void WORLD::ComputeMeshParticules(char *Name, _3D_Object *obj, Mesh *RenderMesh, MATRIX *global)
|
|
{
|
|
int beginFace = 0;
|
|
int beginRand = 0;
|
|
MAP *massTexture = NULL;
|
|
|
|
for (int partIdx=0; partIdx<MAX_PGENERATOR; partIdx++)
|
|
{
|
|
if (!ID_PGENERATOR[partIdx] ||
|
|
!ID_PGENERATOR[partIdx]->alive ||
|
|
!(ID_PGENERATOR[partIdx]->options & 8) ||
|
|
!*ID_PGENERATOR[partIdx]->ObjectName) continue;
|
|
if (strcmp(ID_PGENERATOR[partIdx]->SceneName, Name))
|
|
continue;
|
|
|
|
SmallScene *SmSc = SmallNameToScene(ID_PGENERATOR[partIdx]->SceneName);
|
|
if (SmSc == NULL)
|
|
continue;
|
|
int ObjectREF = SmSc->ObjectNameDico.IsExist(ID_PGENERATOR[partIdx]->ObjectName);
|
|
|
|
if (ObjectREF != -1)
|
|
ObjectREF = SmSc->ObjectNameDico.mpst_Dico[ObjectREF].AssociatedValue;
|
|
if (SmSc->ObjectsPtrs[ObjectREF] != obj)
|
|
continue;
|
|
|
|
float surface = ID_PGENERATOR[partIdx]->MeshSurface;
|
|
if (ID_PGENERATOR[partIdx]->options & 16)
|
|
{
|
|
beginFace = ID_PGENERATOR[partIdx]->MeshFaces * rand() / RAND_MAX;
|
|
beginRand = 2 * (NB_RAND_ELMTS / 2 * rand() / RAND_MAX);
|
|
}
|
|
|
|
if (*ID_PGENERATOR[partIdx]->MassTextureName)
|
|
{
|
|
int MediaIndex = MediaDico.IsExist(ID_PGENERATOR[partIdx]->MassTextureName);
|
|
if (MediaIndex != -1)
|
|
{
|
|
MediaIndex = MediaDico.mpst_Dico[MediaIndex].AssociatedValue;
|
|
if (MediaIndex != -1)
|
|
{
|
|
massTexture = &ID_MEDIA[MediaIndex]->Image;
|
|
}
|
|
}
|
|
}
|
|
|
|
GetPointRepartition(ID_PGENERATOR[partIdx]->OriginList,
|
|
ID_PGENERATOR[partIdx]->DirectionList,
|
|
NULL,
|
|
NULL,
|
|
ID_PGENERATOR[partIdx]->genNumber,
|
|
RenderMesh, global, surface/(ID_PGENERATOR[partIdx]->genNumber),
|
|
ID_PGENERATOR[partIdx]->MeshSurfaceList, massTexture,
|
|
beginFace, beginRand);
|
|
}
|
|
}
|
|
|
|
void WORLD::DestroyAllPGenerator()
|
|
{
|
|
for (u32 Counter = 0 ; Counter < MAX_PGENERATOR; Counter++)
|
|
{
|
|
if (ID_PGENERATOR[Counter])
|
|
{
|
|
delete ID_PGENERATOR[Counter];
|
|
ID_PGENERATOR[Counter] = NULL;
|
|
}
|
|
}
|
|
PGeneratorDico.Destroy();
|
|
PGeneratorCreateID = 0;
|
|
}
|
|
|
|
|
|
int WORLD::GetPGeneratorFromString(char *PGeneratorName, u32 *PGeneratorIndex)
|
|
{
|
|
*PGeneratorIndex = PGeneratorDico.IsExist(PGeneratorName);
|
|
if (*PGeneratorIndex == -1) return 0;
|
|
*PGeneratorIndex = PGeneratorDico.mpst_Dico[*PGeneratorIndex].AssociatedValue;
|
|
return *PGeneratorIndex != -1 && ID_PGENERATOR[*PGeneratorIndex] != NULL;
|
|
}
|
|
|
|
PGENERATOR_OBJ* WORLD::GetPGeneratorPtrFromString(char *PGeneratorName)
|
|
{
|
|
u32 PGeneratorIndex = PGeneratorDico.IsExist(PGeneratorName);
|
|
if (PGeneratorIndex == -1) return NULL;
|
|
PGeneratorIndex = PGeneratorDico.mpst_Dico[PGeneratorIndex].AssociatedValue;
|
|
return ID_PGENERATOR[PGeneratorIndex];
|
|
}
|