lua_world.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545
  1. /*
  2. * Copyright (c) 2012-2016 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/taylor001/crown/blob/master/LICENSE
  4. */
  5. #include "array.h"
  6. #include "device.h"
  7. #include "lua_environment.h"
  8. #include "lua_stack.h"
  9. #include "resource_manager.h"
  10. #include "scene_graph.h"
  11. #include "sound_world.h"
  12. #include "temp_allocator.h"
  13. #include "world.h"
  14. namespace crown
  15. {
  16. struct ProjectionInfo
  17. {
  18. const char* name;
  19. ProjectionType::Enum type;
  20. };
  21. static ProjectionInfo s_projection[] =
  22. {
  23. { "orthographic", ProjectionType::ORTHOGRAPHIC },
  24. { "perspective", ProjectionType::PERSPECTIVE }
  25. };
  26. CE_STATIC_ASSERT(CE_COUNTOF(s_projection) == ProjectionType::COUNT);
  27. static ProjectionType::Enum name_to_projection_type(LuaStack& stack, const char* name)
  28. {
  29. for (uint32_t i = 0; i < CE_COUNTOF(s_projection); ++i)
  30. {
  31. if (strcmp(s_projection[i].name, name) == 0)
  32. return s_projection[i].type;
  33. }
  34. LUA_ASSERT(false, stack, "Unknown projection: %s", name);
  35. return ProjectionType::COUNT;
  36. }
  37. static int world_spawn_unit(lua_State* L)
  38. {
  39. LuaStack stack(L);
  40. World* world = stack.get_world(1);
  41. const StringId64 name = stack.get_resource_id(2);
  42. const Vector3& pos = stack.num_args() > 2 ? stack.get_vector3(3) : VECTOR3_ZERO;
  43. const Quaternion& rot = stack.num_args() > 3 ? stack.get_quaternion(4) : QUATERNION_IDENTITY;
  44. LUA_ASSERT(device()->resource_manager()->can_get(UNIT_TYPE, name), stack, "Unit not found");
  45. UnitId unit = world->spawn_unit(name, pos, rot);
  46. stack.push_unit(unit);
  47. return 1;
  48. }
  49. static int world_destroy_unit(lua_State* L)
  50. {
  51. LuaStack stack(L);
  52. stack.get_world(1)->destroy_unit(stack.get_unit(2));
  53. return 0;
  54. }
  55. static int world_num_units(lua_State* L)
  56. {
  57. LuaStack stack(L);
  58. stack.push_int(stack.get_world(1)->num_units());
  59. return 1;
  60. }
  61. static int world_units(lua_State* L)
  62. {
  63. LuaStack stack(L);
  64. TempAllocator1024 alloc;
  65. Array<UnitId> units(alloc);
  66. stack.get_world(1)->units(units);
  67. const uint32_t num = array::size(units);
  68. stack.push_table(num);
  69. for (uint32_t i = 0; i < num; ++i)
  70. {
  71. stack.push_key_begin((int32_t) i + 1);
  72. stack.push_unit(units[i]);
  73. stack.push_key_end();
  74. }
  75. return 1;
  76. }
  77. static int world_camera(lua_State* L)
  78. {
  79. LuaStack stack(L);
  80. stack.push_camera(stack.get_world(1)->camera(stack.get_unit(2)));
  81. return 1;
  82. }
  83. static int camera_set_projection_type(lua_State* L)
  84. {
  85. LuaStack stack(L);
  86. stack.get_world(1)->set_camera_projection_type(stack.get_camera(2)
  87. , name_to_projection_type(stack, stack.get_string(3))
  88. );
  89. return 0;
  90. }
  91. static int camera_projection_type(lua_State* L)
  92. {
  93. LuaStack stack(L);
  94. ProjectionType::Enum type = stack.get_world(1)->camera_projection_type(stack.get_camera(2));
  95. stack.push_string(s_projection[type].name);
  96. return 1;
  97. }
  98. static int camera_fov(lua_State* L)
  99. {
  100. LuaStack stack(L);
  101. stack.push_float(stack.get_world(1)->camera_fov(stack.get_camera(2)));
  102. return 1;
  103. }
  104. static int camera_set_fov(lua_State* L)
  105. {
  106. LuaStack stack(L);
  107. stack.get_world(1)->set_camera_fov(stack.get_camera(2), stack.get_float(3));
  108. return 0;
  109. }
  110. static int camera_aspect(lua_State* L)
  111. {
  112. LuaStack stack(L);
  113. stack.push_float(stack.get_world(1)->camera_aspect(stack.get_camera(2)));
  114. return 1;
  115. }
  116. static int camera_set_aspect(lua_State* L)
  117. {
  118. LuaStack stack(L);
  119. stack.get_world(1)->set_camera_aspect(stack.get_camera(2), stack.get_float(3));
  120. return 0;
  121. }
  122. static int camera_near_clip_distance(lua_State* L)
  123. {
  124. LuaStack stack(L);
  125. stack.push_float(stack.get_world(1)->camera_near_clip_distance(stack.get_camera(2)));
  126. return 1;
  127. }
  128. static int camera_set_near_clip_distance(lua_State* L)
  129. {
  130. LuaStack stack(L);
  131. stack.get_world(1)->set_camera_near_clip_distance(stack.get_camera(2), stack.get_float(3));
  132. return 0;
  133. }
  134. static int camera_far_clip_distance(lua_State* L)
  135. {
  136. LuaStack stack(L);
  137. stack.push_float(stack.get_world(1)->camera_far_clip_distance(stack.get_camera(2)));
  138. return 1;
  139. }
  140. static int camera_set_far_clip_distance(lua_State* L)
  141. {
  142. LuaStack stack(L);
  143. stack.get_world(1)->set_camera_far_clip_distance(stack.get_camera(2), stack.get_float(3));
  144. return 0;
  145. }
  146. static int camera_set_orthographic_metrics(lua_State* L)
  147. {
  148. LuaStack stack(L);
  149. stack.get_world(1)->set_camera_orthographic_metrics(stack.get_camera(2), stack.get_float(3), stack.get_float(4),
  150. stack.get_float(5), stack.get_float(6));
  151. return 0;
  152. }
  153. static int camera_set_viewport_metrics(lua_State* L)
  154. {
  155. LuaStack stack(L);
  156. stack.get_world(1)->set_camera_viewport_metrics(stack.get_camera(2), stack.get_int(3), stack.get_int(4),
  157. stack.get_int(5), stack.get_int(6));
  158. return 0;
  159. }
  160. static int camera_screen_to_world(lua_State* L)
  161. {
  162. LuaStack stack(L);
  163. stack.push_vector3(stack.get_world(1)->camera_screen_to_world(stack.get_camera(2), stack.get_vector3(3)));
  164. return 1;
  165. }
  166. static int camera_world_to_screen(lua_State* L)
  167. {
  168. LuaStack stack(L);
  169. stack.push_vector3(stack.get_world(1)->camera_world_to_screen(stack.get_camera(2), stack.get_vector3(3)));
  170. return 1;
  171. }
  172. static int world_update_animations(lua_State* L)
  173. {
  174. LuaStack stack(L);
  175. stack.get_world(1)->update_animations(stack.get_float(2));
  176. return 0;
  177. }
  178. static int world_update_scene(lua_State* L)
  179. {
  180. LuaStack stack(L);
  181. stack.get_world(1)->update_scene(stack.get_float(2));
  182. return 0;
  183. }
  184. static int world_update(lua_State* L)
  185. {
  186. LuaStack stack(L);
  187. stack.get_world(1)->update(stack.get_float(2));
  188. return 0;
  189. }
  190. static int world_play_sound(lua_State* L)
  191. {
  192. LuaStack stack(L);
  193. World* world = stack.get_world(1);
  194. const StringId64 name = stack.get_resource_id(2);
  195. const int32_t nargs = stack.num_args();
  196. const bool loop = nargs > 2 ? stack.get_bool(3) : false;
  197. const float volume = nargs > 3 ? stack.get_float(4) : 1.0f;
  198. const Vector3& pos = nargs > 4 ? stack.get_vector3(5) : VECTOR3_ZERO;
  199. const float range = nargs > 5 ? stack.get_float(6) : 1000.0f;
  200. LUA_ASSERT(device()->resource_manager()->can_get(SOUND_TYPE, name), stack, "Sound not found");
  201. stack.push_sound_instance_id(world->play_sound(name, loop, volume, pos, range));
  202. return 1;
  203. }
  204. static int world_stop_sound(lua_State* L)
  205. {
  206. LuaStack stack(L);
  207. stack.get_world(1)->stop_sound(stack.get_sound_instance_id(2));
  208. return 0;
  209. }
  210. static int world_link_sound(lua_State* L)
  211. {
  212. LuaStack stack(L);
  213. stack.get_world(1)->link_sound(stack.get_sound_instance_id(2),
  214. stack.get_unit(3),
  215. stack.get_int(4));
  216. return 0;
  217. }
  218. static int world_set_listener_pose(lua_State* L)
  219. {
  220. LuaStack stack(L);
  221. stack.get_world(1)->set_listener_pose(stack.get_matrix4x4(2));
  222. return 0;
  223. }
  224. static int world_set_sound_position(lua_State* L)
  225. {
  226. LuaStack stack(L);
  227. stack.get_world(1)->set_sound_position(stack.get_sound_instance_id(2),
  228. stack.get_vector3(3));
  229. return 0;
  230. }
  231. static int world_set_sound_range(lua_State* L)
  232. {
  233. LuaStack stack(L);
  234. stack.get_world(1)->set_sound_range(stack.get_sound_instance_id(2),
  235. stack.get_float(3));
  236. return 0;
  237. }
  238. static int world_set_sound_volume(lua_State* L)
  239. {
  240. LuaStack stack(L);
  241. stack.get_world(1)->set_sound_volume(stack.get_sound_instance_id(2),
  242. stack.get_float(3));
  243. return 0;
  244. }
  245. static int world_create_debug_line(lua_State* L)
  246. {
  247. LuaStack stack(L);
  248. stack.push_debug_line(stack.get_world(1)->create_debug_line(stack.get_bool(2)));
  249. return 1;
  250. }
  251. static int world_destroy_debug_line(lua_State* L)
  252. {
  253. LuaStack stack(L);
  254. stack.get_world(1)->destroy_debug_line(*stack.get_debug_line(2));
  255. return 0;
  256. }
  257. static int world_load_level(lua_State* L)
  258. {
  259. LuaStack stack(L);
  260. const StringId64 name = stack.get_resource_id(2);
  261. const Vector3& pos = stack.num_args() > 2 ? stack.get_vector3(3) : VECTOR3_ZERO;
  262. const Quaternion& rot = stack.num_args() > 3 ? stack.get_quaternion(4) : QUATERNION_IDENTITY;
  263. LUA_ASSERT(device()->resource_manager()->can_get(LEVEL_TYPE, name), stack, "Level not found");
  264. stack.push_level(stack.get_world(1)->load_level(name, pos, rot));
  265. return 1;
  266. }
  267. static int world_scene_graph(lua_State* L)
  268. {
  269. LuaStack stack(L);
  270. stack.push_scene_graph(stack.get_world(1)->scene_graph());
  271. return 1;
  272. }
  273. static int world_render_world(lua_State* L)
  274. {
  275. LuaStack stack(L);
  276. stack.push_render_world(stack.get_world(1)->render_world());
  277. return 1;
  278. }
  279. static int world_physics_world(lua_State* L)
  280. {
  281. LuaStack stack(L);
  282. stack.push_physics_world(stack.get_world(1)->physics_world());
  283. return 1;
  284. }
  285. static int world_sound_world(lua_State* L)
  286. {
  287. LuaStack stack(L);
  288. stack.push_sound_world(stack.get_world(1)->sound_world());
  289. return 1;
  290. }
  291. static int world_tostring(lua_State* L)
  292. {
  293. LuaStack stack(L);
  294. World* w = stack.get_world(1);
  295. stack.push_fstring("World (%p)", w);
  296. return 1;
  297. }
  298. static int scene_graph_create(lua_State* L)
  299. {
  300. LuaStack stack(L);
  301. stack.push_transform(stack.get_scene_graph(1)->create(stack.get_unit(2), MATRIX4X4_IDENTITY));
  302. return 1;
  303. }
  304. static int scene_graph_destroy(lua_State* L)
  305. {
  306. LuaStack stack(L);
  307. stack.get_scene_graph(1)->destroy(stack.get_transform(2));
  308. return 0;
  309. }
  310. static int scene_graph_transform_instances(lua_State* L)
  311. {
  312. LuaStack stack(L);
  313. stack.push_transform(stack.get_scene_graph(1)->get(stack.get_unit(2)));
  314. return 1;
  315. }
  316. static int scene_graph_local_position(lua_State* L)
  317. {
  318. LuaStack stack(L);
  319. stack.push_vector3(stack.get_scene_graph(1)->local_position(stack.get_transform(2)));
  320. return 1;
  321. }
  322. static int scene_graph_local_rotation(lua_State* L)
  323. {
  324. LuaStack stack(L);
  325. stack.push_quaternion(stack.get_scene_graph(1)->local_rotation(stack.get_transform(2)));
  326. return 1;
  327. }
  328. static int scene_graph_local_scale(lua_State* L)
  329. {
  330. LuaStack stack(L);
  331. stack.push_vector3(stack.get_scene_graph(1)->local_scale(stack.get_transform(2)));
  332. return 1;
  333. }
  334. static int scene_graph_local_pose(lua_State* L)
  335. {
  336. LuaStack stack(L);
  337. stack.push_matrix4x4(stack.get_scene_graph(1)->local_pose(stack.get_transform(2)));
  338. return 1;
  339. }
  340. static int scene_graph_world_position(lua_State* L)
  341. {
  342. LuaStack stack(L);
  343. stack.push_vector3(stack.get_scene_graph(1)->world_position(stack.get_transform(2)));
  344. return 1;
  345. }
  346. static int scene_graph_world_rotation(lua_State* L)
  347. {
  348. LuaStack stack(L);
  349. stack.push_quaternion(stack.get_scene_graph(1)->world_rotation(stack.get_transform(2)));
  350. return 1;
  351. }
  352. static int scene_graph_world_pose(lua_State* L)
  353. {
  354. LuaStack stack(L);
  355. stack.push_matrix4x4(stack.get_scene_graph(1)->world_pose(stack.get_transform(2)));
  356. return 1;
  357. }
  358. static int scene_graph_set_local_position(lua_State* L)
  359. {
  360. LuaStack stack(L);
  361. stack.get_scene_graph(1)->set_local_position(stack.get_transform(2), stack.get_vector3(3));
  362. return 0;
  363. }
  364. static int scene_graph_set_local_rotation(lua_State* L)
  365. {
  366. LuaStack stack(L);
  367. stack.get_scene_graph(1)->set_local_rotation(stack.get_transform(2), stack.get_quaternion(3));
  368. return 0;
  369. }
  370. static int scene_graph_set_local_scale(lua_State* L)
  371. {
  372. LuaStack stack(L);
  373. stack.get_scene_graph(1)->set_local_scale(stack.get_transform(2), stack.get_vector3(3));
  374. return 0;
  375. }
  376. static int scene_graph_set_local_pose(lua_State* L)
  377. {
  378. LuaStack stack(L);
  379. stack.get_scene_graph(1)->set_local_pose(stack.get_transform(2), stack.get_matrix4x4(3));
  380. return 0;
  381. }
  382. static int scene_graph_link(lua_State* L)
  383. {
  384. LuaStack stack(L);
  385. stack.get_scene_graph(1)->link(stack.get_transform(2), stack.get_transform(3));
  386. return 0;
  387. }
  388. static int scene_graph_unlink(lua_State* L)
  389. {
  390. LuaStack stack(L);
  391. stack.get_scene_graph(1)->unlink(stack.get_transform(2));
  392. return 0;
  393. }
  394. static int unit_manager_create(lua_State* L)
  395. {
  396. LuaStack stack(L);
  397. if (stack.num_args() == 1)
  398. stack.push_unit(device()->unit_manager()->create(*stack.get_world(1)));
  399. else
  400. stack.push_unit(device()->unit_manager()->create());
  401. return 1;
  402. }
  403. static int unit_manager_alive(lua_State* L)
  404. {
  405. LuaStack stack(L);
  406. stack.push_bool(device()->unit_manager()->alive(stack.get_unit(1)));
  407. return 1;
  408. }
  409. void load_world(LuaEnvironment& env)
  410. {
  411. env.load_module_function("World", "spawn_unit", world_spawn_unit);
  412. env.load_module_function("World", "destroy_unit", world_destroy_unit);
  413. env.load_module_function("World", "num_units", world_num_units);
  414. env.load_module_function("World", "units", world_units);
  415. env.load_module_function("World", "camera", world_camera);
  416. env.load_module_function("World", "set_camera_projection_type", camera_set_projection_type);
  417. env.load_module_function("World", "camera_projection_type", camera_projection_type);
  418. env.load_module_function("World", "camera_fov", camera_fov);
  419. env.load_module_function("World", "set_camera_fov", camera_set_fov);
  420. env.load_module_function("World", "camera_aspect", camera_aspect);
  421. env.load_module_function("World", "set_camera_aspect", camera_set_aspect);
  422. env.load_module_function("World", "camera_near_clip_distance", camera_near_clip_distance);
  423. env.load_module_function("World", "set_camera_near_clip_distance", camera_set_near_clip_distance);
  424. env.load_module_function("World", "camera_far_clip_distance", camera_far_clip_distance);
  425. env.load_module_function("World", "set_camera_far_clip_distance", camera_set_far_clip_distance);
  426. env.load_module_function("World", "set_camera_orthographic_metrics", camera_set_orthographic_metrics);
  427. env.load_module_function("World", "set_camera_viewport_metrics", camera_set_viewport_metrics);
  428. env.load_module_function("World", "camera_screen_to_world", camera_screen_to_world);
  429. env.load_module_function("World", "camera_world_to_screen", camera_world_to_screen);
  430. env.load_module_function("World", "update_animations", world_update_animations);
  431. env.load_module_function("World", "update_scene", world_update_scene);
  432. env.load_module_function("World", "update", world_update);
  433. env.load_module_function("World", "play_sound", world_play_sound);
  434. env.load_module_function("World", "stop_sound", world_stop_sound);
  435. env.load_module_function("World", "link_sound", world_link_sound);
  436. env.load_module_function("World", "set_listener_pose", world_set_listener_pose);
  437. env.load_module_function("World", "set_sound_position", world_set_sound_position);
  438. env.load_module_function("World", "set_sound_range", world_set_sound_range);
  439. env.load_module_function("World", "set_sound_volume", world_set_sound_volume);
  440. env.load_module_function("World", "create_debug_line", world_create_debug_line);
  441. env.load_module_function("World", "destroy_debug_line", world_destroy_debug_line);
  442. env.load_module_function("World", "load_level", world_load_level);
  443. env.load_module_function("World", "scene_graph", world_scene_graph);
  444. env.load_module_function("World", "render_world", world_render_world);
  445. env.load_module_function("World", "physics_world", world_physics_world);
  446. env.load_module_function("World", "sound_world", world_sound_world);
  447. env.load_module_function("World", "__index", "World");
  448. env.load_module_function("World", "__tostring", world_tostring);
  449. env.load_module_function("SceneGraph", "create", scene_graph_create);
  450. env.load_module_function("SceneGraph", "destroy", scene_graph_destroy);
  451. env.load_module_function("SceneGraph", "transform_instances", scene_graph_transform_instances);
  452. env.load_module_function("SceneGraph", "local_position", scene_graph_local_position);
  453. env.load_module_function("SceneGraph", "local_rotation", scene_graph_local_rotation);
  454. env.load_module_function("SceneGraph", "local_scale", scene_graph_local_scale);
  455. env.load_module_function("SceneGraph", "local_pose", scene_graph_local_pose);
  456. env.load_module_function("SceneGraph", "world_position", scene_graph_world_position);
  457. env.load_module_function("SceneGraph", "world_rotation", scene_graph_world_rotation);
  458. env.load_module_function("SceneGraph", "world_pose", scene_graph_world_pose);
  459. env.load_module_function("SceneGraph", "set_local_position", scene_graph_set_local_position);
  460. env.load_module_function("SceneGraph", "set_local_rotation", scene_graph_set_local_rotation);
  461. env.load_module_function("SceneGraph", "set_local_scale", scene_graph_set_local_scale);
  462. env.load_module_function("SceneGraph", "set_local_pose", scene_graph_set_local_pose);
  463. env.load_module_function("SceneGraph", "link", scene_graph_link);
  464. env.load_module_function("SceneGraph", "unlink", scene_graph_unlink);
  465. env.load_module_function("UnitManager", "create", unit_manager_create);
  466. env.load_module_function("UnitManager", "alive", unit_manager_alive);
  467. }
  468. } // namespace crown