main.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. #define TPE_LOG puts
  2. #include "tinyphysicsengine.h"
  3. #include <SDL2/SDL.h>
  4. #include <math.h>
  5. #define S3L_RESOLUTION_X 640
  6. #define S3L_RESOLUTION_Y 480
  7. #define S3L_PIXEL_FUNCTION drawPixel
  8. #define S3L_Z_BUFFER 1
  9. #include "small3dlib.h"
  10. #define PIXELS_SIZE (S3L_RESOLUTION_X * S3L_RESOLUTION_Y * 4)
  11. #define FPS 30
  12. #define MSPF (1000 / (FPS))
  13. TPE_World world;
  14. TPE_Body bodies[128];
  15. S3L_Unit cubeVertices[] = { S3L_CUBE_VERTICES(1600) };
  16. S3L_Index cubeTriangles[] = { S3L_CUBE_TRIANGLES };
  17. S3L_Model3D cube;
  18. uint8_t pixels[PIXELS_SIZE];
  19. uint8_t red = 100;
  20. TPE_Vec3 environmentDistance(TPE_Vec3 p)
  21. {
  22. /*
  23. TODO: This function should have another parameter "distance", if the closest
  24. point should be further away than this distance, it won't matter and in that
  25. case the function may return any arbitrary point further away than "distance",
  26. this can speed up detections in vast empty areas.
  27. */
  28. #define WWW 3000
  29. if (p.x < -WWW || p.x > WWW || p.y < -WWW || p.y > WWW ||
  30. p.z < -WWW || p.z > WWW)
  31. return p;
  32. int xx = p.x * p.x;
  33. int yy = p.y * p.y;
  34. int zz = p.z * p.z;
  35. if (xx > yy)
  36. {
  37. if (xx > zz)
  38. p.x = p.x > 0 ? WWW : -WWW;
  39. else
  40. p.z = p.z > 0 ? WWW : -WWW;
  41. }
  42. else
  43. {
  44. if (yy > zz)
  45. p.y = p.y > 0 ? WWW : -WWW;
  46. else
  47. p.z = p.z > 0 ? WWW : -WWW;
  48. }
  49. #undef WWW
  50. return p;
  51. }
  52. void drawPixel(S3L_PixelInfo *p)
  53. {
  54. uint32_t index = (p->y * S3L_RESOLUTION_X + p->x) * 4;
  55. pixels[index + 1] = p->triangleIndex * 16;
  56. pixels[index + 2] = 255 - p->triangleIndex * 16;
  57. pixels[index + 3] = red;
  58. }
  59. void draw2DPoint(int x, int y, int r, int g, int b)
  60. {
  61. if (x < 1 || x > S3L_RESOLUTION_X - 3 ||
  62. y < 1 || y > S3L_RESOLUTION_Y - 3)
  63. return;
  64. uint32_t index = ((y - 1) * S3L_RESOLUTION_X + x) * 4;
  65. #define d pixels[index] = 0; pixels[index + 1] = b; pixels[index + 2] = g; pixels[index + 3] = r;
  66. d
  67. index += S3L_RESOLUTION_X * 4 - 4;
  68. d
  69. index += 4;
  70. d
  71. index += 4;
  72. d
  73. index += S3L_RESOLUTION_X * 4 - 4;
  74. d
  75. #undef d
  76. }
  77. void drawLine(int x1, int y1, int x2, int y2, int r, int g, int b)
  78. {
  79. #define STEPS 20
  80. float dx = (x2 - x1) / ((float) STEPS);
  81. float dy = (y2 - y1) / ((float) STEPS);
  82. for (int i = 0; i < STEPS; ++i)
  83. draw2DPoint(x1 + dx * i, y1 + dy * i,r,g,b);
  84. #undef STEPS
  85. }
  86. S3L_Scene sphereScene;
  87. void draw3DLine(int x1, int y1, int z1, int x2, int y2, int z2)
  88. {
  89. S3L_Vec4 p1, p2, r1, r2;
  90. S3L_vec4Set(&p1,x1,y1,z1,0);
  91. S3L_vec4Set(&p2,x2,y2,z2,0);
  92. S3L_project3DPointToScreen(p1,sphereScene.camera,&r1);
  93. S3L_project3DPointToScreen(p2,sphereScene.camera,&r2);
  94. if (r1.z > 0 && r2.z > 0)
  95. drawLine(r1.x,r1.y,r2.x,r2.y,200,100,200);
  96. }
  97. void drawSphere(S3L_Unit x, S3L_Unit y, S3L_Unit z, S3L_Unit r)
  98. {
  99. sphereScene.models[0].transform.translation.x = x;
  100. sphereScene.models[0].transform.translation.y = y;
  101. sphereScene.models[0].transform.translation.z = z;
  102. sphereScene.models[0].transform.scale.x = r;
  103. sphereScene.models[0].transform.scale.y = r;
  104. sphereScene.models[0].transform.scale.z = r;
  105. S3L_drawScene(sphereScene);
  106. }
  107. void drawBody(TPE_Body *body, uint8_t color)
  108. {
  109. red = color;
  110. for (int i = 0; i < body->jointCount; ++i)
  111. drawSphere(
  112. body->joints[i].position.x,
  113. body->joints[i].position.y,
  114. body->joints[i].position.z,
  115. TPE_JOINT_SIZE(body->joints[i]));
  116. for (int i = 0; i < body->connectionCount; ++i)
  117. {
  118. S3L_Vec4 p1, p2, r1, r2;
  119. S3L_vec4Set(&p1,
  120. body->joints[body->connections[i].joint1].position.x,
  121. body->joints[body->connections[i].joint1].position.y,
  122. body->joints[body->connections[i].joint1].position.z,0);
  123. S3L_vec4Set(&p2,
  124. body->joints[body->connections[i].joint2].position.x,
  125. body->joints[body->connections[i].joint2].position.y,
  126. body->joints[body->connections[i].joint2].position.z,0);
  127. S3L_project3DPointToScreen(p1,sphereScene.camera,&r1);
  128. S3L_project3DPointToScreen(p2,sphereScene.camera,&r2);
  129. if (r1.z > 0 && r2.z > 0)
  130. drawLine(r1.x,r1.y,r2.x,r2.y,100,200,300);
  131. }
  132. }
  133. void drawEnv(TPE_Vec3 p, int stepLength, int steps)
  134. {
  135. TPE_Vec3 p2 = p;
  136. for (int k = 0; k < steps; ++k)
  137. {
  138. p2.y = p.y;
  139. for (int j = 0; j < steps; ++j)
  140. {
  141. p2.x = p.x;
  142. for (int i = 0; i < steps; ++i)
  143. {
  144. TPE_Vec3 p3 = environmentDistance(p2);
  145. S3L_Vec4 p4, p5;
  146. p4.x = p3.x;
  147. p4.y = p3.y;
  148. p4.z = p3.z;
  149. S3L_project3DPointToScreen(p4,sphereScene.camera,&p5);
  150. draw2DPoint(p5.x,p5.y,100,200,255);
  151. p2.x += stepLength;
  152. }
  153. p2.y += stepLength;
  154. }
  155. p2.z += stepLength;
  156. }
  157. }
  158. #define SPHERE_VERTEX_COUNT 42
  159. const S3L_Unit sphereVertices[SPHERE_VERTEX_COUNT * 3] = {
  160. 0, -512, 0, // 0
  161. 370, -228, -269, // 3
  162. -141, -228, -435, // 6
  163. -457, -228, 0, // 9
  164. -141, -228, 435, // 12
  165. 370, -228, 269, // 15
  166. 141, 228, -435, // 18
  167. -370, 228, -269, // 21
  168. -370, 228, 269, // 24
  169. 141, 228, 435, // 27
  170. 457, 228, 0, // 30
  171. 0, 512, 0, // 33
  172. -83, -435, -255, // 36
  173. 217, -435, -158, // 39
  174. 134, -269, -414, // 42
  175. 435, -269, 0, // 45
  176. 217, -435, 158, // 48
  177. -269, -435, 0, // 51
  178. -352, -269, -255, // 54
  179. -83, -435, 255, // 57
  180. -352, -269, 255, // 60
  181. 134, -269, 414, // 63
  182. 486, 0, -158, // 66
  183. 486, 0, 158, // 69
  184. 0, 0, -512, // 72
  185. 300, 0, -414, // 75
  186. -486, 0, -158, // 78
  187. -300, 0, -414, // 81
  188. -300, 0, 414, // 84
  189. -486, 0, 158, // 87
  190. 300, 0, 414, // 90
  191. 0, 0, 512, // 93
  192. 352, 269, -255, // 96
  193. -134, 269, -414, // 99
  194. -435, 269, 0, // 102
  195. -134, 269, 414, // 105
  196. 352, 269, 255, // 108
  197. 83, 435, -255, // 111
  198. 269, 435, 0, // 114
  199. -217, 435, -158, // 117
  200. -217, 435, 158, // 120
  201. 83, 435, 255 // 123
  202. }; // sphereVertices
  203. #define SPHERE_TRIANGLE_COUNT 80
  204. const S3L_Index sphereTriangleIndices[SPHERE_TRIANGLE_COUNT * 3] = {
  205. 0, 13, 12, // 0
  206. 1, 13, 15, // 3
  207. 0, 12, 17, // 6
  208. 0, 17, 19, // 9
  209. 0, 19, 16, // 12
  210. 1, 15, 22, // 15
  211. 2, 14, 24, // 18
  212. 3, 18, 26, // 21
  213. 4, 20, 28, // 24
  214. 5, 21, 30, // 27
  215. 1, 22, 25, // 30
  216. 2, 24, 27, // 33
  217. 3, 26, 29, // 36
  218. 4, 28, 31, // 39
  219. 5, 30, 23, // 42
  220. 6, 32, 37, // 45
  221. 7, 33, 39, // 48
  222. 8, 34, 40, // 51
  223. 9, 35, 41, // 54
  224. 10, 36, 38, // 57
  225. 38, 41, 11, // 60
  226. 38, 36, 41, // 63
  227. 36, 9, 41, // 66
  228. 41, 40, 11, // 69
  229. 41, 35, 40, // 72
  230. 35, 8, 40, // 75
  231. 40, 39, 11, // 78
  232. 40, 34, 39, // 81
  233. 34, 7, 39, // 84
  234. 39, 37, 11, // 87
  235. 39, 33, 37, // 90
  236. 33, 6, 37, // 93
  237. 37, 38, 11, // 96
  238. 37, 32, 38, // 99
  239. 32, 10, 38, // 102
  240. 23, 36, 10, // 105
  241. 23, 30, 36, // 108
  242. 30, 9, 36, // 111
  243. 31, 35, 9, // 114
  244. 31, 28, 35, // 117
  245. 28, 8, 35, // 120
  246. 29, 34, 8, // 123
  247. 29, 26, 34, // 126
  248. 26, 7, 34, // 129
  249. 27, 33, 7, // 132
  250. 27, 24, 33, // 135
  251. 24, 6, 33, // 138
  252. 25, 32, 6, // 141
  253. 25, 22, 32, // 144
  254. 22, 10, 32, // 147
  255. 30, 31, 9, // 150
  256. 30, 21, 31, // 153
  257. 21, 4, 31, // 156
  258. 28, 29, 8, // 159
  259. 28, 20, 29, // 162
  260. 20, 3, 29, // 165
  261. 26, 27, 7, // 168
  262. 26, 18, 27, // 171
  263. 18, 2, 27, // 174
  264. 24, 25, 6, // 177
  265. 24, 14, 25, // 180
  266. 14, 1, 25, // 183
  267. 22, 23, 10, // 186
  268. 22, 15, 23, // 189
  269. 15, 5, 23, // 192
  270. 16, 21, 5, // 195
  271. 16, 19, 21, // 198
  272. 19, 4, 21, // 201
  273. 19, 20, 4, // 204
  274. 19, 17, 20, // 207
  275. 17, 3, 20, // 210
  276. 17, 18, 3, // 213
  277. 17, 12, 18, // 216
  278. 12, 2, 18, // 219
  279. 15, 16, 5, // 222
  280. 15, 13, 16, // 225
  281. 13, 0, 16, // 228
  282. 12, 14, 2, // 231
  283. 12, 13, 14, // 234
  284. 13, 1, 14 // 237
  285. }; // sphereTriangleIndices
  286. int main(void)
  287. {
  288. SDL_Window *window = SDL_CreateWindow("test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, S3L_RESOLUTION_X, S3L_RESOLUTION_Y, SDL_WINDOW_SHOWN);
  289. SDL_Renderer *renderer = SDL_CreateRenderer(window,-1,0);
  290. SDL_Texture *textureSDL = SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGBX8888, SDL_TEXTUREACCESS_STATIC, S3L_RESOLUTION_X, S3L_RESOLUTION_Y);
  291. SDL_Surface *screenSurface = SDL_GetWindowSurface(window);
  292. SDL_Event event;
  293. int running = 1;
  294. S3L_Model3D sphereModel;
  295. S3L_model3DInit(sphereVertices,SPHERE_VERTEX_COUNT,sphereTriangleIndices,
  296. SPHERE_TRIANGLE_COUNT,&sphereModel);
  297. S3L_model3DInit(cubeVertices,S3L_CUBE_VERTEX_COUNT,cubeTriangles,
  298. S3L_CUBE_TRIANGLE_COUNT,&cube);
  299. S3L_sceneInit(&sphereModel,1,&sphereScene);
  300. sphereScene.camera.transform.translation.z = -3000;
  301. int frame = 0;
  302. TPE_Joint joints[100];
  303. TPE_Connection connections[100];
  304. switch (3)
  305. {
  306. case 0:
  307. TPE_make2Line(joints,connections,1500,512);
  308. TPE_bodyInit(bodies,joints,2,connections,1,100);
  309. break;
  310. case 1:
  311. TPE_makeBox(joints,connections,1300,2000,3000,512);
  312. TPE_bodyInit(bodies,joints,8,connections,16,100);
  313. break;
  314. case 2:
  315. TPE_makeCenterRect(joints,connections,1300,1000,512);
  316. TPE_bodyInit(bodies,joints,5,connections,8,100);
  317. break;
  318. case 3:
  319. TPE_makeCenterBox(joints,connections,1000,1000,1000,512);
  320. joints[8].sizeDivided *= 3;
  321. joints[8].sizeDivided /= 2;
  322. TPE_bodyInit(bodies,joints,9,connections,18,100);
  323. break;
  324. case 4:
  325. TPE_makeTriangle(joints,connections,2000,512);
  326. TPE_bodyInit(bodies,joints,3,connections,3,100);
  327. break;
  328. default: break;
  329. }
  330. //TPE_makeBox(joints + 20,connections + 20,300,128);
  331. //TPE_bodyInit(bodies,joints,1,connections,0,100);
  332. //bodies[0].flags |= TPE_BODY_FLAG_SOFT;
  333. TPE_worldInit(&world,bodies,1,environmentDistance);
  334. TPE_bodyMove(world.bodies,TPE_vec3(-800,-300,0));
  335. TPE_bodyMove(&world.bodies[1],TPE_vec3(400,100,1));
  336. TPE_bodyStop(world.bodies);
  337. TPE_bodyStop(world.bodies + 1);
  338. //TPE_bodyRotate(world.bodies,TPE_vec3(0,0,200));
  339. //-------
  340. int time;
  341. while (running)
  342. {
  343. time = SDL_GetTicks();
  344. for (uint32_t i = 0; i < PIXELS_SIZE; ++i)
  345. pixels[i] = 0;
  346. S3L_newFrame();
  347. TPE_Unit m = TPE_bodyAverageSpeed(world.bodies); //TPE_bodyNetSpeed(world.bodies);
  348. printf("%d\n",m);
  349. //TPE_bodiesResolveCollision(world.bodies,world.bodies + 1);
  350. for (int i = 0; i < world.bodyCount; ++i)
  351. {
  352. TPE_bodyAccelerate(world.bodies + i,
  353. TPE_vec3(0,-6,0));
  354. }
  355. TPE_worldStep(&world);
  356. m /= 16;
  357. while (SDL_PollEvent(&event))
  358. {
  359. if (event.type == SDL_QUIT)
  360. running = 0;
  361. else if (event.type == SDL_KEYDOWN)
  362. {
  363. if (event.key.keysym.scancode == SDL_SCANCODE_Q || event.key.keysym.scancode == SDL_SCANCODE_ESCAPE)
  364. running = 0;
  365. }
  366. }
  367. const uint8_t *state = SDL_GetKeyboardState(NULL);
  368. S3L_Vec4 camF, camR;
  369. #define SHIFT_STEP 50
  370. #define ROT_STEP 5
  371. S3L_rotationToDirections(sphereScene.camera.transform.rotation,SHIFT_STEP,&camF,&camR,0);
  372. TPE_Vec3 forw = TPE_vec3Minus(
  373. bodies[0].joints[2].position,
  374. bodies[0].joints[0].position);
  375. TPE_Vec3 righ = TPE_vec3Minus(
  376. bodies[0].joints[0].position,
  377. bodies[0].joints[1].position);
  378. TPE_Vec3 rrrr = TPE_orientationFromVecs(forw,righ);
  379. cube.transform.rotation.x = rrrr.x;
  380. cube.transform.rotation.y = rrrr.y;
  381. cube.transform.rotation.z = rrrr.z;
  382. TPE_Vec3 ppp = TPE_bodyGetCenter(&bodies[0]);
  383. cube.transform.translation.x = ppp.x;
  384. cube.transform.translation.y = ppp.y;
  385. cube.transform.translation.z = ppp.z;
  386. drawEnv(TPE_vec3(-100,-100,-100),100,5);
  387. for (int i = 0; i < world.bodyCount; ++i)
  388. drawBody(&(world.bodies[i]),100 * i);
  389. sphereScene.models = &cube;
  390. S3L_newFrame();
  391. S3L_drawScene(sphereScene);
  392. sphereScene.models = &sphereModel;
  393. draw3DLine(0,0,0,forw.x,forw.y,forw.z);
  394. draw3DLine(0,0,0,righ.x,righ.y,righ.z);
  395. SDL_UpdateTexture(textureSDL,NULL,pixels,S3L_RESOLUTION_X * sizeof(uint32_t));
  396. if (state[SDL_SCANCODE_LSHIFT])
  397. {
  398. if (state[SDL_SCANCODE_UP])
  399. S3L_vec3Add(&sphereScene.camera.transform.translation,camF);
  400. else if (state[SDL_SCANCODE_DOWN])
  401. S3L_vec3Sub(&sphereScene.camera.transform.translation,camF);
  402. else if (state[SDL_SCANCODE_LEFT])
  403. S3L_vec3Sub(&sphereScene.camera.transform.translation,camR);
  404. else if (state[SDL_SCANCODE_RIGHT])
  405. S3L_vec3Add(&sphereScene.camera.transform.translation,camR);
  406. }
  407. else
  408. {
  409. if (state[SDL_SCANCODE_UP])
  410. sphereScene.camera.transform.rotation.x += ROT_STEP;
  411. else if (state[SDL_SCANCODE_DOWN])
  412. sphereScene.camera.transform.rotation.x -= ROT_STEP;
  413. else if (state[SDL_SCANCODE_LEFT])
  414. sphereScene.camera.transform.rotation.y += ROT_STEP;
  415. else if (state[SDL_SCANCODE_RIGHT])
  416. sphereScene.camera.transform.rotation.y -= ROT_STEP;
  417. else if (state[SDL_SCANCODE_K])
  418. sphereScene.camera.transform.rotation.z += ROT_STEP;
  419. else if (state[SDL_SCANCODE_L])
  420. sphereScene.camera.transform.rotation.z -= ROT_STEP;
  421. }
  422. if (state[SDL_SCANCODE_M])
  423. {
  424. TPE_bodyWake(world.bodies);
  425. TPE_bodySpin(bodies,TPE_vec3(50,40,100));
  426. TPE_bodyAccelerate(bodies,TPE_vec3(
  427. 500,
  428. 500,
  429. 30));
  430. }
  431. #define SHIFT_STEP 50
  432. if (state[SDL_SCANCODE_P])
  433. sphereScene.camera.transform.translation.y += SHIFT_STEP;
  434. else if (state[SDL_SCANCODE_O])
  435. sphereScene.camera.transform.translation.y -= SHIFT_STEP;
  436. #undef SHIFT_STEP
  437. SDL_RenderClear(renderer);
  438. SDL_RenderCopy(renderer,textureSDL,NULL,NULL);
  439. SDL_RenderPresent(renderer);
  440. time = time + MSPF - SDL_GetTicks();
  441. if (time > 1)
  442. usleep(time * 1000);
  443. frame++;
  444. }
  445. return 0;
  446. }