helper.h 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817
  1. /**
  2. Helper code for tinyphysicsengine example programs which handle things like
  3. SDL rendering, I/O, small3dlib rendering etc.
  4. */
  5. #define TPE_LOG puts
  6. #include "../tinyphysicsengine.h"
  7. #include <SDL2/SDL.h>
  8. #include <math.h>
  9. #include <stdio.h>
  10. #include <sys/time.h> // for measuring time
  11. #ifndef RES_X
  12. #define RES_X 640
  13. #endif
  14. #ifndef RES_Y
  15. #define RES_Y 480
  16. #endif
  17. #ifndef FPS
  18. #define FPS 30
  19. #endif
  20. #ifndef CAMERA_STEP
  21. #define CAMERA_STEP 100
  22. #endif
  23. #ifndef DEBUG_DRAW_DIVIDE
  24. #define DEBUG_DRAW_DIVIDE 1
  25. #endif
  26. #ifndef CAMERA_ROT_STEP
  27. #define CAMERA_ROT_STEP 5
  28. #endif
  29. #define MSPF (1000 / (FPS))
  30. #define S3L_RESOLUTION_X RES_X
  31. #define S3L_RESOLUTION_Y RES_Y
  32. #define S3L_PIXEL_FUNCTION s3l_drawPixel
  33. #ifndef SCALE_3D_RENDERING
  34. #define SCALE_3D_RENDERING 1 // helper divider for preveneting overflows
  35. #endif
  36. #define S3L_NEAR (S3L_FRACTIONS_PER_UNIT / (4 * SCALE_3D_RENDERING))
  37. #ifndef S3L_Z_BUFFER
  38. #define S3L_Z_BUFFER 1
  39. #endif
  40. #ifndef S3L_PERSPECTIVE_CORRECTION
  41. #define S3L_PERSPECTIVE_CORRECTION 0
  42. #endif
  43. #ifndef S3L_NEAR_CROSS_STRATEGY
  44. #define S3L_NEAR_CROSS_STRATEGY 1
  45. #endif
  46. #define S3L_USE_WIDER_TYPES 1
  47. #include "small3dlib.h"
  48. #define PIXELS_SIZE (S3L_RESOLUTION_X * S3L_RESOLUTION_Y * 4)
  49. #define helper_lastBody tpe_world.bodies[tpe_world.bodyCount - 1]
  50. S3L_Unit cubeVertices[] = { S3L_CUBE_VERTICES(TPE_FRACTIONS_PER_UNIT) };
  51. S3L_Index cubeTriangles[] = { S3L_CUBE_TRIANGLES };
  52. S3L_Model3D cubeModel;
  53. S3L_Unit triangleVertices[9];
  54. S3L_Index triangleTriangles[] = {0, 1, 2, 0, 2, 1};
  55. S3L_Model3D triangleModel;
  56. S3L_Unit planeVerices[] =
  57. {
  58. #define a S3L_FRACTIONS_PER_UNIT / 2
  59. #define b -1 * S3L_FRACTIONS_PER_UNIT / 2
  60. a,0,a,
  61. a,0,b,
  62. b,0,a,
  63. b,0,b
  64. #undef a
  65. #undef b
  66. };
  67. S3L_Index planeTriangles[] = { 0,2,1, 1,2,3 };
  68. S3L_Model3D planeModel;
  69. #define SPHERE_VERTEX_COUNT 42
  70. const S3L_Unit sphereVertices[SPHERE_VERTEX_COUNT * 3] = {
  71. 0, -512, 0, // 0
  72. 370, -228, -269, // 3
  73. -141, -228, -435, // 6
  74. -457, -228, 0, // 9
  75. -141, -228, 435, // 12
  76. 370, -228, 269, // 15
  77. 141, 228, -435, // 18
  78. -370, 228, -269, // 21
  79. -370, 228, 269, // 24
  80. 141, 228, 435, // 27
  81. 457, 228, 0, // 30
  82. 0, 512, 0, // 33
  83. -83, -435, -255, // 36
  84. 217, -435, -158, // 39
  85. 134, -269, -414, // 42
  86. 435, -269, 0, // 45
  87. 217, -435, 158, // 48
  88. -269, -435, 0, // 51
  89. -352, -269, -255, // 54
  90. -83, -435, 255, // 57
  91. -352, -269, 255, // 60
  92. 134, -269, 414, // 63
  93. 486, 0, -158, // 66
  94. 486, 0, 158, // 69
  95. 0, 0, -512, // 72
  96. 300, 0, -414, // 75
  97. -486, 0, -158, // 78
  98. -300, 0, -414, // 81
  99. -300, 0, 414, // 84
  100. -486, 0, 158, // 87
  101. 300, 0, 414, // 90
  102. 0, 0, 512, // 93
  103. 352, 269, -255, // 96
  104. -134, 269, -414, // 99
  105. -435, 269, 0, // 102
  106. -134, 269, 414, // 105
  107. 352, 269, 255, // 108
  108. 83, 435, -255, // 111
  109. 269, 435, 0, // 114
  110. -217, 435, -158, // 117
  111. -217, 435, 158, // 120
  112. 83, 435, 255 // 123
  113. }; // sphereVertices
  114. #define SPHERE_TRIANGLE_COUNT 80
  115. const S3L_Index sphereTriangleIndices[SPHERE_TRIANGLE_COUNT * 3] = {
  116. 0, 13, 12, // 0
  117. 1, 13, 15, // 3
  118. 0, 12, 17, // 6
  119. 0, 17, 19, // 9
  120. 0, 19, 16, // 12
  121. 1, 15, 22, // 15
  122. 2, 14, 24, // 18
  123. 3, 18, 26, // 21
  124. 4, 20, 28, // 24
  125. 5, 21, 30, // 27
  126. 1, 22, 25, // 30
  127. 2, 24, 27, // 33
  128. 3, 26, 29, // 36
  129. 4, 28, 31, // 39
  130. 5, 30, 23, // 42
  131. 6, 32, 37, // 45
  132. 7, 33, 39, // 48
  133. 8, 34, 40, // 51
  134. 9, 35, 41, // 54
  135. 10, 36, 38, // 57
  136. 38, 41, 11, // 60
  137. 38, 36, 41, // 63
  138. 36, 9, 41, // 66
  139. 41, 40, 11, // 69
  140. 41, 35, 40, // 72
  141. 35, 8, 40, // 75
  142. 40, 39, 11, // 78
  143. 40, 34, 39, // 81
  144. 34, 7, 39, // 84
  145. 39, 37, 11, // 87
  146. 39, 33, 37, // 90
  147. 33, 6, 37, // 93
  148. 37, 38, 11, // 96
  149. 37, 32, 38, // 99
  150. 32, 10, 38, // 102
  151. 23, 36, 10, // 105
  152. 23, 30, 36, // 108
  153. 30, 9, 36, // 111
  154. 31, 35, 9, // 114
  155. 31, 28, 35, // 117
  156. 28, 8, 35, // 120
  157. 29, 34, 8, // 123
  158. 29, 26, 34, // 126
  159. 26, 7, 34, // 129
  160. 27, 33, 7, // 132
  161. 27, 24, 33, // 135
  162. 24, 6, 33, // 138
  163. 25, 32, 6, // 141
  164. 25, 22, 32, // 144
  165. 22, 10, 32, // 147
  166. 30, 31, 9, // 150
  167. 30, 21, 31, // 153
  168. 21, 4, 31, // 156
  169. 28, 29, 8, // 159
  170. 28, 20, 29, // 162
  171. 20, 3, 29, // 165
  172. 26, 27, 7, // 168
  173. 26, 18, 27, // 171
  174. 18, 2, 27, // 174
  175. 24, 25, 6, // 177
  176. 24, 14, 25, // 180
  177. 14, 1, 25, // 183
  178. 22, 23, 10, // 186
  179. 22, 15, 23, // 189
  180. 15, 5, 23, // 192
  181. 16, 21, 5, // 195
  182. 16, 19, 21, // 198
  183. 19, 4, 21, // 201
  184. 19, 20, 4, // 204
  185. 19, 17, 20, // 207
  186. 17, 3, 20, // 210
  187. 17, 18, 3, // 213
  188. 17, 12, 18, // 216
  189. 12, 2, 18, // 219
  190. 15, 16, 5, // 222
  191. 15, 13, 16, // 225
  192. 13, 0, 16, // 228
  193. 12, 14, 2, // 231
  194. 12, 13, 14, // 234
  195. 13, 1, 14 // 237
  196. }; // sphereTriangleIndices
  197. #define CYLINDER_VERTEX_COUNT 20
  198. const S3L_Unit cylinderVertices[CYLINDER_VERTEX_COUNT * 3] = {
  199. 0, -256, 512, // 0
  200. 0, 256, 512, // 3
  201. 300, -256, 414, // 6
  202. 300, 256, 414, // 9
  203. 486, -256, 158, // 12
  204. 486, 256, 158, // 15
  205. 486, -256, -158, // 18
  206. 486, 256, -158, // 21
  207. 300, -256, -414, // 24
  208. 300, 256, -414, // 27
  209. 0, -256, -512, // 30
  210. 0, 256, -512, // 33
  211. -300, -256, -414, // 36
  212. -300, 256, -414, // 39
  213. -486, -256, -158, // 42
  214. -486, 256, -158, // 45
  215. -486, -256, 158, // 48
  216. -486, 256, 158, // 51
  217. -300, -256, 414, // 54
  218. -300, 256, 414 // 57
  219. }; // cylinderVertices
  220. #define CYLINDER_TRIANGLE_COUNT 36
  221. const S3L_Index cylinderTriangleIndices[CYLINDER_TRIANGLE_COUNT * 3] = {
  222. 1, 2, 0, // 0
  223. 3, 4, 2, // 3
  224. 5, 6, 4, // 6
  225. 7, 8, 6, // 9
  226. 9, 10, 8, // 12
  227. 11, 12, 10, // 15
  228. 13, 14, 12, // 18
  229. 15, 16, 14, // 21
  230. 17, 7, 5, // 24
  231. 17, 18, 16, // 27
  232. 19, 0, 18, // 30
  233. 6, 14, 18, // 33
  234. 1, 3, 2, // 36
  235. 3, 5, 4, // 39
  236. 5, 7, 6, // 42
  237. 7, 9, 8, // 45
  238. 9, 11, 10, // 48
  239. 11, 13, 12, // 51
  240. 13, 15, 14, // 54
  241. 15, 17, 16, // 57
  242. 5, 3, 17, // 60
  243. 1, 19, 17, // 63
  244. 17, 15, 13, // 66
  245. 13, 11, 17, // 69
  246. 9, 7, 17, // 72
  247. 3, 1, 17, // 75
  248. 17, 11, 9, // 78
  249. 17, 19, 18, // 81
  250. 19, 1, 0, // 84
  251. 18, 0, 2, // 87
  252. 2, 4, 6, // 90
  253. 6, 8, 10, // 93
  254. 10, 12, 14, // 96
  255. 14, 16, 18, // 99
  256. 18, 2, 6, // 102
  257. 6, 10, 14 // 105
  258. }; // cylinderTriangleIndices
  259. S3L_Model3D sphereModel;
  260. S3L_Model3D cylinderModel;
  261. #define MAX_BODIES 128
  262. #define MAX_JOINTS 1024
  263. #define MAX_CONNECTIONS 2048
  264. TPE_Body tpe_bodies[MAX_BODIES];
  265. TPE_Joint tpe_joints[MAX_JOINTS];
  266. TPE_Connection tpe_connections[MAX_CONNECTIONS];
  267. int helper_debugDrawOn = 0,
  268. helper_debugDrawOnCountdown = 0;
  269. unsigned int
  270. helper_jointsUsed = 0,
  271. helper_connectionsUsed = 0;
  272. TPE_World tpe_world;
  273. uint8_t sdl_pixels[PIXELS_SIZE];
  274. SDL_Window *sdl_window;
  275. SDL_Renderer *sdl_renderer;
  276. SDL_Texture *sdl_texture;
  277. SDL_Surface *sdl_screenSurface;
  278. int helper_frameStartTime;
  279. int helper_frameMsLeft;
  280. int helper_running;
  281. int helper_frame;
  282. const uint8_t *sdl_keyboard;
  283. S3L_Scene s3l_scene;
  284. S3L_Vec4 helper_cameraForw, helper_cameraRight, helper_cameraUp;
  285. unsigned long helper_getMicroSecs(void)
  286. {
  287. struct timeval t;
  288. gettimeofday(&t,NULL);
  289. return 1000000 * t.tv_sec + t.tv_usec;
  290. }
  291. void _helper_bodyAdded(int joints, int conns, TPE_Unit mass)
  292. {
  293. TPE_bodyInit(&tpe_bodies[tpe_world.bodyCount],
  294. &tpe_joints[helper_jointsUsed],joints,
  295. &tpe_connections[helper_connectionsUsed],conns,mass);
  296. helper_jointsUsed += joints;
  297. helper_connectionsUsed += conns;
  298. tpe_world.bodyCount++;
  299. }
  300. void helper_addBox(TPE_Unit w, TPE_Unit h, TPE_Unit d, TPE_Unit jointSize, TPE_Unit mass)
  301. {
  302. TPE_makeBox(
  303. tpe_joints + helper_jointsUsed,
  304. tpe_connections + helper_connectionsUsed,w,h,d,jointSize);
  305. _helper_bodyAdded(8,16,mass);
  306. }
  307. void helper_addCenterBox(TPE_Unit w, TPE_Unit h, TPE_Unit d, TPE_Unit jointSize, TPE_Unit mass)
  308. {
  309. TPE_makeCenterBox(
  310. tpe_joints + helper_jointsUsed,
  311. tpe_connections + helper_connectionsUsed,w,h,d,jointSize);
  312. _helper_bodyAdded(9,18,mass);
  313. }
  314. void helper_add2Line(TPE_Unit w, TPE_Unit jointSize, TPE_Unit mass)
  315. {
  316. TPE_make2Line(
  317. tpe_joints + helper_jointsUsed,
  318. tpe_connections + helper_connectionsUsed,w,jointSize);
  319. _helper_bodyAdded(2,1,mass);
  320. }
  321. void helper_addTriangle(TPE_Unit s, TPE_Unit d, TPE_Unit mass)
  322. {
  323. TPE_makeTriangle(
  324. tpe_joints + helper_jointsUsed,
  325. tpe_connections + helper_connectionsUsed,s,d);
  326. _helper_bodyAdded(3,3,mass);
  327. }
  328. void helper_addCenterRect(TPE_Unit w, TPE_Unit d, TPE_Unit jointSize, TPE_Unit mass)
  329. {
  330. TPE_makeCenterRect(
  331. tpe_joints + helper_jointsUsed,
  332. tpe_connections + helper_connectionsUsed,w,d,jointSize);
  333. _helper_bodyAdded(5,8,mass);
  334. }
  335. void helper_addCenterRectFull(TPE_Unit w, TPE_Unit d, TPE_Unit jointSize, TPE_Unit mass)
  336. {
  337. TPE_makeCenterRectFull(
  338. tpe_joints + helper_jointsUsed,
  339. tpe_connections + helper_connectionsUsed,w,d,jointSize);
  340. _helper_bodyAdded(5,10,mass);
  341. }
  342. void helper_addRect(TPE_Unit w, TPE_Unit d, TPE_Unit jointSize, TPE_Unit mass)
  343. {
  344. TPE_makeRect(
  345. tpe_joints + helper_jointsUsed,
  346. tpe_connections + helper_connectionsUsed,w,d,jointSize);
  347. _helper_bodyAdded(4,6,mass);
  348. }
  349. void helper_addBall(TPE_Unit s, TPE_Unit mass)
  350. {
  351. tpe_joints[helper_jointsUsed] = TPE_joint(TPE_vec3(0,0,0),s);
  352. _helper_bodyAdded(1,0,mass);
  353. }
  354. void helper_printCamera(void)
  355. {
  356. printf("camera: %ld %ld %ld (%ld %ld %ld)\n",
  357. s3l_scene.camera.transform.translation.x,
  358. s3l_scene.camera.transform.translation.y,
  359. s3l_scene.camera.transform.translation.z,
  360. s3l_scene.camera.transform.rotation.x,
  361. s3l_scene.camera.transform.rotation.y,
  362. s3l_scene.camera.transform.rotation.z);
  363. }
  364. void helper_printCPU(void)
  365. {
  366. printf("CPU (%d FPS): %d%% load\n",FPS,((MSPF - helper_frameMsLeft) * 100) / MSPF);
  367. }
  368. void helper_cameraFreeMovement(void)
  369. {
  370. if (sdl_keyboard[SDL_SCANCODE_LSHIFT])
  371. {
  372. if (sdl_keyboard[SDL_SCANCODE_UP])
  373. S3L_vec3Add(&s3l_scene.camera.transform.translation,helper_cameraForw);
  374. else if (sdl_keyboard[SDL_SCANCODE_DOWN])
  375. S3L_vec3Sub(&s3l_scene.camera.transform.translation,helper_cameraForw);
  376. else if (sdl_keyboard[SDL_SCANCODE_LEFT])
  377. S3L_vec3Sub(&s3l_scene.camera.transform.translation,helper_cameraRight);
  378. else if (sdl_keyboard[SDL_SCANCODE_RIGHT])
  379. S3L_vec3Add(&s3l_scene.camera.transform.translation,helper_cameraRight);
  380. }
  381. else
  382. {
  383. if (sdl_keyboard[SDL_SCANCODE_UP])
  384. s3l_scene.camera.transform.rotation.x += CAMERA_ROT_STEP;
  385. else if (sdl_keyboard[SDL_SCANCODE_DOWN])
  386. s3l_scene.camera.transform.rotation.x -= CAMERA_ROT_STEP;
  387. else if (sdl_keyboard[SDL_SCANCODE_LEFT])
  388. s3l_scene.camera.transform.rotation.y += CAMERA_ROT_STEP;
  389. else if (sdl_keyboard[SDL_SCANCODE_RIGHT])
  390. s3l_scene.camera.transform.rotation.y -= CAMERA_ROT_STEP;
  391. else if (sdl_keyboard[SDL_SCANCODE_Q])
  392. s3l_scene.camera.transform.rotation.z += CAMERA_ROT_STEP;
  393. else if (sdl_keyboard[SDL_SCANCODE_E])
  394. s3l_scene.camera.transform.rotation.z -= CAMERA_ROT_STEP;
  395. }
  396. }
  397. void sdl_drawPixel(int x, int y, uint8_t r, uint8_t g, uint8_t b)
  398. {
  399. uint8_t *pixel = sdl_pixels + (y * S3L_RESOLUTION_X + x) * 4 + 1;
  400. *pixel = b;
  401. pixel++;
  402. *pixel = g;
  403. pixel++;
  404. *pixel = r;
  405. }
  406. void helper_drawLine2D(int x1, int y1, int x2, int y2, uint8_t r, uint8_t g,
  407. uint8_t b)
  408. {
  409. if (x1 < 0 || x2 < 0 || y1 < 0 || y2 < 0 ||
  410. x1 >= RES_X || x2 >= RES_X || y1 >= RES_Y || y2 >= RES_Y)
  411. return;
  412. // stupid algorithm
  413. x2 -= x1;
  414. y2 -= y1;
  415. int max = (x2 * x2 > y2 * y2) ? x2 : y2;
  416. if (max < 0)
  417. max *= -1;
  418. for (int i = 0; i < max; ++i)
  419. sdl_drawPixel(x1 + (x2 * i) / max,y1 + (y2 * i) / max,r,g,b);
  420. }
  421. void helper_drawPoint3D(TPE_Vec3 p, uint8_t r, uint8_t g, uint8_t b)
  422. {
  423. S3L_Vec4 p2, p3;
  424. p2.x = p.x;
  425. p2.y = p.y;
  426. p2.z = p.z;
  427. p2.w = 0;
  428. S3L_project3DPointToScreen(p2,s3l_scene.camera,&p3);
  429. if (p3.x >= 0 && p3.x < S3L_RESOLUTION_X - 1 &&
  430. p3.y >= 0 && p3.y < S3L_RESOLUTION_Y - 1 && p3.z > 0)
  431. {
  432. sdl_drawPixel(p3.x,p3.y,r,g,b);
  433. sdl_drawPixel(p3.x + 1,p3.y,r,g,b);
  434. sdl_drawPixel(p3.x,p3.y + 1,r,g,b);
  435. sdl_drawPixel(p3.x + 1,p3.y + 1,r,g,b);
  436. }
  437. }
  438. void helper_drawLine3D(TPE_Vec3 p1, TPE_Vec3 p2, uint8_t rr, uint8_t gg,
  439. uint8_t bb)
  440. {
  441. S3L_Vec4 a, b, c, d;
  442. a.x = p1.x; a.y = p1.y; a.z = p1.z; a.w = 0;
  443. b.x = p2.x; b.y = p2.y; b.z = p2.z; b.w = 0;
  444. S3L_project3DPointToScreen(a,s3l_scene.camera,&c);
  445. S3L_project3DPointToScreen(b,s3l_scene.camera,&d);
  446. if (c.x >= 0 && c.x < S3L_RESOLUTION_X && c.y >= 0 && c.y < S3L_RESOLUTION_Y && c.z > 0 &&
  447. d.x >= 0 && d.x < S3L_RESOLUTION_X && d.y >= 0 && d.y < S3L_RESOLUTION_Y && d.z > 0)
  448. helper_drawLine2D(c.x,c.y,d.x,d.y,rr,gg,bb);
  449. }
  450. void tpe_debugDrawPixel(uint16_t x, uint16_t y, uint8_t color)
  451. {
  452. x /= DEBUG_DRAW_DIVIDE;
  453. y /= DEBUG_DRAW_DIVIDE;
  454. if (x < S3L_RESOLUTION_X - 2 && y < S3L_RESOLUTION_Y - 2)
  455. {
  456. uint8_t r, g, b;
  457. switch (color)
  458. {
  459. case 0: r = 100; g = 255; b = 200; break;
  460. case 1: r = 255; g = 100; b = 100; break;
  461. case 2: r = 0; g = 50; b = 50; break;
  462. case 3: r = 100; g = 100; b = 100; break;
  463. default: r = 0; g = 0; b = 0; break;
  464. }
  465. for (int i = 0; i < 3; ++i)
  466. for (int j = 0; j < 3; ++j)
  467. sdl_drawPixel(x + i,y + j,r,g,b);
  468. }
  469. }
  470. void helper_debugDraw(int drawEnv)
  471. {
  472. TPE_Vec3 camPos =
  473. TPE_vec3(
  474. s3l_scene.camera.transform.translation.x,
  475. s3l_scene.camera.transform.translation.y,
  476. s3l_scene.camera.transform.translation.z);
  477. TPE_Vec3 camRot =
  478. TPE_vec3(
  479. s3l_scene.camera.transform.rotation.x,
  480. s3l_scene.camera.transform.rotation.y,
  481. s3l_scene.camera.transform.rotation.z);
  482. TPE_worldDebugDraw(&tpe_world,tpe_debugDrawPixel,camPos,camRot,
  483. TPE_vec3(S3L_RESOLUTION_X * DEBUG_DRAW_DIVIDE,S3L_RESOLUTION_Y * DEBUG_DRAW_DIVIDE,s3l_scene.camera.focalLength),
  484. drawEnv ? 16 : 0,drawEnv ? 256 : 0);
  485. }
  486. uint8_t s3l_r = 0, s3l_g = 255, s3l_b = 0;
  487. uint8_t s3l_rr = 0, s3l_gg = 255, s3l_bb = 0;
  488. unsigned int s3l_previousTriangleID = 10000;
  489. S3L_Model3D *_helper_drawnModel;
  490. TPE_Vec3 helper_lightDir;
  491. void s3l_drawPixel(S3L_PixelInfo *p)
  492. {
  493. if (p->triangleIndex != s3l_previousTriangleID)
  494. {
  495. S3L_Index *v = _helper_drawnModel->triangles
  496. + 3 * p->triangleIndex;
  497. TPE_Vec3 a = TPE_vec3(
  498. _helper_drawnModel->vertices[(*v) * 3],
  499. _helper_drawnModel->vertices[(*v) * 3 + 1],
  500. _helper_drawnModel->vertices[(*v) * 3 + 2]);
  501. v++;
  502. TPE_Vec3 b = TPE_vec3(
  503. _helper_drawnModel->vertices[(*v) * 3],
  504. _helper_drawnModel->vertices[(*v) * 3 + 1],
  505. _helper_drawnModel->vertices[(*v) * 3 + 2]);
  506. v++;
  507. TPE_Vec3 c = TPE_vec3(
  508. _helper_drawnModel->vertices[(*v) * 3],
  509. _helper_drawnModel->vertices[(*v) * 3 + 1],
  510. _helper_drawnModel->vertices[(*v) * 3 + 2]);
  511. TPE_Vec3 normal = TPE_vec3Normalized(TPE_vec3Cross(
  512. TPE_vec3Minus(c,a),TPE_vec3Minus(c,b)));
  513. TPE_Unit intensity = 190 + TPE_vec3Dot(normal,
  514. helper_lightDir) / 8;
  515. s3l_rr = (s3l_r * intensity) / 256;
  516. s3l_gg = (s3l_g * intensity) / 256;
  517. s3l_bb = (s3l_b * intensity) / 256;
  518. s3l_previousTriangleID = p->triangleIndex;
  519. }
  520. sdl_drawPixel(p->x,p->y,s3l_rr,s3l_gg,s3l_bb);
  521. }
  522. void helper_set3DColor(uint8_t r, uint8_t g, uint8_t b)
  523. {
  524. s3l_r = r;
  525. s3l_g = g;
  526. s3l_b = b;
  527. }
  528. void helper_drawModel(S3L_Model3D *model, TPE_Vec3 pos, TPE_Vec3 scale,
  529. TPE_Vec3 rot)
  530. {
  531. _helper_drawnModel = model;
  532. s3l_previousTriangleID = -1;
  533. model->transform.translation.x = pos.x;
  534. model->transform.translation.y = pos.y;
  535. model->transform.translation.z = pos.z;
  536. model->transform.scale.x = scale.x;
  537. model->transform.scale.y = scale.y;
  538. model->transform.scale.z = scale.z;
  539. model->transform.rotation.x = rot.x;
  540. model->transform.rotation.y = rot.y;
  541. model->transform.rotation.z = rot.z;
  542. s3l_scene.models = model;
  543. #if SCALE_3D_RENDERING != 1
  544. S3L_Vec4 cp = s3l_scene.camera.transform.translation;
  545. S3L_Vec4 ms = s3l_scene.models[0].transform.scale;
  546. S3L_Vec4 mp = s3l_scene.models[0].transform.translation;
  547. s3l_scene.camera.transform.translation.x /= SCALE_3D_RENDERING;
  548. s3l_scene.camera.transform.translation.y /= SCALE_3D_RENDERING;
  549. s3l_scene.camera.transform.translation.z /= SCALE_3D_RENDERING;
  550. s3l_scene.models[0].transform.scale.x /= SCALE_3D_RENDERING;
  551. s3l_scene.models[0].transform.scale.y /= SCALE_3D_RENDERING;
  552. s3l_scene.models[0].transform.scale.z /= SCALE_3D_RENDERING;
  553. s3l_scene.models[0].transform.translation.x /= SCALE_3D_RENDERING;
  554. s3l_scene.models[0].transform.translation.y /= SCALE_3D_RENDERING;
  555. s3l_scene.models[0].transform.translation.z /= SCALE_3D_RENDERING;
  556. #endif
  557. S3L_drawScene(s3l_scene);
  558. #if SCALE_3D_RENDERING != 1
  559. s3l_scene.camera.transform.translation = cp;
  560. s3l_scene.models[0].transform.scale = ms;
  561. s3l_scene.models[0].transform.translation = mp;
  562. #endif
  563. }
  564. void helper_draw3DTriangle(TPE_Vec3 v1, TPE_Vec3 v2, TPE_Vec3 v3)
  565. {
  566. triangleVertices[0] = v1.x;
  567. triangleVertices[1] = v1.y;
  568. triangleVertices[2] = v1.z;
  569. triangleVertices[3] = v2.x;
  570. triangleVertices[4] = v2.y;
  571. triangleVertices[5] = v2.z;
  572. triangleVertices[6] = v3.x;
  573. triangleVertices[7] = v3.y;
  574. triangleVertices[8] = v3.z;
  575. helper_drawModel(&triangleModel,TPE_vec3(0,0,0),
  576. TPE_vec3(S3L_FRACTIONS_PER_UNIT,S3L_FRACTIONS_PER_UNIT,S3L_FRACTIONS_PER_UNIT),
  577. TPE_vec3(0,0,0));
  578. }
  579. void helper_draw3DBox(TPE_Vec3 pos, TPE_Vec3 scale, TPE_Vec3 rot)
  580. {
  581. cubeModel.config.backfaceCulling = 2;
  582. helper_drawModel(&cubeModel,pos,scale,rot);
  583. }
  584. void helper_draw3DCylinder(TPE_Vec3 pos, TPE_Vec3 scale, TPE_Vec3 rot)
  585. {
  586. helper_drawModel(&cylinderModel,pos,scale,rot);
  587. }
  588. void helper_draw3DBoxInside(TPE_Vec3 pos, TPE_Vec3 scale, TPE_Vec3 rot)
  589. {
  590. cubeModel.config.backfaceCulling = 1;
  591. helper_drawModel(&cubeModel,pos,scale,rot);
  592. }
  593. void helper_draw3DPlane(TPE_Vec3 pos, TPE_Vec3 scale, TPE_Vec3 rot)
  594. {
  595. helper_drawModel(&planeModel,pos,scale,rot);
  596. }
  597. void helper_draw3DSphere(TPE_Vec3 pos, TPE_Vec3 scale, TPE_Vec3 rot)
  598. {
  599. sphereModel.config.backfaceCulling = 2;
  600. helper_drawModel(&sphereModel,pos,scale,rot);
  601. }
  602. void helper_draw3DSphereInside(TPE_Vec3 pos, TPE_Vec3 scale, TPE_Vec3 rot)
  603. {
  604. sphereModel.config.backfaceCulling = 1;
  605. helper_drawModel(&sphereModel,pos,scale,rot);
  606. }
  607. void helper_init(void)
  608. {
  609. helper_lightDir = TPE_vec3Normalized(TPE_vec3(300,200,100));
  610. sdl_window = SDL_CreateWindow("program",SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,S3L_RESOLUTION_X,S3L_RESOLUTION_Y,SDL_WINDOW_SHOWN);
  611. sdl_renderer = SDL_CreateRenderer(sdl_window,-1,0);
  612. sdl_texture = SDL_CreateTexture(sdl_renderer,SDL_PIXELFORMAT_RGBX8888,SDL_TEXTUREACCESS_STATIC,S3L_RESOLUTION_X,S3L_RESOLUTION_Y);
  613. sdl_screenSurface = SDL_GetWindowSurface(sdl_window);
  614. sdl_keyboard = SDL_GetKeyboardState(NULL);
  615. helper_running = 1;
  616. helper_frame = 0;
  617. helper_frameMsLeft = 0;
  618. S3L_model3DInit(cubeVertices,S3L_CUBE_VERTEX_COUNT,cubeTriangles,
  619. S3L_CUBE_TRIANGLE_COUNT,&cubeModel);
  620. S3L_model3DInit(planeVerices,4,planeTriangles,2,&planeModel);
  621. S3L_model3DInit(sphereVertices,SPHERE_VERTEX_COUNT,sphereTriangleIndices,
  622. SPHERE_TRIANGLE_COUNT,&sphereModel);
  623. S3L_model3DInit(cylinderVertices,CYLINDER_VERTEX_COUNT,
  624. cylinderTriangleIndices,CYLINDER_TRIANGLE_COUNT,&cylinderModel);
  625. S3L_model3DInit(triangleVertices,3,triangleTriangles,2,&triangleModel);
  626. S3L_sceneInit(0,1,&s3l_scene);
  627. TPE_worldInit(&tpe_world,tpe_bodies,0,0);
  628. }
  629. void helper_frameStart(void)
  630. {
  631. helper_frameStartTime = SDL_GetTicks();
  632. for (uint32_t i = 0; i < PIXELS_SIZE; ++i)
  633. sdl_pixels[i] = 0;
  634. S3L_newFrame();
  635. SDL_Event event;
  636. while (SDL_PollEvent(&event))
  637. if (
  638. (event.type == SDL_QUIT) ||
  639. ((event.type == SDL_KEYDOWN) && (event.key.keysym.scancode == SDL_SCANCODE_ESCAPE))
  640. )
  641. helper_running = 0;
  642. S3L_rotationToDirections(s3l_scene.camera.transform.rotation,
  643. CAMERA_STEP,&helper_cameraForw,&helper_cameraRight,&helper_cameraUp);
  644. sdl_keyboard = SDL_GetKeyboardState(NULL);
  645. if (helper_debugDrawOnCountdown == 0 && sdl_keyboard[SDL_SCANCODE_F1])
  646. {
  647. helper_debugDrawOn = !helper_debugDrawOn;
  648. helper_debugDrawOnCountdown = FPS / 4;
  649. }
  650. else if (helper_debugDrawOnCountdown > 0)
  651. helper_debugDrawOnCountdown--;
  652. }
  653. void helper_frameEnd(void)
  654. {
  655. SDL_UpdateTexture(sdl_texture,NULL,sdl_pixels,S3L_RESOLUTION_X * sizeof(uint32_t));
  656. SDL_RenderClear(sdl_renderer);
  657. SDL_RenderCopy(sdl_renderer,sdl_texture,NULL,NULL);
  658. SDL_RenderPresent(sdl_renderer);
  659. helper_frame++;
  660. helper_frameMsLeft = helper_frameStartTime + MSPF - SDL_GetTicks();
  661. if (helper_frameMsLeft > 0)
  662. usleep(helper_frameMsLeft * 1000); // ofc this isn't accurate
  663. }
  664. void helper_end(void)
  665. {
  666. // TODO
  667. }