OpenSource.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. #include "bsp.h"
  2. #include "cache.h"
  3. #include "collection.h"
  4. #include "mempools.h"
  5. #include "common.h"
  6. #include "texture.h"
  7. #include "profiler.h"
  8. #include "atto/app.h"
  9. #include "atto/math.h"
  10. static char persistent_data[128*1024*1024];
  11. static char temp_data[128*1024*1024];
  12. static struct Stack stack_temp = {
  13. .storage = temp_data,
  14. .size = sizeof(temp_data),
  15. .cursor = 0
  16. };
  17. static struct Stack stack_persistent = {
  18. .storage = persistent_data,
  19. .size = sizeof(persistent_data),
  20. .cursor = 0
  21. };
  22. struct SimpleCamera {
  23. struct AVec3f pos, dir, up;
  24. struct AMat3f axes;
  25. struct AMat4f projection;
  26. struct AMat4f view_projection;
  27. };
  28. static void simplecamRecalc(struct SimpleCamera *cam) {
  29. cam->dir = aVec3fNormalize(cam->dir);
  30. const struct AVec3f
  31. z = aVec3fNeg(cam->dir),
  32. x = aVec3fNormalize(aVec3fCross(cam->up, z)),
  33. y = aVec3fCross(z, x);
  34. cam->axes = aMat3fv(x, y, z);
  35. const struct AMat3f axes_inv = aMat3fTranspose(cam->axes);
  36. cam->view_projection = aMat4fMul(cam->projection,
  37. aMat4f3(axes_inv, aVec3fMulMat(axes_inv, aVec3fNeg(cam->pos))));
  38. }
  39. static void simplecamProjection(struct SimpleCamera *cam, float znear, float zfar, float horizfov, float aspect) {
  40. const float w = 2.f * znear * tanf(horizfov / 2.f), h = w / aspect;
  41. //aAppDebugPrintf("%f %f %f %f -> %f %f", near, far, horizfov, aspect, w, h);
  42. cam->projection = aMat4fPerspective(znear, zfar, w, h);
  43. }
  44. static void simplecamLookAt(struct SimpleCamera *cam, struct AVec3f pos, struct AVec3f at, struct AVec3f up) {
  45. cam->pos = pos;
  46. cam->dir = aVec3fNormalize(aVec3fSub(at, pos));
  47. cam->up = up;
  48. simplecamRecalc(cam);
  49. }
  50. static void simplecamMove(struct SimpleCamera *cam, struct AVec3f v) {
  51. cam->pos = aVec3fAdd(cam->pos, aVec3fMulf(cam->axes.X, v.x));
  52. cam->pos = aVec3fAdd(cam->pos, aVec3fMulf(cam->axes.Y, v.y));
  53. cam->pos = aVec3fAdd(cam->pos, aVec3fMulf(cam->axes.Z, v.z));
  54. }
  55. static void simplecamRotateYaw(struct SimpleCamera *cam, float yaw) {
  56. const struct AMat3f rot = aMat3fRotateAxis(cam->up, yaw);
  57. cam->dir = aVec3fMulMat(rot, cam->dir);
  58. }
  59. static void simplecamRotatePitch(struct SimpleCamera *cam, float pitch) {
  60. /* TODO limit pitch */
  61. const struct AMat3f rot = aMat3fRotateAxis(cam->axes.X, pitch);
  62. cam->dir = aVec3fMulMat(rot, cam->dir);
  63. }
  64. struct Map {
  65. char *name;
  66. int loaded;
  67. struct AVec3f offset;
  68. struct BSPModel model;
  69. struct Map *next;
  70. };
  71. static struct {
  72. struct SimpleCamera camera;
  73. int forward, right, run;
  74. struct AVec3f center;
  75. float R;
  76. float lmn;
  77. struct Map *maps_begin, *maps_end;
  78. int maps_count, maps_limit;
  79. } g;
  80. void openSourceAddMap(const char* mapname, int mapname_length) {
  81. if (g.maps_count >= g.maps_limit) {
  82. PRINTF("Map limit reached, not trying to add map %.*s",
  83. mapname_length, mapname);
  84. return;
  85. }
  86. struct Map *map = g.maps_begin;
  87. while (map) {
  88. if (strncmp(map->name, mapname, mapname_length) == 0)
  89. return;
  90. map = map->next;
  91. }
  92. char *mem = stackAlloc(&stack_persistent, sizeof(struct Map) + mapname_length + 1);
  93. if (!mem) {
  94. PRINT("Not enough memory");
  95. return;
  96. }
  97. memcpy(mem, mapname, mapname_length);
  98. mem[mapname_length] = '\0';
  99. map = (void*)(mem + mapname_length + 1);
  100. memset(map, 0, sizeof(*map));
  101. map->name = mem;
  102. if (!g.maps_end)
  103. g.maps_begin = map;
  104. else
  105. g.maps_end->next = map;
  106. g.maps_end = map;
  107. ++g.maps_count;
  108. PRINTF("Added new map to the queue: %.*s", mapname_length, mapname);
  109. }
  110. static enum BSPLoadResult loadMap(struct Map *map, struct ICollection *collection) {
  111. struct BSPLoadModelContext loadctx = {
  112. .collection = collection,
  113. .persistent = &stack_persistent,
  114. .tmp = &stack_temp,
  115. .model = &map->model
  116. };
  117. const enum BSPLoadResult result = bspLoadWorldspawn(loadctx, map->name);
  118. if (result != BSPLoadResult_Success) {
  119. PRINTF("Cannot load map \"%s\": %d", map->name, result);
  120. return result;
  121. }
  122. aAppDebugPrintf("Loaded %s to %u draw calls", map->name, map->model.draws_count);
  123. aAppDebugPrintf("AABB (%f, %f, %f) - (%f, %f, %f)",
  124. map->model.aabb.min.x,
  125. map->model.aabb.min.y,
  126. map->model.aabb.min.z,
  127. map->model.aabb.max.x,
  128. map->model.aabb.max.y,
  129. map->model.aabb.max.z);
  130. PRINTF("Landmarks: %d", map->model.landmarks_count);
  131. for (int i = 0; i < map->model.landmarks_count; ++i) {
  132. struct BSPLandmark *lm = map->model.landmarks + i;
  133. PRINTF("\t%d: %s -> (%f, %f, %f)", i + 1, lm->name,
  134. lm->origin.x, lm->origin.y, lm->origin.z);
  135. }
  136. map->loaded = 1;
  137. if (map != g.maps_begin && map->model.landmarks_count != 0) {
  138. for (struct Map *map2 = g.maps_begin; map2; map2 = map2->next) {
  139. if (map2->loaded != 1)
  140. continue;
  141. for (int j = 0; j < map2->model.landmarks_count; ++j) {
  142. const struct BSPLandmark *m2 = map2->model.landmarks + j;
  143. for (int k = 0; k < map->model.landmarks_count; ++k) {
  144. const struct BSPLandmark *m1 = map->model.landmarks + k;
  145. if (strcmp(m1->name, m2->name) == 0) {
  146. map->offset = aVec3fAdd(map2->offset, aVec3fSub(m2->origin, m1->origin));
  147. PRINTF("Map %s offset %f, %f, %f",
  148. map->name, map->offset.x, map->offset.y, map->offset.z);
  149. return BSPLoadResult_Success;
  150. } // if landmarks match
  151. } // for all landmarks of map 1
  152. } // for all landmarks of map 2
  153. } // for all maps (2)
  154. } // if neet to position map
  155. return BSPLoadResult_Success;
  156. }
  157. static void opensrcInit(struct ICollection *collection, const char *map, int max_maps) {
  158. cacheInit(&stack_persistent);
  159. if (!renderInit()) {
  160. PRINT("Failed to initialize render");
  161. aAppTerminate(-1);
  162. }
  163. g.maps_limit = max_maps > 0 ? max_maps : 1;
  164. g.maps_count = 0;
  165. openSourceAddMap(map, strlen(map));
  166. for(struct Map *map = g.maps_begin; map; map = map->next)
  167. if (BSPLoadResult_Success != loadMap(map, collection) && map == g.maps_begin)
  168. aAppTerminate(-2);
  169. PRINTF("Maps loaded: %d", g.maps_count);
  170. g.center = aVec3fMulf(aVec3fAdd(g.maps_begin->model.aabb.min, g.maps_begin->model.aabb.max), .5f);
  171. g.R = aVec3fLength(aVec3fSub(g.maps_begin->model.aabb.max, g.maps_begin->model.aabb.min)) * .5f;
  172. aAppDebugPrintf("Center %f, %f, %f, R~=%f", g.center.x, g.center.y, g.center.z, g.R);
  173. const float t = 0;
  174. simplecamLookAt(&g.camera,
  175. aVec3fAdd(g.center, aVec3fMulf(aVec3f(cosf(t*.5f), sinf(t*.5f), .25f), g.R*.5f)),
  176. g.center, aVec3f(0.f, 0.f, 1.f));
  177. }
  178. static void opensrcResize(ATimeUs timestamp, unsigned int old_w, unsigned int old_h) {
  179. (void)(timestamp); (void)(old_w); (void)(old_h);
  180. glViewport(0, 0, a_app_state->width, a_app_state->height);
  181. simplecamProjection(&g.camera, 1.f, g.R * 10.f, 3.1415926f/2.f, (float)a_app_state->width / (float)a_app_state->height);
  182. simplecamRecalc(&g.camera);
  183. }
  184. static void opensrcPaint(ATimeUs timestamp, float dt) {
  185. (void)(timestamp); (void)(dt);
  186. float move = dt * (g.run?3000.f:300.f);
  187. simplecamMove(&g.camera, aVec3f(g.right * move, 0.f, -g.forward * move));
  188. simplecamRecalc(&g.camera);
  189. renderClear();
  190. for (struct Map *map = g.maps_begin; map; map = map->next) {
  191. if (!map->loaded)
  192. continue;
  193. const struct AMat4f mvp = aMat4fMul(g.camera.view_projection, aMat4fTranslation(map->offset));
  194. renderModelDraw(&mvp, g.lmn, &map->model);
  195. if (profilerFrame(&stack_temp)) {
  196. int triangles = 0;
  197. for (int i = 0; i < map->model.draws_count; ++i) {
  198. triangles += map->model.draws[i].count / 3;
  199. }
  200. PRINTF("Total triangles: %d", triangles);
  201. }
  202. }
  203. }
  204. #ifdef _WIN32
  205. /* FIXME need proper support from atto */
  206. static void aAppGrabInput(int grab) {
  207. (void)grab;
  208. }
  209. #endif
  210. static void opensrcKeyPress(ATimeUs timestamp, AKey key, int pressed) {
  211. (void)(timestamp); (void)(key); (void)(pressed);
  212. //printf("KEY %u %d %d\n", timestamp, key, pressed);
  213. switch (key) {
  214. case AK_Esc:
  215. if (!pressed) break;
  216. if (a_app_state->grabbed)
  217. aAppGrabInput(0);
  218. else
  219. aAppTerminate(0);
  220. break;
  221. case AK_W: g.forward += pressed?1:-1; break;
  222. case AK_S: g.forward += pressed?-1:1; break;
  223. case AK_A: g.right += pressed?-1:1; break;
  224. case AK_D: g.right += pressed?1:-1; break;
  225. case AK_LeftShift: g.run = pressed; break;
  226. case AK_E: g.lmn = (float)pressed; break;
  227. default: break;
  228. }
  229. }
  230. static void opensrcPointer(ATimeUs timestamp, int dx, int dy, unsigned int btndiff) {
  231. (void)(timestamp); (void)(dx); (void)(dy); (void)(btndiff);
  232. //printf("PTR %u %d %d %x\n", timestamp, dx, dy, btndiff);
  233. if (a_app_state->grabbed) {
  234. simplecamRotatePitch(&g.camera, dy * -4e-3f);
  235. simplecamRotateYaw(&g.camera, dx * -4e-3f);
  236. simplecamRecalc(&g.camera);
  237. } else if (btndiff)
  238. aAppGrabInput(1);
  239. }
  240. static struct ICollection *addToCollectionChain(struct ICollection *chain, struct ICollection *next) {
  241. if (chain) {
  242. struct ICollection *coll = chain;
  243. while (coll->next)
  244. coll = coll->next;
  245. coll->next = next;
  246. return chain;
  247. }
  248. return next;
  249. }
  250. void attoAppInit(struct AAppProctable *proctable) {
  251. profilerInit();
  252. //aGLInit();
  253. struct ICollection *collection_chain = NULL;
  254. const char *map = 0;
  255. int max_maps = 1;
  256. struct Memories mem = {
  257. &stack_temp,
  258. &stack_persistent
  259. };
  260. for (int i = 1; i < a_app_state->argc; ++i) {
  261. const char *argv = a_app_state->argv[i];
  262. if (strcmp(argv, "-p") == 0) {
  263. if (i == a_app_state->argc - 1) {
  264. aAppDebugPrintf("-p requires an argument");
  265. goto print_usage_and_exit;
  266. }
  267. const char *value = a_app_state->argv[++i];
  268. PRINTF("Adding vpk collection at %s", value);
  269. collection_chain = addToCollectionChain(collection_chain, collectionCreateVPK(&mem, value));
  270. } else if (strcmp(argv, "-d") == 0) {
  271. if (i == a_app_state->argc - 1) {
  272. aAppDebugPrintf("-d requires an argument");
  273. goto print_usage_and_exit;
  274. }
  275. const char *value = a_app_state->argv[++i];
  276. PRINTF("Adding dir collection at %s", value);
  277. collection_chain = addToCollectionChain(collection_chain, collectionCreateFilesystem(&mem, value));
  278. } else if (strcmp(argv, "-n") == 0) {
  279. if (i == a_app_state->argc - 1) {
  280. aAppDebugPrintf("-p requires an argument");
  281. goto print_usage_and_exit;
  282. }
  283. const char *value = a_app_state->argv[++i];
  284. max_maps = atoi(value);
  285. } else {
  286. if (map) {
  287. aAppDebugPrintf("Only one map can be specified");
  288. goto print_usage_and_exit;
  289. }
  290. map = argv;
  291. }
  292. }
  293. if (!map || !collection_chain) {
  294. aAppDebugPrintf("At least one map and one collection required");
  295. goto print_usage_and_exit;
  296. }
  297. opensrcInit(collection_chain, map, max_maps);
  298. proctable->resize = opensrcResize;
  299. proctable->paint = opensrcPaint;
  300. proctable->key = opensrcKeyPress;
  301. proctable->pointer = opensrcPointer;
  302. return;
  303. print_usage_and_exit:
  304. aAppDebugPrintf("usage: %s <-d path> ... mapname", a_app_state->argv[0]);
  305. aAppTerminate(1);
  306. }