collision.c
上传用户:zhbcxc
上传日期:2022-08-09
资源大小:577k
文件大小:27k
源码类别:

OpenGL

开发平台:

Visual C++

  1. #include <stdlib.h>
  2. #include <GL/glut.h>
  3. #include <stdio.h>
  4. #include <math.h>
  5. #include <sys/types.h>
  6. #include <time.h>
  7. // 光源定义
  8. GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0};  
  9. GLfloat light_position[] = {10.0, 10.0, 30.0, 1.0};  
  10. int win_id;
  11. static GLuint texName;
  12. // SETUP DATASTRUCTURE FOR OBJECTS
  13. #define MAXGUYS 300
  14. #define MAXOBJS 80
  15. int NUMOBJS;
  16. int TEXENABLE;
  17. int DEBUGENABLE;
  18. int frame;
  19. //  点的数据结构
  20. struct point 
  21. {
  22. float x; 
  23. float y; 
  24. float z;
  25. };
  26. //  有关弹性碰撞的数据结构
  27. struct spring 
  28. {
  29. struct point* p1; 
  30. struct point* p2;
  31. struct point* v1; 
  32. struct point* v2;
  33. float* m1; 
  34. float* m2;
  35. float length; 
  36. float stiff; 
  37. float damp; 
  38. float breaklen;
  39. };
  40. //  有关碰撞线的数据结构
  41. struct cdline 
  42. {
  43. struct point* p1; 
  44. struct point* p2; 
  45. struct point* v1; 
  46. struct point* v2;
  47. struct point* vi1; 
  48. struct point* vi2;
  49. struct point min; 
  50. struct point max;
  51. float* mass;
  52. float fric;
  53. };
  54. //  对象的面的数据结构
  55. struct face 
  56. {
  57. struct point* p1; 
  58. struct point* p2;
  59. struct point* p3;
  60. struct point* v1; 
  61. struct point* v2; 
  62. struct point* v3;
  63. struct point* vi1; 
  64. struct point* vi2; 
  65. struct point* vi3; 
  66.     float* m1; 
  67. float* m2; 
  68. float* m3;
  69.     struct point min; 
  70. struct point max;
  71.     float fric; 
  72. struct point nor;
  73. };
  74. //  有关对象的数据结构
  75. struct object 
  76. {
  77. int NUMPTS;
  78. int NUMSPRINGS;
  79. int NUMFACES;
  80. int NUMCDLINES;
  81. float mass[MAXGUYS];
  82. float r,g,b,a;
  83. struct point points[MAXGUYS];
  84. struct point vel[MAXGUYS];
  85. struct point velinc[MAXGUYS];
  86. struct spring springs[MAXGUYS];
  87. struct cdline cdlines[MAXGUYS];
  88. struct face faces[MAXGUYS];
  89. struct point max;                             // 对象的边界盒
  90. struct point min;
  91. int texture;
  92. int NUMTEXPTS;
  93. int texmap[64][64];
  94. struct point texpoints[MAXGUYS]; 
  95. struct face texfaces[MAXGUYS];
  96. };
  97. struct object objects[MAXOBJS];
  98. // 定义一些底层函数
  99. #define sqa(A) (A*fabs(A))
  100. #define length(A) sqrt(A.x*A.x+A.y*A.y+A.z*A.z)
  101. #define dot(A,B) (A.x*B.x+A.y*B.y+A.z*B.z)
  102. #define cross(D,A,B) D.x=A.y*B.z-A.z*B.y; D.y=A.z*B.x-A.x*B.z; D.z=A.x*B.y-A.y*B.x
  103. #define vsub(D,A,B) D.x=A.x-B.x; D.y=A.y-B.y; D.z=A.z-B.z
  104. #define fmaxinc(X,Y) X.x=(fabs(X.x)>fabs(Y.x)) ? X.x:Y.x; X.y=(fabs(X.y)>fabs(Y.y)) ? X.y:Y.y; X.z=(fabs(X.z)>fabs(Y.z)) ? X.z:Y.z
  105. // 物理定义,步长和重力加速度
  106. int STEP;
  107. float GRAVITY;
  108. // Spring variables
  109. struct point sdistvec, relvel, sforcevec;
  110. float springforce;
  111. void drawcross(float x, float y, float z)
  112. {
  113.   glBegin(GL_LINES);
  114.     glColor4f(.3,.3,.3,1.0);
  115.     glNormal3f(0.0,1.0,0.0);
  116.     glVertex3f(x+1.0,y    ,z    );
  117.     glVertex3f(x-1.0,y    ,z    );
  118.     glVertex3f(x    ,y+1.0,z    );
  119.     glVertex3f(x    ,y-1.0,z    );
  120.     glVertex3f(x    ,y    ,z+1.0);
  121.     glVertex3f(x    ,y    ,z-1.0);
  122.   glEnd();
  123. }
  124. void display(void)
  125. {
  126. int x,y,i,j,step;
  127. float len,u,t1,t2,t3,distdiff,relmass,SFORCE,FFORCE,frico;
  128. struct point tmp1,tmp2, cpt, n1, n2, n3, avgfacevel, vdiff, vdiff_norm, vdiff_notnorm;
  129. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  130. // 弹性碰撞计算
  131. for(step=0;step<STEP;step++)
  132. {
  133. for(i=0;i<NUMOBJS;i++) // 遍历每个对象
  134. {
  135. // 进行弹性碰撞
  136. for(x=0;x<objects[i].NUMSPRINGS;x++)
  137. {
  138. // 相对位置
  139. vsub(sdistvec,(*objects[i].springs[x].p1),(*objects[i].springs[x].p2));
  140. // 相对速度
  141. vsub(relvel,(*objects[i].springs[x].v1),(*objects[i].springs[x].v2));
  142. distdiff =    length(sdistvec)-objects[i].springs[x].length;
  143. springforce = sqa(distdiff)*objects[i].springs[x].stiff;
  144. springforce+= objects[i].springs[x].damp*dot(relvel,sdistvec); 
  145. // 如果距离超过一定范围,则解除弹性力
  146. if(fabs(distdiff)>objects[i].springs[x].breaklen) 
  147. {
  148. objects[i].springs[x].stiff=0.0; 
  149. objects[i].springs[x].damp=0.0;
  150. }
  151. sforcevec.x = sdistvec.x*springforce;
  152. sforcevec.y = sdistvec.y*springforce;
  153. sforcevec.z = sdistvec.z*springforce;
  154. relmass = (*objects[i].springs[x].m1)/
  155. ( (*objects[i].springs[x].m1) + (*objects[i].springs[x].m2) );
  156. // 应用弹性力 
  157. (*objects[i].springs[x].v1).x -= (1.0-relmass)*sforcevec.x;
  158. (*objects[i].springs[x].v1).y -= (1.0-relmass)*sforcevec.y;
  159. (*objects[i].springs[x].v1).z -= (1.0-relmass)*sforcevec.z;
  160. (*objects[i].springs[x].v2).x += relmass*sforcevec.x;
  161. (*objects[i].springs[x].v2).y += relmass*sforcevec.y;
  162. (*objects[i].springs[x].v2).z += relmass*sforcevec.z;
  163. }
  164. // 更新对象的各点
  165. for(x=0;x<objects[i].NUMPTS;x++)
  166. {
  167. // 应用重力加速度
  168. objects[i].vel[x].y-=GRAVITY;
  169. if(objects[i].points[x].y<-15.0) 
  170. {
  171. objects[i].points[x].y=-15.0; 
  172. objects[i].vel[x].y=0.0;
  173. objects[i].vel[x].x/=1.1; 
  174. objects[i].vel[x].z/=1.1;
  175. }
  176. }
  177. }
  178. // 碰撞初始化
  179. for(i=0;i<NUMOBJS;i++)
  180. for(x=0;x<objects[i].NUMFACES;x++)
  181. {
  182. // 计算边界盒
  183. objects[i].faces[x].max.x = (*objects[i].faces[x].p1).x;
  184. objects[i].faces[x].max.x = (objects[i].faces[x].max.x>(*objects[i].faces[x].p2).x) ?
  185.                          objects[i].faces[x].max.x:(*objects[i].faces[x].p2).x;
  186. objects[i].faces[x].max.x = (objects[i].faces[x].max.x>(*objects[i].faces[x].p3).x) ?
  187.                                              objects[i].faces[x].max.x:(*objects[i].faces[x].p3).x;
  188. objects[i].faces[x].max.y = (*objects[i].faces[x].p1).y;
  189. objects[i].faces[x].max.y = (objects[i].faces[x].max.y>(*objects[i].faces[x].p2).y) ?
  190.                                              objects[i].faces[x].max.y:(*objects[i].faces[x].p2).y;
  191. objects[i].faces[x].max.y = (objects[i].faces[x].max.y>(*objects[i].faces[x].p3).y) ?
  192.                                              objects[i].faces[x].max.y:(*objects[i].faces[x].p3).y;
  193. objects[i].faces[x].max.z = (*objects[i].faces[x].p1).z;
  194. objects[i].faces[x].max.z = (objects[i].faces[x].max.z>(*objects[i].faces[x].p2).z) ?
  195.                                              objects[i].faces[x].max.z:(*objects[i].faces[x].p2).z;
  196. objects[i].faces[x].max.z = (objects[i].faces[x].max.z>(*objects[i].faces[x].p3).z) ?
  197.                                              objects[i].faces[x].max.z:(*objects[i].faces[x].p3).z;
  198. objects[i].faces[x].min.x = (*objects[i].faces[x].p1).x;
  199. objects[i].faces[x].min.x = (objects[i].faces[x].min.x<(*objects[i].faces[x].p2).x) ?
  200.                                              objects[i].faces[x].min.x:(*objects[i].faces[x].p2).x;
  201. objects[i].faces[x].min.x = (objects[i].faces[x].min.x<(*objects[i].faces[x].p3).x) ?
  202.                                              objects[i].faces[x].min.x:(*objects[i].faces[x].p3).x;
  203. objects[i].faces[x].min.y = (*objects[i].faces[x].p1).y;
  204. objects[i].faces[x].min.y = (objects[i].faces[x].min.y<(*objects[i].faces[x].p2).y) ?
  205.                                              objects[i].faces[x].min.y:(*objects[i].faces[x].p2).y;
  206. objects[i].faces[x].min.y = (objects[i].faces[x].min.y<(*objects[i].faces[x].p3).y) ?
  207.                                              objects[i].faces[x].min.y:(*objects[i].faces[x].p3).y;
  208. objects[i].faces[x].min.z = (*objects[i].faces[x].p1).z;
  209. objects[i].faces[x].min.z = (objects[i].faces[x].min.z<(*objects[i].faces[x].p2).z) ?
  210.                                              objects[i].faces[x].min.z:(*objects[i].faces[x].p2).z;
  211. objects[i].faces[x].min.z = (objects[i].faces[x].min.z<(*objects[i].faces[x].p3).z) ?
  212.                                              objects[i].faces[x].min.z:(*objects[i].faces[x].p3).z;
  213. // 计算法向量
  214. vsub(tmp1,(*objects[i].faces[x].p1),(*objects[i].faces[x].p2));
  215. vsub(tmp2,(*objects[i].faces[x].p2),(*objects[i].faces[x].p3));
  216. cross(objects[i].faces[x].nor,tmp1,tmp2);
  217. len=length(objects[i].faces[x].nor);
  218. objects[i].faces[x].nor.x/=len;
  219. objects[i].faces[x].nor.y/=len;
  220. objects[i].faces[x].nor.z/=len;
  221. }
  222. for(i=0;i<NUMOBJS;i++)
  223. for(x=0;x<objects[i].NUMCDLINES;x++) 
  224. {
  225. // 获得碰撞检测边界线
  226. objects[i].cdlines[x].max.x = (*objects[i].cdlines[x].p1).x;
  227. objects[i].cdlines[x].max.x = (objects[i].cdlines[x].max.x>(*objects[i].cdlines[x].p2).x) ?
  228.                                                   objects[i].cdlines[x].max.x:(*objects[i].cdlines[x].p2).x;
  229. objects[i].cdlines[x].max.y = (*objects[i].cdlines[x].p1).y;
  230. objects[i].cdlines[x].max.y = (objects[i].cdlines[x].max.y>(*objects[i].cdlines[x].p2).y) ?
  231.                                                   objects[i].cdlines[x].max.y:(*objects[i].cdlines[x].p2).y;
  232. objects[i].cdlines[x].max.z = (*objects[i].cdlines[x].p1).z;
  233. objects[i].cdlines[x].max.z = (objects[i].cdlines[x].max.z>(*objects[i].cdlines[x].p2).z) ?
  234.                                                   objects[i].cdlines[x].max.z:(*objects[i].cdlines[x].p2).z;
  235. objects[i].cdlines[x].min.x = (*objects[i].cdlines[x].p1).x;
  236. objects[i].cdlines[x].min.x = (objects[i].cdlines[x].min.x<(*objects[i].cdlines[x].p2).x) ?
  237.                                                   objects[i].cdlines[x].min.x:(*objects[i].cdlines[x].p2).x;
  238. objects[i].cdlines[x].min.y = (*objects[i].cdlines[x].p1).y;
  239. objects[i].cdlines[x].min.y = (objects[i].cdlines[x].min.y<(*objects[i].cdlines[x].p2).y) ?
  240.                                                   objects[i].cdlines[x].min.y:(*objects[i].cdlines[x].p2).y;
  241. objects[i].cdlines[x].min.z = (*objects[i].cdlines[x].p1).z;
  242. objects[i].cdlines[x].min.z = (objects[i].cdlines[x].min.z<(*objects[i].cdlines[x].p2).z) ?
  243.                                                   objects[i].cdlines[x].min.z:(*objects[i].cdlines[x].p2).z;
  244. }
  245. for(i=0;i<NUMOBJS;i++)
  246. for(x=0;x<objects[i].NUMPTS;x++)
  247. {
  248. // 计算对象边界盒
  249. objects[i].max.x=-HUGE; 
  250. objects[i].max.y=-HUGE; 
  251. objects[i].max.z=-HUGE;
  252. objects[i].min.x= HUGE; 
  253. objects[i].min.y= HUGE; 
  254. objects[i].min.z= HUGE;
  255. for(x=0;x<objects[i].NUMPTS;x++)
  256. {
  257. objects[i].max.x=(objects[i].max.x<objects[i].points[x].x) ? objects[i].points[x].x:objects[i].max.x;
  258. objects[i].max.y=(objects[i].max.y<objects[i].points[x].y) ? objects[i].points[x].y:objects[i].max.y;
  259. objects[i].max.z=(objects[i].max.z<objects[i].points[x].z) ? objects[i].points[x].z:objects[i].max.z;
  260. objects[i].min.x=(objects[i].min.x>objects[i].points[x].x) ? objects[i].points[x].x:objects[i].min.x;
  261. objects[i].min.y=(objects[i].min.y>objects[i].points[x].y) ? objects[i].points[x].y:objects[i].min.y;
  262. objects[i].min.z=(objects[i].min.z>objects[i].points[x].z) ? objects[i].points[x].z:objects[i].min.z;
  263. }
  264. }
  265. // 碰撞检测开始
  266. for(i=0;i<NUMOBJS;i++)   // 对任意两个物体都进行计算
  267. for(j=0;j<NUMOBJS;j++) 
  268. {
  269. //  同一物体,继续下一个
  270. if(i==j) continue;
  271. // 没有碰撞,继续下一个
  272. if( (objects[i].max.x-objects[j].min.x)*(objects[i].min.x-objects[j].max.x)>0.0 ||
  273. (objects[i].max.y-objects[j].min.y)*(objects[i].min.y-objects[j].max.y)>0.0 ||
  274. (objects[i].max.z-objects[j].min.z)*(objects[i].min.z-objects[j].max.z)>0.0 ) 
  275. continue;
  276. // 碰撞处理
  277. for(x=0;x<objects[i].NUMFACES;x++)
  278. for(y=0;y<objects[j].NUMCDLINES;y++)
  279. {
  280. // 面/碰撞线边界盒检测
  281. if( (objects[i].faces[x].max.x-objects[j].cdlines[y].min.x)*
  282. (objects[i].faces[x].min.x-objects[j].cdlines[y].max.x)>0.0 || 
  283. (objects[i].faces[x].max.y-objects[j].cdlines[y].min.y)*
  284. (objects[i].faces[x].min.y-objects[j].cdlines[y].max.y)>0.0 || 
  285. (objects[i].faces[x].max.z-objects[j].cdlines[y].min.z)*
  286. (objects[i].faces[x].min.z-objects[j].cdlines[y].max.z)>0.0 ) 
  287. continue;
  288. vsub(tmp1,(*objects[j].cdlines[y].p2),(*objects[j].cdlines[y].p1));
  289. if(dot(tmp1,objects[i].faces[x].nor)>0.0) 
  290. continue;
  291. // 碰撞线穿过面
  292. vsub(tmp1,(*objects[i].faces[x].p1),  (*objects[j].cdlines[y].p1) );
  293. vsub(tmp2,(*objects[j].cdlines[y].p2),(*objects[j].cdlines[y].p1) );
  294. u   = dot(objects[i].faces[x].nor,tmp1)/
  295. dot(objects[i].faces[x].nor,tmp2);
  296. if(u<0.0 || u>1.0) 
  297. continue;  
  298. cpt.x = (*objects[j].cdlines[y].p1).x + u*tmp2.x;
  299. cpt.y = (*objects[j].cdlines[y].p1).y + u*tmp2.y;
  300. cpt.z = (*objects[j].cdlines[y].p1).z + u*tmp2.z;
  301. // 找出边界法向量
  302. vsub(tmp1,(*objects[i].faces[x].p2),(*objects[i].faces[x].p1) );
  303. cross(n1,tmp1,objects[i].faces[x].nor);
  304. vsub(tmp1,(*objects[i].faces[x].p3),(*objects[i].faces[x].p2) );
  305. cross(n2,tmp1,objects[i].faces[x].nor);
  306. vsub(tmp1,(*objects[i].faces[x].p1),(*objects[i].faces[x].p3) );
  307. cross(n3,tmp1,objects[i].faces[x].nor);
  308. // 检测三角形边界
  309. vsub(tmp1,(*objects[i].faces[x].p1),cpt);
  310. t1=dot(tmp1,n1);
  311. vsub(tmp1,(*objects[i].faces[x].p2),cpt);
  312. t2=dot(tmp1,n2);
  313. vsub(tmp1,(*objects[i].faces[x].p3),cpt);
  314. t3=dot(tmp1,n3);
  315. if(t1<0.0||t2<0.0||t3<0.0) 
  316. u=-999.0;
  317. if(u<0.0) continue; 
  318. if(DEBUGENABLE) drawcross(cpt.x,cpt.y,cpt.z);  // 绘制碰撞点
  319. // 计算面的平均速度
  320. avgfacevel.x = ((*objects[i].faces[x].v1).x+
  321. (*objects[i].faces[x].v2).x+(*objects[i].faces[x].v3).x)*.3333333333333333333333333333;
  322. avgfacevel.y = ((*objects[i].faces[x].v1).y+
  323. (*objects[i].faces[x].v2).y+(*objects[i].faces[x].v3).y)*.3333333333333333333333333333;
  324. avgfacevel.z = ((*objects[i].faces[x].v1).z+
  325. (*objects[i].faces[x].v2).z+(*objects[i].faces[x].v3).z)*.3333333333333333333333333333;
  326. vsub(vdiff,avgfacevel,(*objects[j].cdlines[y].v2));
  327. FFORCE=(*objects[j].cdlines[y].mass)/((*objects[j].cdlines[y].mass)+
  328. (*objects[i].faces[x].m1)+(*objects[i].faces[x].m2)+(*objects[i].faces[x].m3));
  329. SFORCE=1.0-FFORCE;
  330. vdiff_norm.x = dot(vdiff, objects[i].faces[x].nor) * objects[i].faces[x].nor.x;
  331. vdiff_norm.y = dot(vdiff, objects[i].faces[x].nor) * objects[i].faces[x].nor.y;
  332. vdiff_norm.z = dot(vdiff, objects[i].faces[x].nor) * objects[i].faces[x].nor.z;
  333. vsub(vdiff_notnorm,vdiff,vdiff_norm);
  334. // 产生摩擦系数
  335. frico = objects[i].faces[x].fric+objects[j].cdlines[y].fric;  
  336. // 解决碰撞
  337. if(dot(vdiff,objects[i].faces[x].nor)>0.0) 
  338. {
  339. fmaxinc((*objects[j].cdlines[y].vi2),SFORCE*vdiff_norm);
  340. fmaxinc((*objects[i].faces[x].vi1),  -FFORCE*vdiff_norm);
  341. fmaxinc((*objects[i].faces[x].vi2),  -FFORCE*vdiff_norm);
  342. fmaxinc((*objects[i].faces[x].vi3),  -FFORCE*vdiff_norm);
  343. fmaxinc((*objects[j].cdlines[y].vi2),SFORCE*frico*vdiff_notnorm);
  344. fmaxinc((*objects[i].faces[x].vi1),  -FFORCE*frico*vdiff_notnorm);
  345. fmaxinc((*objects[i].faces[x].vi2),  -FFORCE*frico*vdiff_notnorm);
  346. fmaxinc((*objects[i].faces[x].vi3),  -FFORCE*frico*vdiff_notnorm);
  347. }
  348. }
  349. }
  350. for(i=0;i<NUMOBJS;i++)
  351. for(x=0;x<objects[i].NUMPTS;x++)
  352. {
  353. // 获取速度
  354. objects[i].vel[x].x+=objects[i].velinc[x].x;
  355. objects[i].vel[x].y+=objects[i].velinc[x].y;
  356. objects[i].vel[x].z+=objects[i].velinc[x].z;
  357. objects[i].velinc[x].x=0.0;
  358. objects[i].velinc[x].y=0.0;
  359. objects[i].velinc[x].z=0.0;
  360. // 更新点的位置
  361. objects[i].points[x].x+=objects[i].vel[x].x;
  362. objects[i].points[x].y+=objects[i].vel[x].y;
  363. objects[i].points[x].z+=objects[i].vel[x].z;
  364. }
  365. }  
  366. // 场景显示
  367. for(i=0;i<NUMOBJS;i++)
  368. {
  369. if(DEBUGENABLE)
  370. {
  371. glColor4f(0.4,1.0,0.4,1.0);
  372. //  绘制个定点与中心连线
  373. for(x=0;x<objects[i].NUMCDLINES;x++)
  374. {
  375. glBegin(GL_LINES);
  376. glNormal3f(0.0,1.0,0.0);
  377. glVertex3f((*objects[i].cdlines[x].p1).x,(*objects[i].cdlines[x].p1).y,
  378. (*objects[i].cdlines[x].p1).z);
  379. glVertex3f((*objects[i].cdlines[x].p2).x,(*objects[i].cdlines[x].p2).y,
  380. (*objects[i].cdlines[x].p2).z);
  381. glEnd();
  382. }
  383. //  绘制对象的各个面
  384. for(x=0;x<objects[i].NUMFACES;x++)
  385. {
  386. glBegin(GL_LINES);
  387. glNormal3f(0.0,1.0,0.0);
  388. glColor4f(1.0,0.4,0.4,1.0);
  389. glVertex3f((*objects[i].faces[x].p1).x,(*objects[i].faces[x].p1).y,
  390. (*objects[i].faces[x].p1).z);
  391. glVertex3f((*objects[i].faces[x].p2).x,(*objects[i].faces[x].p2).y,
  392.      (*objects[i].faces[x].p2).z);
  393. glVertex3f((*objects[i].faces[x].p2).x,(*objects[i].faces[x].p2).y,
  394.  (*objects[i].faces[x].p2).z);
  395. glVertex3f((*objects[i].faces[x].p3).x,(*objects[i].faces[x].p3).y,
  396. (*objects[i].faces[x].p3).z);
  397. glVertex3f((*objects[i].faces[x].p3).x,(*objects[i].faces[x].p3).y,
  398. (*objects[i].faces[x].p3).z);
  399. glVertex3f((*objects[i].faces[x].p1).x,(*objects[i].faces[x].p1).y,
  400. (*objects[i].faces[x].p1).z);
  401. glNormal3f(0.0,1.0,0.0);
  402. glColor4f(0.4,0.4,1.0,1.0);
  403. glVertex3f((*objects[i].faces[x].p1).x,(*objects[i].faces[x].p1).y,
  404. (*objects[i].faces[x].p1).z);
  405. glVertex3f((*objects[i].faces[x].p1).x+(objects[i].faces[x].nor).x,
  406. (*objects[i].faces[x].p1).y+(objects[i].faces[x].nor).y,
  407. (*objects[i].faces[x].p1).z+(objects[i].faces[x].nor).z);
  408. glVertex3f((*objects[i].faces[x].p2).x,(*objects[i].faces[x].p2).y,
  409. (*objects[i].faces[x].p2).z);
  410. glVertex3f((*objects[i].faces[x].p2).x+(objects[i].faces[x].nor).x,
  411. (*objects[i].faces[x].p2).y+(objects[i].faces[x].nor).y,
  412. (*objects[i].faces[x].p2).z+(objects[i].faces[x].nor).z);
  413. glVertex3f((*objects[i].faces[x].p3).x,(*objects[i].faces[x].p3).y,
  414. (*objects[i].faces[x].p3).z);
  415. glVertex3f((*objects[i].faces[x].p3).x+(objects[i].faces[x].nor).x,
  416. (*objects[i].faces[x].p3).y+(objects[i].faces[x].nor).y,
  417. (*objects[i].faces[x].p3).z+(objects[i].faces[x].nor).z);
  418. glEnd();
  419. }
  420. else // 标准显示
  421. {
  422. glColor4f(objects[i].r,objects[i].g,objects[i].b,objects[i].a);
  423. // 使用纹理
  424. if(objects[i].texture && TEXENABLE)   
  425. {
  426. glEnable(GL_TEXTURE_2D);
  427. glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  428. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, objects[i].texmap);
  429. glBindTexture(GL_TEXTURE_2D, texName);
  430. for(x=0;x<objects[i].NUMFACES;x++)
  431. {
  432. glBegin(GL_TRIANGLES); 
  433. glNormal3f(objects[i].faces[x].nor.x,objects[i].faces[x].nor.y,
  434. objects[i].faces[x].nor.z);
  435. glTexCoord2f((*objects[i].texfaces[x].p1).x,(*objects[i].texfaces[x].p1).y);
  436. glVertex3f((*objects[i].faces[x].p1).x,(*objects[i].faces[x].p1).y,
  437. (*objects[i].faces[x].p1).z);
  438. glTexCoord2f((*objects[i].texfaces[x].p2).x,(*objects[i].texfaces[x].p2).y);
  439. glVertex3f((*objects[i].faces[x].p2).x,(*objects[i].faces[x].p2).y,
  440. (*objects[i].faces[x].p2).z);
  441. glTexCoord2f((*objects[i].texfaces[x].p3).x,(*objects[i].texfaces[x].p3).y);
  442. glVertex3f((*objects[i].faces[x].p3).x,(*objects[i].faces[x].p3).y,
  443. (*objects[i].faces[x].p3).z);
  444. glEnd();
  445. }
  446. glDisable(GL_TEXTURE_2D);
  447. }
  448. // 不使用纹理
  449. else
  450. {
  451. for(x=0;x<objects[i].NUMFACES;x++)
  452. {
  453. glBegin(GL_TRIANGLES);
  454. glNormal3f(objects[i].faces[x].nor.x,objects[i].faces[x].nor.y,
  455. objects[i].faces[x].nor.z);
  456. glVertex3f((*objects[i].faces[x].p1).x,(*objects[i].faces[x].p1).y,
  457. (*objects[i].faces[x].p1).z);
  458. glVertex3f((*objects[i].faces[x].p2).x,(*objects[i].faces[x].p2).y,
  459. (*objects[i].faces[x].p2).z);
  460. glVertex3f((*objects[i].faces[x].p3).x,(*objects[i].faces[x].p3).y,
  461. (*objects[i].faces[x].p3).z);
  462. glEnd();
  463. }
  464. }
  465. }
  466. // 绘制地板
  467. glColor4f(.2,.4,.2,1.0);
  468. glNormal3f(0.0,1.0,0.0);
  469. glBegin(GL_TRIANGLES);
  470. glTexCoord2f(0.0,1.0); glVertex3f(-20.0,-15.4,20.0);
  471. glTexCoord2f(1.0,1.0); glVertex3f(20.0,-15.4,20.0);
  472. glTexCoord2f(0.0,0.0); glVertex3f(-20.0,-15.4,-20.0);
  473. glTexCoord2f(1.0,0.0); glVertex3f(20.0,-15.4,-20.0);
  474. glTexCoord2f(0.0,0.0); glVertex3f(-20.0,-15.4,-20.0);
  475. glTexCoord2f(1.0,1.0); glVertex3f(20.0,-15.4,20.0);
  476. glEnd();
  477. glutSwapBuffers();
  478. }
  479. void init()
  480. {
  481. char rval,gval,bval;
  482. int x,i;
  483. int windbackwards;
  484. FILE *file;
  485. int p1,p2,p3,o1,o2;
  486. char filename[MAXOBJS][100];
  487. char modfile[MAXOBJS][100];
  488. char texfile[MAXOBJS][100];
  489. struct point offset[MAXOBJS];
  490. float scale;
  491. struct point tmp;
  492. float damp, fric, breaklen;
  493. frame=0;
  494. TEXENABLE=1;
  495. DEBUGENABLE=0;
  496. if((file=fopen("config.txt","r"))==NULL) 
  497. {
  498. printf("Can't open config.txtn"); 
  499. exit(-1);
  500. }
  501. fscanf(file,"%d %f",&STEP,&GRAVITY); //  读出步数,重力加速度
  502. fscanf(file,"%d",&NUMOBJS); //  读出对象的数量
  503. for(x=0;x<NUMOBJS;x++) 
  504. //  读出对象的名称和对象的初始位置
  505. fscanf(file,"%s %f %f %f",&filename[x][0],&offset[x].x, &offset[x].y,&offset[x].z);
  506. fclose(file);
  507. for(i=0;i<NUMOBJS;i++)
  508. {
  509. sprintf(modfile[i],"models/%s.mod",filename[i]);
  510. sprintf(texfile[i],"models/%s.tga",filename[i]);
  511. printf("Attempting to open model file %sn",modfile[i]);
  512. if((file=fopen(modfile[i],"r"))==NULL) {printf("Can't open modeln"); exit(-1);}
  513. //  读出对象的缩放系数
  514. fscanf(file,"%f",&scale);
  515. //  读出对象的RGBA颜色值 
  516. fscanf(file,"%f %f %f %f",&objects[i].r,&objects[i].g,&objects[i].b,&objects[i].a);
  517. fscanf(file,"%d",&objects[i].NUMPTS);
  518. fscanf(file,"%d",&objects[i].NUMSPRINGS);
  519. fscanf(file,"%d",&objects[i].NUMFACES);
  520. fscanf(file,"%d",&objects[i].NUMCDLINES);
  521. fscanf(file,"%f",&damp);
  522. fscanf(file,"%f",&fric);
  523. fscanf(file,"%f",&breaklen);
  524. fscanf(file,"%d %d",&objects[i].texture,&windbackwards);
  525. for(x=0;x<objects[i].NUMPTS;x++) 
  526. {
  527. fscanf(file,"%f",&objects[i].mass[x]);
  528. }
  529. for(x=0;x<objects[i].NUMPTS;x++)
  530. {
  531. fscanf(file,"%f %f %f",&objects[i].points[x].x,&objects[i].points[x].y,&objects[i].points[x].z);
  532. objects[i].points[x].x*=scale;
  533. objects[i].points[x].y*=scale;
  534. objects[i].points[x].z*=scale;
  535. }
  536. for(x=0;x<objects[i].NUMPTS;x++)
  537. {
  538. objects[i].points[x].x+=offset[i].x;
  539. objects[i].points[x].y+=offset[i].y;
  540. objects[i].points[x].z+=offset[i].z;
  541. }
  542. for(x=0;x<objects[i].NUMPTS;x++)
  543. fscanf(file,"%f %f %f",&objects[i].vel[x].x,&objects[i].vel[x].y,&objects[i].vel[x].z);
  544. for(x=0;x<objects[i].NUMSPRINGS;x++)
  545. {
  546. fscanf(file,"%d %d %d %d %f",&o1,&p1,&o2,&p2,&objects[i].springs[x].stiff);
  547. if(o1<0) o1=i; if(o2<0) o2=i;
  548. objects[i].springs[x].damp=damp;
  549. objects[i].springs[x].p1=&objects[o1].points[p1];
  550. objects[i].springs[x].p2=&objects[o2].points[p2];
  551. vsub(tmp,(*objects[i].springs[x].p1),(*objects[i].springs[x].p2));
  552. objects[i].springs[x].length=length(tmp);
  553. objects[i].springs[x].v1=&objects[o1].vel[p1];
  554. objects[i].springs[x].v2=&objects[o2].vel[p2];
  555. objects[i].springs[x].m1=&objects[o1].mass[p1];
  556. objects[i].springs[x].m2=&objects[o2].mass[p2];
  557. objects[i].springs[x].breaklen=breaklen;
  558. }
  559. for(x=0;x<objects[i].NUMFACES;x++)
  560. {
  561. if(windbackwards==0)
  562. fscanf(file,"%d %d %d",&p1,&p2,&p3);
  563. else
  564. fscanf(file,"%d %d %d",&p2,&p1,&p3);
  565. objects[i].faces[x].fric=fric;
  566. objects[i].faces[x].p1 =&objects[i].points[p1];
  567. objects[i].faces[x].p2 =&objects[i].points[p2];
  568. objects[i].faces[x].p3 =&objects[i].points[p3];
  569. objects[i].faces[x].v1 =&objects[i].vel[p1];
  570. objects[i].faces[x].v2 =&objects[i].vel[p2];
  571. objects[i].faces[x].v3 =&objects[i].vel[p3];
  572. objects[i].faces[x].vi1=&objects[i].velinc[p1];
  573. objects[i].faces[x].vi2=&objects[i].velinc[p2];
  574. objects[i].faces[x].vi3=&objects[i].velinc[p3];
  575. objects[i].faces[x].m1=&objects[i].mass[p1];
  576. objects[i].faces[x].m2=&objects[i].mass[p2];
  577. objects[i].faces[x].m3=&objects[i].mass[p3];
  578. }
  579. for(x=0;x<objects[i].NUMCDLINES;x++)
  580. {
  581. fscanf(file,"%d %d",&p1,&p2);
  582. objects[i].cdlines[x].p1=&objects[i].points[p1];
  583. objects[i].cdlines[x].p2=&objects[i].points[p2];
  584. objects[i].cdlines[x].v1=&objects[i].vel[p1];
  585. objects[i].cdlines[x].v2=&objects[i].vel[p2];
  586. objects[i].cdlines[x].vi1=&objects[i].velinc[p1];
  587. objects[i].cdlines[x].vi2=&objects[i].velinc[p2];
  588. objects[i].cdlines[x].fric=fric;
  589. objects[i].cdlines[x].mass=&objects[i].mass[p2];
  590. }
  591. if(objects[i].texture==1)
  592. {
  593. fscanf(file,"%d",&objects[i].NUMTEXPTS);
  594. for(x=0;x<objects[i].NUMTEXPTS;x++)
  595. fscanf(file,"%f %f",&objects[i].texpoints[x].x,&objects[i].texpoints[x].y);
  596. for(x=0;x<objects[i].NUMTEXPTS;x++)
  597. {
  598. objects[i].texpoints[x].x/=256.0; 
  599. objects[i].texpoints[x].y/=256.0; 
  600. }
  601. for(x=0;x<objects[i].NUMFACES;x++)
  602. {
  603. if(windbackwards==0)
  604. fscanf(file,"%d %d %d",&p1,&p2,&p3);
  605. else
  606. fscanf(file,"%d %d %d",&p2,&p1,&p3);
  607. objects[i].texfaces[x].p1=&objects[i].texpoints[p1];
  608. objects[i].texfaces[x].p2=&objects[i].texpoints[p2];
  609. objects[i].texfaces[x].p3=&objects[i].texpoints[p3];
  610. }
  611. }
  612. fclose(file);
  613. if(objects[i].texture==1)
  614. {
  615. if((file=fopen(texfile[i],"rb"))==NULL) 
  616. {
  617. printf("Can't open texture n"); 
  618. exit(-1);
  619. }
  620. for(x=0;x<60;x++) fscanf(file,"%c",&rval); 
  621. for(x=0;x<64*64;x++)
  622. {
  623. fscanf(file,"%c",&bval);
  624. fscanf(file,"%c",&gval);
  625. fscanf(file,"%c",&rval);
  626. objects[i].texmap[0][x]=0xFF000000|(0xFF&bval)<<16|(0xFF&gval)<<8|(0xFF&rval); // ABGR
  627. }
  628. }
  629. }
  630. void glinit()
  631. {
  632. glGenTextures(1,&texName);
  633. glBindTexture(GL_TEXTURE_2D, texName);
  634. //  设置纹理参数
  635. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  636. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  637. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  638. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  639. // 使用光照
  640. glLightfv(GL_LIGHT0, GL_SPECULAR, light_diffuse);
  641. glLightfv(GL_LIGHT0, GL_POSITION, light_position);
  642. glEnable(GL_LIGHT0);
  643. glEnable(GL_LIGHTING);
  644. glEnable(GL_CULL_FACE);
  645. glCullFace(GL_BACK);
  646. glEnable(GL_COLOR_MATERIAL); 
  647. //  使用深度测试
  648. glEnable(GL_DEPTH_TEST);
  649. glMatrixMode(GL_PROJECTION);
  650. gluPerspective( 60.0, 1.0, 1.0, 10000.0);
  651. glMatrixMode(GL_MODELVIEW);
  652. gluLookAt(10.0, 10.0, 30.0,   0.0, -10.0, 0.0,  0.0, 1.0, 0.); 
  653. }
  654. void keyboard(unsigned char key, int x, int y)
  655. {
  656. switch (key) 
  657. {
  658. case 27:  // 按下'ESC'键,退出程序
  659. {
  660. glutDestroyWindow(win_id);
  661. exit(0); 
  662. }
  663. break;
  664.     case 'r':   //  场景复位
  665. init();
  666. break;
  667.         case 't': //  是否使用纹理开关
  668. if(TEXENABLE) 
  669. TEXENABLE=0;
  670. else 
  671. TEXENABLE=1;
  672. break;
  673.         case 'd':  //  是否以线框模式绘制开关
  674.             if(DEBUGENABLE) 
  675. DEBUGENABLE=0;
  676.             else 
  677. DEBUGENABLE=1;
  678.             break;
  679.     case '5':
  680. {
  681. for(x=0;x<objects[0].NUMPTS;x++) 
  682. objects[0].vel[x].x+=.004;
  683. }
  684.     break;
  685.     case '8':
  686. {
  687. for(x=0;x<objects[0].NUMPTS;x++) 
  688. objects[0].vel[x].x-=.004;
  689. }
  690.     break;
  691.     case '4':
  692. {
  693. for(x=0;x<objects[0].NUMPTS;x++) 
  694. objects[0].vel[x].z+=.004;
  695. }
  696.     break;
  697.     case '6':
  698. {
  699. for(x=0;x<objects[0].NUMPTS;x++)
  700. objects[0].vel[x].z-=.004;
  701. }
  702.     break;
  703.     case '1': // 按下'1'键,向左旋转场景
  704. gluLookAt(0.0, 0.0, 0.01,  
  705.     0.001, 0.0, 0.0,      
  706. 0.0, 1.0, 0.0);      
  707.             break;
  708.     case '3': // 按下'3'键,向右旋转场景
  709. gluLookAt(0.0, 0.0, 0.01,  
  710.     -0.001, 0.0, 0.0,      
  711.     0.0, 1.0, 0.0);      
  712. break;
  713. }
  714. }
  715. void redisp(void) {glutPostRedisplay();}
  716. int main(int argc, char **argv)
  717. {
  718.   printf("nn碰撞检测 ver 1.0nn -使用键盘交互-n r:tt restart simulationn t:tt toggle texturingn d:tt toggle debug moden 4,5,6,8:t move first objectn ESC:tt halt simulationnn");
  719.   glutInit(&argc, argv);
  720.   glutInitWindowPosition(0,0);
  721.   glutInitWindowSize(400,300);
  722.   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
  723.   win_id = glutCreateWindow("碰撞检测");
  724.   glutKeyboardFunc(keyboard);
  725.   glutDisplayFunc(display);
  726.   glutIdleFunc(redisp);
  727.   init();
  728.   glinit();
  729.   glutMainLoop();
  730.   return 0;
  731. }
  732.