hello2.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /** Simple demo showing 2 bodies thrown inside a room, the world is rendered
  2. as a simple ASCII side view. */
  3. #include "../tinyphysicsengine.h"
  4. #include <stdio.h>
  5. #define ROOM_SIZE (20 * TPE_F)
  6. TPE_Vec3 environmentDistance(TPE_Vec3 point, TPE_Unit maxDistance)
  7. {
  8. // our environemnt: just a simple room
  9. return TPE_envAABoxInside(point,TPE_vec3(ROOM_SIZE / 2,ROOM_SIZE / 2,0),
  10. TPE_vec3(ROOM_SIZE,ROOM_SIZE,ROOM_SIZE));
  11. }
  12. // the following functions are just for ASCII drawing the world
  13. #define SCREEN_W 32
  14. #define SCREEN_H 16
  15. char screen[SCREEN_W * SCREEN_H];
  16. void clearScreen(void)
  17. {
  18. for (int i = 0; i < SCREEN_W * SCREEN_H; ++i)
  19. screen[i] = (i < SCREEN_W || i >= SCREEN_W * (SCREEN_H - 1)) ? '-' :
  20. ((i % SCREEN_W) == 0 || (i % SCREEN_W) == SCREEN_W - 1 ? '|' : ' ');
  21. }
  22. void setPixel(int x, int y, char c)
  23. {
  24. if (x < 0 || x >= SCREEN_W || y < 0 || y >= SCREEN_H)
  25. return;
  26. y = SCREEN_H - 1 - y;
  27. screen[y * SCREEN_W + x] = c;
  28. }
  29. void printScreen(void)
  30. {
  31. for (int i = 0; i < 20; ++i)
  32. putchar('\n');
  33. for (int y = 0; y < SCREEN_H; ++y)
  34. {
  35. for (int x = 0; x < SCREEN_W; ++x)
  36. putchar(screen[y * SCREEN_W + x]);
  37. putchar('\n');
  38. }
  39. }
  40. int main(void)
  41. {
  42. TPE_Body bodies[2]; // we'll have two bodies
  43. TPE_World world;
  44. TPE_Joint joints[32]; // joint buffer
  45. TPE_Connection connections[64]; // connection buffer
  46. /* we'll create the first body "by hand", just two joints (spheres) with one
  47. connection: */
  48. joints[0] = TPE_joint(TPE_vec3(3 * ROOM_SIZE / 4,ROOM_SIZE / 2,0),TPE_F);
  49. joints[1] =
  50. TPE_joint(TPE_vec3(3 * ROOM_SIZE / 4 + TPE_F * 4,ROOM_SIZE / 2,0),TPE_F);
  51. connections[0].joint1 = 0;
  52. connections[0].joint2 = 1;
  53. TPE_bodyInit(&bodies[0],joints,2,connections,1,TPE_F);
  54. /* the other (a "box" approximated by spheres) will be made by the library
  55. function: */
  56. TPE_makeBox(joints + 2,connections + 1,2 * TPE_F, 2 * TPE_F, 2 * TPE_F,TPE_F);
  57. TPE_bodyInit(&bodies[1],joints + 2,8,connections + 1,16,TPE_F);
  58. TPE_bodyMoveTo(&bodies[1],TPE_vec3(ROOM_SIZE / 2,ROOM_SIZE / 2,0));
  59. TPE_worldInit(&world,bodies,2,environmentDistance);
  60. // give some initial velocities and spins to the bodies:
  61. TPE_bodyAccelerate(&world.bodies[0],TPE_vec3(-1 * TPE_F / 8,TPE_F / 3,0));
  62. TPE_bodySpin(&world.bodies[0],TPE_vec3(0,0,-1 * TPE_F / 25));
  63. TPE_bodyAccelerate(&world.bodies[1],TPE_vec3(-1 * TPE_F / 2,50,0));
  64. TPE_bodySpin(&world.bodies[1],TPE_vec3(0,0,TPE_F / 23));
  65. #define FRAMES 200
  66. for (int i = 0; i <= FRAMES; ++i) // simulate 200 steps
  67. {
  68. if (i % 10 == 0) // draw the world every 10 frames
  69. {
  70. clearScreen();
  71. for (int j = 0; j < world.bodyCount; ++j)
  72. {
  73. // draw body joints:
  74. for (int k = 0; k < world.bodies[j].jointCount; ++k)
  75. {
  76. TPE_Vec3 pos = world.bodies[j].joints[k].position;
  77. setPixel((pos.x * SCREEN_W) / ROOM_SIZE,
  78. (pos.y * SCREEN_H) / ROOM_SIZE,'.');
  79. }
  80. // draw the body center:
  81. TPE_Vec3 pos = TPE_bodyGetCenterOfMass(&world.bodies[j]);
  82. setPixel((pos.x * SCREEN_W) / ROOM_SIZE,(pos.y * SCREEN_H) / ROOM_SIZE,
  83. 'A' + j);
  84. }
  85. printScreen();
  86. printf("frame %d/%d\n",i,FRAMES);
  87. puts("press return to step");
  88. getchar();
  89. }
  90. TPE_worldStep(&world); // simulate next tick
  91. for (int j = 0; j < world.bodyCount; ++j)
  92. TPE_bodyApplyGravity(&world.bodies[j],TPE_F / 100);
  93. }
  94. return 0;
  95. }