00001 #include "Revolt.h"
00002 #include "Particle.h"
00003 #include "Geom.h"
00004 #include "NewColl.h"
00005 
00006 void ParticleWorldColls(PARTICLE *particle);
00007 
00009 
00010 
00011 
00012 
00013 
00014 
00016 
00017 void SetParticleMass(PARTICLE *particle, REAL newMass)
00018 {
00019   particle->Mass = newMass;
00020   particle->InvMass = DivScalar(ONE, newMass);
00021 }
00022 
00023 
00025 
00026 
00027 
00028 
00029 
00030 
00032 
00033 void ApplyParticleImpulse(PARTICLE *particle, VEC *impulse)
00034 {
00035   VecPlusEqVec(&particle->Impulse, impulse);
00036 }
00037 
00038 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00048 
00049 
00050 void UpdateParticle(PARTICLE *particle, REAL dt)
00051 {
00052   VEC oldVel;
00053   REAL  tReal;
00054 
00055   
00056   VecPlusEqVec(&particle->Pos, &particle->Shift);
00057   SetVecZero(&particle->Shift);
00058 
00059   
00060   CopyVec(&particle->Pos, &particle->OldPos);
00061   CopyVec(&particle->Vel, &oldVel);
00062 
00063   
00064   VecPlusEqScalarVec(&particle->Vel, particle->InvMass, &particle->Impulse);
00065 
00066   
00067   tReal = MulScalar(particle->Resistance, MulScalar(FRICTION_TIME_SCALE, dt));
00068   VecMulScalar(&particle->Vel, ONE - tReal);
00069 
00070   
00071   VecPlusEqScalarVec(&particle->Pos, dt, &particle->Vel);
00072 
00073   
00074   SetVecZero(&particle->Impulse);
00075 
00076   
00077   VecMinusVec(&particle->Vel, &oldVel, &particle->Acc);
00078 
00079 }
00080 
00081 
00083 
00084 
00085 
00087 
00088 void ParticleWorldColls(PARTICLE *particle)
00089 {
00090   int iPoly;
00091   REAL time, depth, velDotNorm;
00092   VEC dPos, wPos;
00093   BBOX bBox;
00094   NEWCOLLPOLY *collPoly;
00095   COLLGRID *grid;
00096 
00097   
00098   grid = PosToCollGrid(&particle->Pos);
00099   if (grid == NULL) return;
00100 
00101   
00102   for (iPoly = 0; iPoly < grid->NCollPolys; iPoly++) {
00103 #ifndef _PSX
00104     collPoly = grid->CollPolyPtr[iPoly];
00105 #else
00106     collPoly = &COL_WorldCollPoly[grid->CollPolyIndices[iPoly]];
00107 #endif
00108 
00109     if (PolyCameraOnly(collPoly)) continue;
00110 
00111     
00112     SetBBox(&bBox, 
00113       Min(particle->Pos.v[X], particle->OldPos.v[X]),
00114       Max(particle->Pos.v[X], particle->OldPos.v[X]),
00115       Min(particle->Pos.v[Y], particle->OldPos.v[Y]),
00116       Max(particle->Pos.v[Y], particle->OldPos.v[Y]),
00117       Min(particle->Pos.v[Z], particle->OldPos.v[Z]),
00118       Max(particle->Pos.v[Z], particle->OldPos.v[Z]));
00119     if(!BBTestYXZ(&bBox, &collPoly->BBox)) continue;
00120 
00121     
00122     if (!LinePlaneIntersect(&particle->OldPos, &particle->Pos, &collPoly->Plane, &time, &depth)) {
00123       continue;
00124     }
00125 
00126     
00127     VecMinusVec(&particle->Pos, &particle->OldPos, &dPos);
00128     VecPlusScalarVec(&particle->OldPos, time, &dPos, &wPos);
00129 
00130     
00131     velDotNorm = VecDotVec(&particle->Vel, PlaneNormal(&collPoly->Plane));
00132     if (velDotNorm > ZERO) continue;
00133 
00134 
00135     
00136     if (!PointInCollPolyBounds(&wPos, collPoly)) {
00137       continue;
00138     }
00139 
00140     
00141     VecPlusEqScalarVec(&particle->Pos, -depth + COLL_EPSILON, PlaneNormal(&collPoly->Plane));
00142 
00143     
00144     VecPlusEqScalarVec(&particle->Vel, -velDotNorm, PlaneNormal(&collPoly->Plane));
00145     VecMulScalar(&particle->Vel, (ONE - particle->KineticFriction));
00146     VecPlusEqScalarVec(&particle->Vel, -(particle->Hardness * velDotNorm), PlaneNormal(&collPoly->Plane));
00147 
00148 
00149   }
00150 }
00151 
00152