00001
00002
00003 #include "ReVolt.h"
00004 #include "NewColl.h"
00005 #include "Wheel.h"
00006 #include "Geom.h"
00007 #ifndef _PSX
00008 #include "visibox.h"
00009 #endif
00010 #ifdef _PC
00011 #include "Draw.h"
00012 #endif
00013 #ifdef _N64
00014 #include "car.h"
00015 #include "drawobj.h"
00016 #endif
00017 #include "weapon.h"
00018
00019 SKIDMARK WHL_SkidMark[SKID_MAX_SKIDS];
00020 int WHL_SkidHead = 0;
00021 int WHL_NSkids = 0;
00022
00023
00025
00026
00027
00029
00030 SKIDMARK *AddSkid(SKIDMARK_START *skidStart, SKIDMARK_START *skidEnd, long rgb)
00031 {
00032 VEC right;
00033 SKIDMARK *skid;
00034 BOUNDING_BOX box;
00035
00036 skid = &WHL_SkidMark[WHL_SkidHead++];
00037 Wrap(WHL_SkidHead, 0, SKID_MAX_SKIDS);
00038 WHL_NSkids++;
00039 Limit(WHL_NSkids, 0, SKID_MAX_SKIDS);
00040
00041
00042 VecCrossVec(&skidStart->Dir, &skidStart->Normal, &right);
00043 VecPlusScalarVec(&skidStart->Pos, skidStart->Width, &right, &skid->Corner[0]);
00044 VecPlusScalarVec(&skidStart->Pos, -skidStart->Width, &right, &skid->Corner[1]);
00045
00046 VecCrossVec(&skidEnd->Dir, &skidEnd->Normal, &right);
00047 VecPlusScalarVec(&skidEnd->Pos, -skidEnd->Width, &right, &skid->Corner[2]);
00048 VecPlusScalarVec(&skidEnd->Pos, skidEnd->Width, &right, &skid->Corner[3]);
00049
00050
00051 #ifdef _PC
00052 skid->RGB = rgb;
00053 #endif
00054 #ifdef _N64
00055 skid->RGB = (rgb << 8) | (rgb & 0xFF);
00056 #endif
00057
00058
00059 box.Xmin = box.Xmax = skidStart->Pos.v[X];
00060 box.Ymin = box.Ymax = skidStart->Pos.v[Y];
00061 box.Zmin = box.Zmax = skidStart->Pos.v[Z];
00062
00063 #ifndef _PSX
00064 skid->VisiMask = SetObjectVisiMask(&box);
00065
00066
00067 FadeSkidMarks();
00068 #endif
00069
00070 return skid;
00071 }
00072
00073
00075
00076
00077
00079
00080 void MoveSkidEnd(SKIDMARK *skid, SKIDMARK_START *skidEnd)
00081 {
00082 VEC right;
00083
00084 VecCrossVec(&skidEnd->Dir, &skidEnd->Normal, &right);
00085 VecPlusScalarVec(&skidEnd->Pos, -skidEnd->Width, &right, &skid->Corner[2]);
00086 VecPlusScalarVec(&skidEnd->Pos, skidEnd->Width, &right, &skid->Corner[3]);
00087
00088 skid->Centre.v[X] = (skid->Corner[0].v[X] + skid->Corner[2].v[X]) / 2;
00089 skid->Centre.v[Y] = (skid->Corner[0].v[Y] + skid->Corner[2].v[Y]) / 2;
00090 skid->Centre.v[Z] = (skid->Corner[0].v[Z] + skid->Corner[2].v[Z]) / 2;
00091 }
00092
00093
00095
00096
00097
00099
00100 #ifndef _PSX
00101 void FadeSkidMarks()
00102 {
00103 int iSkid, currentSkid;
00104 int nFade;
00105 unsigned char r, g, b;
00106 SKIDMARK *skid;
00107
00108 if (WHL_NSkids < SKID_FADE_START) return;
00109
00110 nFade = WHL_NSkids - SKID_FADE_START;
00111
00112 currentSkid = WHL_SkidHead - WHL_NSkids + 1;
00113 for (iSkid = 0; iSkid < nFade; iSkid++)
00114 {
00115 Wrap(currentSkid, 0, SKID_MAX_SKIDS);
00116 skid = &WHL_SkidMark[currentSkid++];
00117
00118
00119 #ifdef _PC
00120 r = (unsigned char)((skid->RGB & RGB_RED_MASK) >> 16);
00121 g = (unsigned char)((skid->RGB & RGB_GREEN_MASK) >> 8);
00122 b = (unsigned char)(skid->RGB & RGB_BLUE_MASK);
00123
00124 if (r > SKID_FADE_FACTOR) {
00125 r -= SKID_FADE_FACTOR;
00126 } else {
00127 r = 0;
00128 }
00129 if (g > SKID_FADE_FACTOR) {
00130 g -= SKID_FADE_FACTOR;
00131 } else {
00132 g = 0;
00133 }
00134 if (b > SKID_FADE_FACTOR) {
00135 b -= SKID_FADE_FACTOR;
00136 } else {
00137 b = 0;
00138 }
00139
00140 skid->RGB = (r << 16) | (g << 8) | (b);
00141 #endif
00142 #ifdef _N64
00143 r = skid->RGB & 0xFF;
00144 if (r > SKID_FADE_FACTOR) {
00145 r -= SKID_FADE_FACTOR;
00146 } else {
00147 r = 0;
00148 }
00149 skid->RGB = (skid->RGB & 0xFFFFFF00) | (unsigned char)r;
00150 #endif
00151 }
00152 }
00153
00154
00155 #endif
00156
00158
00159
00160
00162
00163 void ClearSkids()
00164 {
00165 WHL_NSkids = 0;
00166 WHL_SkidHead = 0;
00167 }
00168
00170
00171
00172
00174
00175 void SetupWheel(WHEEL *wheel, WHEEL_INFO *wheelInfo)
00176 {
00177
00178 wheel->Status = 0;
00179 if (wheelInfo->IsPresent) {
00180 SetWheelPresent(wheel);
00181 }
00182 if (wheelInfo->IsTurnable) {
00183 SetWheelTurnable(wheel);
00184 }
00185 if (wheelInfo->IsPowered) {
00186 SetWheelPowered(wheel);
00187 }
00188
00189
00190 wheel->Mass = wheelInfo->Mass;
00191 wheel->InvMass = DivScalar(ONE, wheelInfo->Mass);
00192
00193
00194 wheel->Radius = wheelInfo->Radius;
00195
00196
00197 wheel->Inertia = MulScalar(wheelInfo->Mass, MulScalar(wheelInfo->Radius, wheelInfo->Radius)) / 2;
00198 wheel->InvInertia = DivScalar(ONE, wheel->Inertia);
00199
00200
00201 wheel->Gravity = wheelInfo->Gravity;
00202
00203
00204 wheel->Grip = wheelInfo->Grip;
00205 wheel->StaticFriction = wheelInfo->StaticFriction;
00206 wheel->KineticFriction = wheelInfo->KineticFriction;
00207 wheel->AxleFriction = wheelInfo->AxleFriction;
00208
00209
00210 wheel->SteerRatio = wheelInfo->SteerRatio;
00211
00212
00213 #ifndef _PSX
00214 wheel->EngineRatio = wheelInfo->EngineRatio;
00215 #else
00216 wheel->EngineRatio = DivScalar(wheelInfo->EngineRatio, wheel->Radius);
00217 #endif
00218
00219
00220
00221 SetBBox(&wheel->BBox,
00222 -wheelInfo->Radius, wheelInfo->Radius,
00223 -wheelInfo->Radius, wheelInfo->Radius,
00224 -wheelInfo->Radius, wheelInfo->Radius);
00225 wheel->BBRadius = wheelInfo->Radius;
00226
00227
00228 wheel->MaxPos = wheelInfo->MaxPos;
00229
00230
00231 wheel->SkidWidth = wheelInfo->SkidWidth;
00232
00233
00234 wheel->OilTime = OILY_WHEEL_TIME;
00235
00236
00237 wheel->SpinAngImp = MulScalar(MulScalar(wheel->Mass, TO_ACC(Real(15000))), wheel->Radius);
00238
00239 }
00240
00241
00243
00244
00245
00247
00248 void SetupSuspension(SPRING *spring, SPRING_INFO *info)
00249 {
00250 spring->Stiffness = info->Stiffness;
00251 spring->Damping = info->Damping;
00252 spring->Restitution = info->Restitution;
00253 }
00254
00255
00257
00258
00259
00260
00262
00263 REAL SpringDampedForce(SPRING *spring, REAL extension, REAL velocity)
00264 {
00265 REAL force;
00266
00267 force = - MulScalar(spring->Stiffness, extension) - MulScalar(spring->Damping, velocity);
00268
00269 if (Sign(force) == Sign(extension)) {
00270 force = ZERO;
00271 }
00272
00273 return force;
00274 }