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