unit_compiler.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. /*
  2. * Copyright (c) 2012-2018 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/dbartolini/crown/blob/master/LICENSE
  4. */
  5. #include "core/containers/array.h"
  6. #include "core/containers/sort_map.h"
  7. #include "core/json/json_object.h"
  8. #include "core/json/sjson.h"
  9. #include "core/math/math.h"
  10. #include "core/memory/temp_allocator.h"
  11. #include "core/strings/dynamic_string.h"
  12. #include "resource/compile_options.h"
  13. #include "resource/physics_resource.h"
  14. #include "resource/unit_compiler.h"
  15. #include "resource/unit_resource.h"
  16. #include "world/types.h"
  17. namespace crown
  18. {
  19. struct ProjectionInfo
  20. {
  21. const char* name;
  22. ProjectionType::Enum type;
  23. };
  24. static const ProjectionInfo s_projection[] =
  25. {
  26. { "perspective", ProjectionType::PERSPECTIVE },
  27. { "orthographic", ProjectionType::ORTHOGRAPHIC }
  28. };
  29. CE_STATIC_ASSERT(countof(s_projection) == ProjectionType::COUNT);
  30. struct LightInfo
  31. {
  32. const char* name;
  33. LightType::Enum type;
  34. };
  35. static const LightInfo s_light[] =
  36. {
  37. { "directional", LightType::DIRECTIONAL },
  38. { "omni", LightType::OMNI },
  39. { "spot", LightType::SPOT }
  40. };
  41. CE_STATIC_ASSERT(countof(s_light) == LightType::COUNT);
  42. static ProjectionType::Enum projection_name_to_enum(const char* name)
  43. {
  44. for (u32 i = 0; i < countof(s_projection); ++i)
  45. {
  46. if (strcmp(name, s_projection[i].name) == 0)
  47. return s_projection[i].type;
  48. }
  49. return ProjectionType::COUNT;
  50. }
  51. static LightType::Enum light_name_to_enum(const char* name)
  52. {
  53. for (u32 i = 0; i < countof(s_light); ++i)
  54. {
  55. if (strcmp(name, s_light[i].name) == 0)
  56. return s_light[i].type;
  57. }
  58. return LightType::COUNT;
  59. }
  60. static Buffer compile_transform(const char* json, CompileOptions& /*opts*/)
  61. {
  62. TempAllocator4096 ta;
  63. JsonObject obj(ta);
  64. sjson::parse(json, obj);
  65. TransformDesc td;
  66. td.position = sjson::parse_vector3 (obj["position"]);
  67. td.rotation = sjson::parse_quaternion(obj["rotation"]);
  68. td.scale = sjson::parse_vector3 (obj["scale"]);
  69. Buffer buf(default_allocator());
  70. array::push(buf, (char*)&td, sizeof(td));
  71. return buf;
  72. }
  73. static Buffer compile_camera(const char* json, CompileOptions& opts)
  74. {
  75. TempAllocator4096 ta;
  76. JsonObject obj(ta);
  77. sjson::parse(json, obj);
  78. DynamicString type(ta);
  79. sjson::parse_string(obj["projection"], type);
  80. ProjectionType::Enum pt = projection_name_to_enum(type.c_str());
  81. DATA_COMPILER_ASSERT(pt != ProjectionType::COUNT
  82. , opts
  83. , "Unknown projection type: '%s'"
  84. , type.c_str()
  85. );
  86. CameraDesc cd;
  87. cd.type = pt;
  88. cd.fov = sjson::parse_float(obj["fov"]);
  89. cd.near_range = sjson::parse_float(obj["near_range"]);
  90. cd.far_range = sjson::parse_float(obj["far_range"]);
  91. Buffer buf(default_allocator());
  92. array::push(buf, (char*)&cd, sizeof(cd));
  93. return buf;
  94. }
  95. static Buffer compile_mesh_renderer(const char* json, CompileOptions& opts)
  96. {
  97. TempAllocator4096 ta;
  98. JsonObject obj(ta);
  99. sjson::parse(json, obj);
  100. DynamicString mesh_resource(ta);
  101. sjson::parse_string(obj["mesh_resource"], mesh_resource);
  102. DATA_COMPILER_ASSERT_RESOURCE_EXISTS("mesh"
  103. , mesh_resource.c_str()
  104. , opts
  105. );
  106. DynamicString material(ta);
  107. sjson::parse_string(obj["material"], material);
  108. DATA_COMPILER_ASSERT_RESOURCE_EXISTS("material"
  109. , material.c_str()
  110. , opts
  111. );
  112. MeshRendererDesc mrd;
  113. mrd.mesh_resource = sjson::parse_resource_id(obj["mesh_resource"]);
  114. mrd.geometry_name = sjson::parse_string_id (obj["geometry_name"]);
  115. mrd.material_resource = sjson::parse_resource_id(obj["material"]);
  116. mrd.visible = sjson::parse_bool (obj["visible"]);
  117. mrd._pad0[0] = 0;
  118. mrd._pad0[1] = 0;
  119. mrd._pad0[2] = 0;
  120. Buffer buf(default_allocator());
  121. array::push(buf, (char*)&mrd, sizeof(mrd));
  122. return buf;
  123. }
  124. static Buffer compile_sprite_renderer(const char* json, CompileOptions& opts)
  125. {
  126. TempAllocator4096 ta;
  127. JsonObject obj(ta);
  128. sjson::parse(json, obj);
  129. DynamicString sprite_resource(ta);
  130. sjson::parse_string(obj["sprite_resource"], sprite_resource);
  131. DATA_COMPILER_ASSERT_RESOURCE_EXISTS("sprite"
  132. , sprite_resource.c_str()
  133. , opts
  134. );
  135. DynamicString material(ta);
  136. sjson::parse_string(obj["material"], material);
  137. DATA_COMPILER_ASSERT_RESOURCE_EXISTS("material"
  138. , material.c_str()
  139. , opts
  140. );
  141. SpriteRendererDesc srd;
  142. srd.sprite_resource = sjson::parse_resource_id(obj["sprite_resource"]);
  143. srd.material_resource = sjson::parse_resource_id(obj["material"]);
  144. srd.layer = sjson::parse_int (obj["layer"]);
  145. srd.depth = sjson::parse_int (obj["depth"]);
  146. srd.visible = sjson::parse_bool (obj["visible"]);
  147. srd._pad0[0] = 0;
  148. srd._pad0[1] = 0;
  149. srd._pad0[2] = 0;
  150. srd._pad1[0] = 0;
  151. srd._pad1[1] = 0;
  152. srd._pad1[2] = 0;
  153. srd._pad1[3] = 0;
  154. Buffer buf(default_allocator());
  155. array::push(buf, (char*)&srd, sizeof(srd));
  156. return buf;
  157. }
  158. static Buffer compile_light(const char* json, CompileOptions& opts)
  159. {
  160. TempAllocator4096 ta;
  161. JsonObject obj(ta);
  162. sjson::parse(json, obj);
  163. DynamicString type(ta);
  164. sjson::parse_string(obj["type"], type);
  165. LightType::Enum lt = light_name_to_enum(type.c_str());
  166. DATA_COMPILER_ASSERT(lt != LightType::COUNT
  167. , opts
  168. , "Unknown light type: '%s'"
  169. , type.c_str()
  170. );
  171. LightDesc ld;
  172. ld.type = lt;
  173. ld.range = sjson::parse_float (obj["range"]);
  174. ld.intensity = sjson::parse_float (obj["intensity"]);
  175. ld.spot_angle = sjson::parse_float (obj["spot_angle"]);
  176. ld.color = sjson::parse_vector3(obj["color"]);
  177. Buffer buf(default_allocator());
  178. array::push(buf, (char*)&ld, sizeof(ld));
  179. return buf;
  180. }
  181. static Buffer compile_script(const char* json, CompileOptions& opts)
  182. {
  183. TempAllocator4096 ta;
  184. JsonObject obj(ta);
  185. sjson::parse(json, obj);
  186. DynamicString script_resource(ta);
  187. sjson::parse_string(obj["script_resource"], script_resource);
  188. DATA_COMPILER_ASSERT_RESOURCE_EXISTS("lua"
  189. , script_resource.c_str()
  190. , opts
  191. );
  192. ScriptDesc sd;
  193. sd.script_resource = sjson::parse_resource_id(obj["script_resource"]);
  194. Buffer buf(default_allocator());
  195. array::push(buf, (char*)&sd, sizeof(sd));
  196. return buf;
  197. }
  198. static Buffer compile_animation_state_machine(const char* json, CompileOptions& opts)
  199. {
  200. TempAllocator4096 ta;
  201. JsonObject obj(ta);
  202. sjson::parse(json, obj);
  203. DynamicString state_machine_resource(ta);
  204. sjson::parse_string(obj["state_machine_resource"], state_machine_resource);
  205. DATA_COMPILER_ASSERT_RESOURCE_EXISTS("state_machine"
  206. , state_machine_resource.c_str()
  207. , opts
  208. );
  209. AnimationStateMachineDesc asmd;
  210. asmd.state_machine_resource = sjson::parse_resource_id(obj["state_machine_resource"]);
  211. Buffer buf(default_allocator());
  212. array::push(buf, (char*)&asmd, sizeof(asmd));
  213. return buf;
  214. }
  215. UnitCompiler::UnitCompiler(CompileOptions& opts)
  216. : _opts(opts)
  217. , _num_units(0)
  218. , _component_data(default_allocator())
  219. , _component_info(default_allocator())
  220. {
  221. register_component_compiler("transform", &compile_transform, 0.0f);
  222. register_component_compiler("camera", &compile_camera, 1.0f);
  223. register_component_compiler("mesh_renderer", &compile_mesh_renderer, 1.0f);
  224. register_component_compiler("sprite_renderer", &compile_sprite_renderer, 1.0f);
  225. register_component_compiler("light", &compile_light, 1.0f);
  226. register_component_compiler("script", &compile_script, 1.0f);
  227. register_component_compiler("collider", &physics_resource_internal::compile_collider, 1.0f);
  228. register_component_compiler("actor", &physics_resource_internal::compile_actor, 2.0f);
  229. register_component_compiler("joint", &physics_resource_internal::compile_joint, 3.0f);
  230. register_component_compiler("animation_state_machine", &compile_animation_state_machine, 1.0f);
  231. }
  232. Buffer UnitCompiler::read_unit(const char* path)
  233. {
  234. Buffer buf = _opts.read(path);
  235. array::push_back(buf, '\0');
  236. return buf;
  237. }
  238. void UnitCompiler::compile_unit(const char* path)
  239. {
  240. compile_unit_from_json(array::begin(read_unit(path)));
  241. }
  242. u32 component_index(const JsonArray& components, const FixedString& id)
  243. {
  244. char guid[37];
  245. strncpy(guid, id.data(), sizeof(guid) - 1);
  246. guid[36] = '\0';
  247. Guid idd = guid::parse(guid);
  248. for (u32 i = 0; i < array::size(components); ++i)
  249. {
  250. TempAllocator512 ta;
  251. JsonObject obj(ta);
  252. sjson::parse(components[i], obj);
  253. if (sjson::parse_guid(obj["id"]) == idd)
  254. return i;
  255. }
  256. return UINT32_MAX;
  257. }
  258. void UnitCompiler::compile_unit_from_json(const char* json)
  259. {
  260. Buffer data(default_allocator());
  261. array::reserve(data, 1024*1024);
  262. u32 num_prefabs = 1;
  263. TempAllocator4096 ta;
  264. JsonObject prefabs[4] = { JsonObject(ta), JsonObject(ta), JsonObject(ta), JsonObject(ta) };
  265. sjson::parse(json, prefabs[0]);
  266. for (u32 i = 0; i < countof(prefabs); ++i, ++num_prefabs)
  267. {
  268. const JsonObject& prefab = prefabs[i];
  269. if (!json_object::has(prefab, "prefab"))
  270. break;
  271. TempAllocator512 ta;
  272. DynamicString path(ta);
  273. sjson::parse_string(prefab["prefab"], path);
  274. DATA_COMPILER_ASSERT_RESOURCE_EXISTS("unit"
  275. , path.c_str()
  276. , _opts
  277. );
  278. path += ".unit";
  279. Buffer buf = read_unit(path.c_str());
  280. const char* d = array::end(data);
  281. array::push(data, array::begin(buf), array::size(buf));
  282. sjson::parse(d, prefabs[i + 1]);
  283. }
  284. JsonObject& prefab_root = prefabs[num_prefabs - 1];
  285. JsonArray prefab_root_components_original(ta);
  286. sjson::parse_array(prefab_root["components"], prefab_root_components_original);
  287. JsonArray prefab_root_components(ta);
  288. sjson::parse_array(prefab_root["components"], prefab_root_components);
  289. if (num_prefabs > 1)
  290. {
  291. // Merge prefabs' components
  292. for (u32 i = 0; i < num_prefabs; ++i)
  293. {
  294. const JsonObject& prefab = prefabs[num_prefabs - i - 1];
  295. if (!json_object::has(prefab, "modified_components"))
  296. continue;
  297. JsonObject modified_components(ta);
  298. sjson::parse(prefab["modified_components"], modified_components);
  299. auto cur = json_object::begin(modified_components);
  300. auto end = json_object::end(modified_components);
  301. for (; cur != end; ++cur)
  302. {
  303. if (json_object::is_hole(modified_components, cur))
  304. continue;
  305. const FixedString key = cur->first;
  306. const FixedString id(&key.data()[1], key.length()-1);
  307. const char* value = cur->second;
  308. u32 comp_index = component_index(prefab_root_components_original, id);
  309. if (comp_index != UINT32_MAX)
  310. prefab_root_components[comp_index] = value;
  311. }
  312. }
  313. }
  314. if (array::size(prefab_root_components) > 0)
  315. {
  316. for (u32 i = 0; i < array::size(prefab_root_components); ++i)
  317. {
  318. const char* value = prefab_root_components[i];
  319. TempAllocator512 ta;
  320. JsonObject component(ta);
  321. sjson::parse(value, component);
  322. const StringId32 type = sjson::parse_string_id(component["type"]);
  323. Buffer buf = compile_component(type, component["data"]);
  324. add_component_data(type, buf, _num_units);
  325. }
  326. }
  327. ++_num_units;
  328. }
  329. void UnitCompiler::compile_multiple_units(const char* json)
  330. {
  331. TempAllocator4096 ta;
  332. JsonArray units(ta);
  333. sjson::parse_array(json, units);
  334. for (u32 i = 0; i < array::size(units); ++i)
  335. compile_unit_from_json(units[i]);
  336. }
  337. Buffer UnitCompiler::blob()
  338. {
  339. UnitResource ur;
  340. ur.version = RESOURCE_VERSION_UNIT;
  341. ur.num_units = _num_units;
  342. ur.num_component_types = 0;
  343. auto cur = sort_map::begin(_component_data);
  344. auto end = sort_map::end(_component_data);
  345. for (; cur != end; ++cur)
  346. {
  347. const u32 num = cur->second._num;
  348. if (num > 0)
  349. ++ur.num_component_types;
  350. }
  351. Buffer buf(default_allocator());
  352. array::push(buf, (char*)&ur, sizeof(ur));
  353. for (u32 i = 0; i < array::size(_component_info); ++i)
  354. {
  355. const StringId32 type = _component_info[i]._type;
  356. const ComponentTypeData& ctd = sort_map::get(_component_data, type, ComponentTypeData(default_allocator()));
  357. const Buffer& data = ctd._data;
  358. const Array<u32>& unit_index = ctd._unit_index;
  359. const u32 num = ctd._num;
  360. if (num > 0)
  361. {
  362. ComponentData cd;
  363. cd.type = type;
  364. cd.num_instances = num;
  365. cd.size = array::size(data) + sizeof(u32)*array::size(unit_index);
  366. const u32 pad = cd.size % alignof(cd);
  367. cd.size += pad;
  368. array::push(buf, (char*)&cd, sizeof(cd));
  369. array::push(buf, (char*)array::begin(unit_index), sizeof(u32)*array::size(unit_index));
  370. array::push(buf, array::begin(data), array::size(data));
  371. // Insert proper padding
  372. for (u32 i = 0; i < pad; ++i)
  373. array::push_back(buf, (char)0);
  374. }
  375. }
  376. return buf;
  377. }
  378. void UnitCompiler::add_component_data(StringId32 type, const Buffer& data, u32 unit_index)
  379. {
  380. ComponentTypeData& ctd = const_cast<ComponentTypeData&>(sort_map::get(_component_data, type, ComponentTypeData(default_allocator())));
  381. array::push(ctd._data, array::begin(data), array::size(data));
  382. array::push_back(ctd._unit_index, unit_index);
  383. ++ctd._num;
  384. }
  385. void UnitCompiler::register_component_compiler(const char* type, CompileFunction fn, f32 spawn_order)
  386. {
  387. register_component_compiler(StringId32(type), fn, spawn_order);
  388. }
  389. void UnitCompiler::register_component_compiler(StringId32 type, CompileFunction fn, f32 spawn_order)
  390. {
  391. ComponentTypeData ctd(default_allocator());
  392. ctd._compiler = fn;
  393. ComponentTypeInfo cti;
  394. cti._type = type;
  395. cti._spawn_order = spawn_order;
  396. sort_map::set(_component_data, type, ctd);
  397. sort_map::sort(_component_data);
  398. array::push_back(_component_info, cti);
  399. std::sort(array::begin(_component_info), array::end(_component_info));
  400. }
  401. Buffer UnitCompiler::compile_component(StringId32 type, const char* json)
  402. {
  403. DATA_COMPILER_ASSERT(sort_map::has(_component_data, type), _opts, "Unknown component");
  404. return sort_map::get(_component_data, type, ComponentTypeData(default_allocator()))._compiler(json, _opts);
  405. }
  406. } // namespace crown