00001 #include <windows.h>
00002 #include "shared.h"
00003 #include "bspline.h"
00004 #include "tll.h"
00005 #include "camera.h"
00006 #include "light.h"
00007 #include "mmgr.h"
00008
00009 extern LIGHT* light;
00010 extern int currentLight;
00011 extern CAMERA* camera;
00012 extern int currentCamera;
00013 extern float ApplicationStartTime;
00014 extern int numSplines;
00015 extern int visible;
00016 extern int cameraMode;
00017 extern int currentSpline;
00018 extern int lookAtPath;
00019 extern char SplineFileName[MAX_PATH];
00020 extern SPLINE* spline;
00021
00022 int SPLINE::Compare(const SPLINE& Spline)
00023 {
00024 if (linkPosition < Spline.linkPosition)
00025 return smaller;
00026 if (linkPosition > Spline.linkPosition)
00027 return bigger;
00028 else
00029 return same;
00030 }
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 void bspline(SPLINE* spline)
00044 {
00045 int t = spline->Degree;
00046 int n = spline->NumControl;
00047 int num_output = spline->NumPoints;
00048 VECTOR* control = spline->Control;
00049
00050 int* u;
00051
00052 int output_index;
00053 float increment,interval;
00054 VECTOR calcxyz;
00055
00056 u = new int[n+t+1];
00057 compute_intervals(u, n, t);
00058
00059 increment = (float) (n-t+2) / (num_output-1);
00060 interval = 0;
00061
00062 for (output_index = 0; output_index < num_output - 1; output_index++)
00063 {
00064 compute_point(u, n, t, interval, control, &calcxyz);
00065 spline->Output[output_index].x = calcxyz.x;
00066 spline->Output[output_index].y = calcxyz.y;
00067 spline->Output[output_index].z = calcxyz.z;
00068 interval = interval + increment;
00069 }
00070 spline->Output[num_output-1].x = control[n].x;
00071 spline->Output[num_output-1].y = control[n].y;
00072 spline->Output[num_output-1].z = control[n].z;
00073
00074 delete u;
00075 }
00076
00077
00078 VECTOR bsplinepoint(SPLINE* spline)
00079 {
00080 int t = spline->Degree;
00081 int n = spline->NumControl;
00082 VECTOR *control = spline->Control;
00083
00084
00085 int* u;
00086 float increment;
00087 VECTOR calcxyz;
00088
00089 u = new int[n+t+1];
00090 compute_intervals(u, n, t);
00091
00092 float CurrentTime = (float)GetTickCount() - ApplicationStartTime;
00093
00094 float TotalTime = spline->EndTime - spline->StartTime;
00095 float Position;
00096 float ActualTime;
00097
00098 if (CurrentTime <= spline->CopyOfStartTime)
00099 {
00100 calcxyz.x = control[0].x;
00101 calcxyz.y = control[0].y;
00102 calcxyz.z = control[0].z;
00103 delete u;
00104 return calcxyz;
00105 }
00106 else if (CurrentTime >= spline->CopyOfEndTime)
00107 {
00108 if (spline->Repeat)
00109 {
00110 spline->CopyOfStartTime = CurrentTime;
00111 spline->CopyOfEndTime = CurrentTime + TotalTime;
00112 }
00113 calcxyz.x = control[n].x;
00114 calcxyz.y = control[n].y;
00115 calcxyz.z = control[n].z;
00116 delete u;
00117 return calcxyz;
00118 }
00119 else
00120 {
00121 ActualTime = CurrentTime - spline->CopyOfStartTime;
00122 Position = 1 / (TotalTime / ActualTime);
00123 }
00124 increment = (n - t + 2) * Position;
00125
00126 compute_point(u, n, t, increment, control, &calcxyz);
00127
00128 delete u;
00129
00130 return calcxyz;
00131 }
00132
00133 float blend(int k, int t, int *u, float v)
00134 {
00135 float value;
00136
00137 if (t == 1)
00138 {
00139 if ((u[k] <= v) && (v < u[k+1]))
00140 value = 1;
00141 else
00142 value = 0;
00143 }
00144 else
00145 {
00146 if ((u[k+t-1] == u[k]) && (u[k+t] == u[k+1]))
00147 value = 0;
00148 else
00149 if (u[k+t-1] == u[k])
00150 value = (u[k+t] - v) / (u[k+t] - u[k+1]) * blend(k+1, t-1, u, v);
00151 else
00152 if (u[k+t]==u[k+1])
00153 value = (v - u[k]) / (u[k+t-1] - u[k]) * blend(k, t-1, u, v);
00154 else
00155 value = (v - u[k]) / (u[k+t-1] - u[k]) * blend(k, t-1, u, v) + (u[k+t] - v) / (u[k+t] - u[k+1]) * blend(k+1, t-1, u, v);
00156 }
00157 return value;
00158 }
00159
00160 void compute_intervals(int *u, int n, int t)
00161 {
00162 int j;
00163
00164 for (j = 0; j <= n+t; j++)
00165 {
00166 if (j<t)
00167 u[j]=0;
00168 else
00169 if ((t <= j) && (j <= n))
00170 u[j] = j-t+1;
00171 else
00172 if (j > n)
00173 u[j] = n-t+2;
00174 }
00175 }
00176
00177 void compute_point(int *u, int n, int t, float v, VECTOR *control, VECTOR *output)
00178 {
00179 int k;
00180 float temp;
00181
00182
00183 output->x=0;
00184 output->y=0;
00185 output->z=0;
00186
00187 for (k = 0; k <= n; k++)
00188 {
00189 temp = blend(k,t,u,v);
00190 output->x = output->x + (control[k]).x * temp;
00191 output->y = output->y + (control[k]).y * temp;
00192 output->z = output->z + (control[k]).z * temp;
00193 }
00194 }
00195
00196 void DrawSplines(LinkedList<SPLINE>& SplineList)
00197 {
00198 GLUquadricObj * sphere = gluNewQuadric();
00199
00200 for (int loop = 0; loop < numSplines; loop++)
00201 {
00202 spline = SplineList.Get(loop);
00203
00204 if (visible)
00205 {
00206
00207 glDisable(GL_TEXTURE_2D);
00208 float mat_ambient[] = {spline->Red, spline->Green, spline->Blue, 1.0 };
00209 float mat_diffuse[] = {spline->Red, spline->Green, spline->Blue, 1.0 };
00210 float mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
00211 glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
00212 glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
00213 glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
00214 for (int i=0; i <= spline->NumControl; i++)
00215 {
00216 glPushMatrix();
00217 glTranslatef(spline->Control[i].x, spline->Control[i].y, spline->Control[i].z);
00218 gluSphere(sphere,0.4,10,10);
00219 glPopMatrix();
00220 }
00221 glEnable(GL_TEXTURE_2D);
00222
00223
00224 VECTOR Output = bsplinepoint(spline);
00225
00226
00227 glPointSize(5.0);
00228 glColor3f(0.0, 1.0 ,0.0);
00229 glDisable(GL_TEXTURE_2D);
00230 glDisable(GL_LIGHTING);
00231 glPushMatrix();
00232 glBegin(GL_POINTS);
00233 glVertex3f(Output.x, Output.y, Output.z);
00234 glEnd();
00235 glPopMatrix();
00236 glEnable(GL_TEXTURE_2D);
00237 glEnable(GL_LIGHTING);
00238
00239 if (cameraMode > 0 && currentSpline == loop)
00240 {
00241 VECTOR LookAt;
00242 if (cameraMode == 2 && (currentSpline != lookAtPath))
00243 {
00244 SPLINE* spline2 = SplineList.Get(lookAtPath);
00245 LookAt = bsplinepoint(spline2);
00246 }
00247 camera[currentCamera].Position.x = Output.x;
00248 camera[currentCamera].Position.y = Output.y;
00249 camera[currentCamera].Position.z = Output.z;
00250 MATRIX mat;
00251 glPushMatrix();
00252 glLoadIdentity();
00253 if (cameraMode == 2 && (currentSpline != lookAtPath))
00254 gluLookAt(Output.x, Output.y, Output.z, LookAt.x, LookAt.y, LookAt.z, 0, 1, 0);
00255 else
00256
00257 gluLookAt(Output.x, Output.y, Output.z, light[currentLight].Position.x, light[currentLight].Position.y, light[currentLight].Position.z, 0, 1, 0);
00258 glGetFloatv(GL_MODELVIEW_MATRIX, mat.Element);
00259 glPopMatrix();
00260
00261 float mat2[4][4];
00262 mat2[0][0] = mat.Element[0];
00263 mat2[0][1] = mat.Element[1];
00264 mat2[0][2] = mat.Element[2];
00265 mat2[0][3] = mat.Element[3];
00266 mat2[1][0] = mat.Element[4];
00267 mat2[1][1] = mat.Element[5];
00268 mat2[1][2] = mat.Element[6];
00269 mat2[1][3] = mat.Element[7];
00270 mat2[2][0] = mat.Element[8];
00271 mat2[2][1] = mat.Element[9];
00272 mat2[2][2] = mat.Element[10];
00273 mat2[2][3] = mat.Element[11];
00274 mat2[3][0] = mat.Element[12];
00275 mat2[3][1] = mat.Element[13];
00276 mat2[3][2] = mat.Element[14];
00277 mat2[3][3] = mat.Element[15];
00278
00279 camera[currentCamera].Orientation.MatrixToQuat(mat2);
00280 }
00281
00282 bspline(spline);
00283
00284
00285 glColor3f(spline->Red, spline->Green, spline->Blue);
00286 glDisable(GL_TEXTURE_2D);
00287 glDisable(GL_LIGHTING);
00288 glPushMatrix();
00289 glBegin(GL_LINE_STRIP);
00290 for (int i=0; i < spline->NumPoints; i++)
00291 {
00292 glVertex3fv(&spline->Output[i].x);
00293 }
00294 glEnd();
00295 glPopMatrix();
00296 glEnable(GL_TEXTURE_2D);
00297 glEnable(GL_LIGHTING);
00298 }
00299
00300 else if (cameraMode > 0)
00301 {
00302 VECTOR Output = bsplinepoint(spline);
00303
00304 VECTOR LookAt;
00305 if (cameraMode == 2 && currentSpline != lookAtPath)
00306 {
00307 SPLINE* spline2 = SplineList.Get(lookAtPath);
00308 LookAt = bsplinepoint(spline2);
00309 }
00310 camera[currentCamera].Position.x = Output.x;
00311 camera[currentCamera].Position.y = Output.y;
00312 camera[currentCamera].Position.z = Output.z;
00313 MATRIX mat;
00314 glPushMatrix();
00315 glLoadIdentity();
00316 if (cameraMode == 2 && currentSpline != lookAtPath)
00317 gluLookAt(Output.x, Output.y, Output.z, LookAt.x, LookAt.y, LookAt.z, 0, 1, 0);
00318 else
00319 gluLookAt(Output.x, Output.y, Output.z, light[currentLight].Position.x, light[currentLight].Position.y, light[currentLight].Position.z, 0, 1, 0);
00320 glGetFloatv(GL_MODELVIEW_MATRIX, mat.Element);
00321 glPopMatrix();
00322
00323 float mat2[4][4];
00324 mat2[0][0] = mat.Element[0];
00325 mat2[0][1] = mat.Element[1];
00326 mat2[0][2] = mat.Element[2];
00327 mat2[0][3] = mat.Element[3];
00328 mat2[1][0] = mat.Element[4];
00329 mat2[1][1] = mat.Element[5];
00330 mat2[1][2] = mat.Element[6];
00331 mat2[1][3] = mat.Element[7];
00332 mat2[2][0] = mat.Element[8];
00333 mat2[2][1] = mat.Element[9];
00334 mat2[2][2] = mat.Element[10];
00335 mat2[2][3] = mat.Element[11];
00336 mat2[3][0] = mat.Element[12];
00337 mat2[3][1] = mat.Element[13];
00338 mat2[3][2] = mat.Element[14];
00339 mat2[3][3] = mat.Element[15];
00340
00341 camera[currentCamera].Orientation.MatrixToQuat(mat2);
00342 }
00343 }
00344 }