helper.h 25 KB

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