00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #pragma warning(disable : 4701) //local variable may be used without having been initialized
00013
00014 #include "g_local.h"
00015
00016 #define MAX_GRAVITY_PULL 512
00017
00018
00019
00020
00021 void G_RunExPhys(gentity_t *ent, float gravity, float mass, float bounce, qboolean autoKill, int *g2Bolts, int numG2Bolts)
00022 {
00023 trace_t tr;
00024 vec3_t projectedOrigin;
00025 vec3_t vNorm;
00026 vec3_t ground;
00027 float velScaling = 0.1f;
00028 float vTotal = 0.0f;
00029
00030 assert(mass <= 1.0f && mass >= 0.01f);
00031
00032 if (gravity)
00033 {
00034 VectorCopy(ent->r.currentOrigin, ground);
00035 ground[2] -= 0.1f;
00036
00037 trap_Trace(&tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, ground, ent->s.number, ent->clipmask);
00038
00039 if (tr.fraction == 1.0f)
00040 {
00041 ent->s.groundEntityNum = ENTITYNUM_NONE;
00042 }
00043 else
00044 {
00045 ent->s.groundEntityNum = tr.entityNum;
00046 }
00047
00048 if (ent->s.groundEntityNum == ENTITYNUM_NONE)
00049 {
00050 ent->epGravFactor += gravity;
00051
00052 if (ent->epGravFactor > MAX_GRAVITY_PULL)
00053 {
00054 ent->epGravFactor = MAX_GRAVITY_PULL;
00055 }
00056
00057 ent->epVelocity[2] -= ent->epGravFactor;
00058 }
00059 else
00060 {
00061 ent->epGravFactor = 0;
00062 }
00063 }
00064
00065 if (!ent->epVelocity[0] && !ent->epVelocity[1] && !ent->epVelocity[2])
00066 {
00067 if (ent->touch)
00068 {
00069 trap_Trace(&tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, ent->r.currentOrigin, ent->s.number, ent->clipmask);
00070 if (tr.startsolid || tr.allsolid)
00071 {
00072 ent->touch(ent, &g_entities[tr.entityNum], &tr);
00073 }
00074 }
00075 return;
00076 }
00077
00078
00079 VectorMA(ent->r.currentOrigin, velScaling, ent->epVelocity, projectedOrigin);
00080
00081 VectorScale(ent->epVelocity, 1.0f-mass, ent->epVelocity);
00082
00083 VectorCopy(ent->epVelocity, vNorm);
00084 vTotal = VectorNormalize(vNorm);
00085
00086 if (vTotal < 1 && ent->s.groundEntityNum != ENTITYNUM_NONE)
00087 {
00088 VectorClear(ent->epVelocity);
00089 ent->epGravFactor = 0;
00090 trap_LinkEntity(ent);
00091 return;
00092 }
00093
00094 if (ent->ghoul2 && g2Bolts)
00095 {
00096 vec3_t tMins, tMaxs;
00097 vec3_t trajDif;
00098 vec3_t gbmAngles;
00099 vec3_t boneOrg;
00100 vec3_t projectedBoneOrg;
00101 vec3_t collisionRootPos;
00102 mdxaBone_t matrix;
00103 trace_t bestCollision;
00104 qboolean hasFirstCollision = qfalse;
00105 int i = 0;
00106
00107
00108
00109 VectorSet(tMins, -3, -3, -3);
00110 VectorSet(tMaxs, 3, 3, 3);
00111
00112 gbmAngles[PITCH] = gbmAngles[ROLL] = 0;
00113 gbmAngles[YAW] = ent->s.apos.trBase[YAW];
00114
00115
00116 VectorSubtract(ent->r.currentOrigin, projectedOrigin, trajDif);
00117
00118 while (i < numG2Bolts)
00119 {
00120
00121 trap_G2API_GetBoltMatrix(ent->ghoul2, 0, g2Bolts[i], &matrix, gbmAngles, ent->r.currentOrigin, level.time, NULL, ent->modelScale);
00122 BG_GiveMeVectorFromMatrix(&matrix, ORIGIN, boneOrg);
00123
00124
00125 VectorAdd(boneOrg, trajDif, projectedBoneOrg);
00126
00127 trap_Trace(&tr, boneOrg, tMins, tMaxs, projectedBoneOrg, ent->s.number, ent->clipmask);
00128
00129 if (tr.fraction != 1.0 || tr.startsolid || tr.allsolid)
00130 {
00131
00132 if (!hasFirstCollision)
00133 {
00134 bestCollision = tr;
00135 VectorCopy(boneOrg, collisionRootPos);
00136 hasFirstCollision = qtrue;
00137 }
00138 else
00139 {
00140 if (tr.allsolid && !bestCollision.allsolid)
00141 {
00142 bestCollision = tr;
00143 VectorCopy(boneOrg, collisionRootPos);
00144 }
00145 else if (tr.startsolid && !bestCollision.startsolid && !bestCollision.allsolid)
00146 {
00147 bestCollision = tr;
00148 VectorCopy(boneOrg, collisionRootPos);
00149 }
00150 else if (!bestCollision.startsolid && !bestCollision.allsolid &&
00151 tr.fraction < bestCollision.fraction)
00152 {
00153 bestCollision = tr;
00154 VectorCopy(boneOrg, collisionRootPos);
00155 }
00156 }
00157 }
00158
00159 i++;
00160 }
00161
00162 if (hasFirstCollision)
00163 {
00164
00165
00166 VectorSubtract(collisionRootPos, bestCollision.endpos, trajDif);
00167
00168 VectorAdd(ent->r.currentOrigin, trajDif, projectedOrigin);
00169 }
00170 }
00171
00172
00173
00174
00175 trap_Trace(&tr, ent->r.currentOrigin, ent->r.mins, ent->r.maxs, projectedOrigin, ent->s.number, ent->clipmask);
00176
00177 if (tr.startsolid || tr.allsolid)
00178 {
00179 #ifdef _DEBUG
00180 Com_Printf("ExPhys object in solid (%i)\n", ent->s.number);
00181 #endif
00182 if (autoKill)
00183 {
00184 ent->think = G_FreeEntity;
00185 ent->nextthink = level.time;
00186 }
00187 return;
00188 }
00189
00190
00191 G_SetOrigin(ent, tr.endpos);
00192 trap_LinkEntity(ent);
00193
00194 if (tr.fraction == 1.0f)
00195 {
00196 return;
00197 }
00198
00199 if (bounce)
00200 {
00201 vTotal *= bounce;
00202
00203 VectorScale(tr.plane.normal, vTotal, vNorm);
00204
00205 if (vNorm[2] > 0)
00206 {
00207 ent->epGravFactor -= vNorm[2]*(1.0f-mass);
00208 if (ent->epGravFactor < 0)
00209 {
00210 ent->epGravFactor = 0;
00211 }
00212 }
00213
00214
00215 if (tr.entityNum != ENTITYNUM_NONE && ent->touch)
00216 {
00217 ent->touch(ent, &g_entities[tr.entityNum], &tr);
00218 }
00219
00220 VectorAdd(ent->epVelocity, vNorm, ent->epVelocity);
00221 }
00222 else
00223 {
00224 ent->epVelocity[0] = 0;
00225 ent->epVelocity[1] = 0;
00226
00227 if (!gravity)
00228 {
00229 ent->epVelocity[2] = 0;
00230 }
00231 }
00232 }