From 8739f0a85cfaf58be9c93e7a6bda8a2c13229c62 Mon Sep 17 00:00:00 2001 From: Lucas Schwiderski Date: Thu, 25 May 2023 15:36:33 +0200 Subject: [PATCH] chore: Initialize reposoitory Stingray SDK headers taken from https://github.com/AutodeskGames/stingray-plugin/ --- .gitignore | 9 + Cargo.toml | 9 + LICENSE | 675 ++++ README.adoc | 13 + lib/dt_p2p/.gitignore | 2 + lib/dt_p2p/Cargo.toml | 14 + lib/dt_p2p/build.rs | 22 + lib/dt_p2p/src/lib.rs | 6 + lib/dt_p2p/src/stingray_sdk.rs | 7 + lib/dt_p2p/stingray_sdk.h | 1 + lib/dt_p2p/stingray_sdk/LICENSE.md | 13 + .../editor_foundation/stingray.d.ts | 66 + .../stingray_sdk/editor_foundation/types.d.ts | 271 ++ .../editor_plugin_api/editor_plugin_api.h | 339 ++ .../engine_plugin_api/c_api/c_api_actor.h | 72 + .../c_api/c_api_application.h | 43 + .../engine_plugin_api/c_api/c_api_assert.h | 11 + .../engine_plugin_api/c_api/c_api_camera.h | 58 + .../c_api/c_api_dynamic_script_data.h | 63 + .../engine_plugin_api/c_api/c_api_entity.h | 112 + .../c_api/c_api_game_session.h | 56 + .../engine_plugin_api/c_api/c_api_gui.h | 104 + .../engine_plugin_api/c_api/c_api_input.h | 51 + .../c_api/c_api_input_controller.h | 49 + .../engine_plugin_api/c_api/c_api_keyboard.h | 18 + .../engine_plugin_api/c_api/c_api_lan.h | 47 + .../engine_plugin_api/c_api/c_api_level.h | 60 + .../c_api/c_api_line_object.h | 29 + .../engine_plugin_api/c_api/c_api_material.h | 25 + .../engine_plugin_api/c_api/c_api_mesh.h | 38 + .../engine_plugin_api/c_api/c_api_mover.h | 35 + .../engine_plugin_api/c_api/c_api_network.h | 32 + .../c_api/c_api_physics_world.h | 41 + .../engine_plugin_api/c_api/c_api_ps4.h | 13 + .../c_api/c_api_ps4_error_dialog.h | 13 + .../c_api/c_api_ps4_ime_dialog.h | 13 + .../c_api/c_api_ps4_msg_dialog.h | 13 + .../c_api/c_api_ps4_np_commerce_dialog.h | 13 + .../engine_plugin_api/c_api/c_api_ps4_types.h | 5 + .../engine_plugin_api/c_api/c_api_ps4pad.h | 18 + .../engine_plugin_api/c_api/c_api_psn.h | 13 + .../c_api/c_api_save_system.h | 23 + .../c_api/c_api_scatter_system.h | 36 + .../c_api/c_api_touch_input.h | 37 + .../engine_plugin_api/c_api/c_api_types.h | 627 ++++ .../engine_plugin_api/c_api/c_api_unit.h | 207 ++ .../c_api/c_api_unit_synchronizer.h | 21 + .../engine_plugin_api/c_api/c_api_utilities.h | 24 + .../engine_plugin_api/c_api/c_api_viewport.h | 16 + .../engine_plugin_api/c_api/c_api_window.h | 85 + .../engine_plugin_api/c_api/c_api_world.h | 100 + .../engine_plugin_api/c_api/c_api_xbox1pad.h | 16 + .../entity_components/c_api_actor_component.h | 25 + .../c_api_animation_blender_component.h | 27 + .../c_api_animation_state_machine_component.h | 25 + .../entity_components/c_api_data_component.h | 16 + .../c_api_debug_name_component.h | 16 + .../entity_components/c_api_flow_component.h | 20 + .../entity_components/c_api_mesh_component.h | 20 + .../c_api_render_data_component.h | 23 + .../c_api_scene_graph_component.h | 32 + .../entity_components/c_api_tag_component.h | 22 + .../c_api_transform_component.h | 37 + .../entity_components/c_api_unit_component.h | 17 + .../engine_plugin_api/default_plugin_suffix.h | 19 + .../engine_plugin_api/plugin_api.h | 2745 +++++++++++++++++ .../engine_plugin_api/plugin_api_types.h | 136 + .../engine_plugin_api/plugin_c_api.h | 73 + .../plugin_scene_database_api.h | 347 +++ .../plugin_foundation/allocator.h | 106 + .../stingray_sdk/plugin_foundation/array.h | 149 + .../stingray_sdk/plugin_foundation/array.inl | 276 ++ .../stingray_sdk/plugin_foundation/assert.h | 38 + .../plugin_foundation/bucket_iterator.h | 97 + .../plugin_foundation/bucket_iterator.inl | 89 + .../stingray_sdk/plugin_foundation/buffer.h | 73 + .../plugin_foundation/collection_tools.h | 16 + .../plugin_foundation/collection_tools.inl | 16 + .../stingray_sdk/plugin_foundation/color.h | 23 + .../stingray_sdk/plugin_foundation/com_ptr.h | 31 + .../plugin_foundation/com_ptr.inl | 66 + .../plugin_foundation/const_config.h | 168 + .../stingray_sdk/plugin_foundation/encoding.h | 84 + .../plugin_foundation/encoding.inl | 211 ++ .../plugin_foundation/exception_handling.h | 33 + .../stingray_sdk/plugin_foundation/flow.h | 51 + .../plugin_foundation/functional.h | 17 + .../plugin_foundation/hash_function.h | 192 ++ .../plugin_foundation/hash_function_string.h | 24 + .../stingray_sdk/plugin_foundation/hash_map.h | 145 + .../plugin_foundation/hash_map.inl | 518 ++++ .../stingray_sdk/plugin_foundation/hash_set.h | 93 + .../plugin_foundation/hash_set.inl | 404 +++ .../plugin_foundation/id_string.h | 109 + .../plugin_foundation/id_string.inl | 88 + .../plugin_foundation/line_shapes.h | 25 + .../plugin_foundation/line_shapes.inl | 80 + .../plugin_foundation/local_transform.h | 47 + .../plugin_foundation/local_transform.inl | 189 ++ .../stingray_sdk/plugin_foundation/math.h | 171 + .../stingray_sdk/plugin_foundation/math.inl | 120 + .../plugin_foundation/matrix4x4.h | 78 + .../plugin_foundation/matrix4x4.inl | 385 +++ .../plugin_foundation/memory_utilities.h | 94 + .../stingray_sdk/plugin_foundation/option.h | 40 + .../stingray_sdk/plugin_foundation/pair.h | 179 ++ .../stingray_sdk/plugin_foundation/path.h | 74 + .../stingray_sdk/plugin_foundation/platform.h | 43 + .../plugin_foundation/quaternion.h | 69 + .../plugin_foundation/quaternion.inl | 511 +++ .../stingray_sdk/plugin_foundation/random.h | 83 + .../plugin_foundation/scene_flags.h | 41 + .../plugin_foundation/scene_tree.h | 490 +++ .../plugin_foundation/scene_tree.inl | 42 + .../scene_tree_api_convert.h | 8 + .../scene_tree_api_convert.inl | 498 +++ .../stingray_sdk/plugin_foundation/sort_map.h | 184 ++ .../plugin_foundation/sort_map.inl | 403 +++ .../stingray_sdk/plugin_foundation/sort_set.h | 68 + .../plugin_foundation/sort_set.inl | 233 ++ .../stingray_sdk/plugin_foundation/stream.h | 125 + .../stingray_sdk/plugin_foundation/string.h | 322 ++ .../stingray_sdk/plugin_foundation/string.inl | 223 ++ .../plugin_foundation/string_stream.h | 58 + .../plugin_foundation/string_stream.inl | 116 + .../plugin_foundation/template_tools.h | 51 + .../stingray_sdk/plugin_foundation/types.h | 44 + .../stingray_sdk/plugin_foundation/vector.h | 176 ++ .../stingray_sdk/plugin_foundation/vector.inl | 245 ++ .../stingray_sdk/plugin_foundation/vector2.h | 53 + .../plugin_foundation/vector2.inl | 167 + .../stingray_sdk/plugin_foundation/vector3.h | 82 + .../plugin_foundation/vector3.inl | 274 ++ .../stingray_sdk/plugin_foundation/vector4.h | 58 + .../plugin_foundation/vector4.inl | 193 ++ lib/nat_traversal/.gitignore | 2 + lib/nat_traversal/Cargo.toml | 8 + lib/nat_traversal/src/lib.rs | 14 + 138 files changed, 16767 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.toml create mode 100644 LICENSE create mode 100644 README.adoc create mode 100644 lib/dt_p2p/.gitignore create mode 100644 lib/dt_p2p/Cargo.toml create mode 100644 lib/dt_p2p/build.rs create mode 100644 lib/dt_p2p/src/lib.rs create mode 100644 lib/dt_p2p/src/stingray_sdk.rs create mode 100644 lib/dt_p2p/stingray_sdk.h create mode 100644 lib/dt_p2p/stingray_sdk/LICENSE.md create mode 100644 lib/dt_p2p/stingray_sdk/editor_foundation/stingray.d.ts create mode 100644 lib/dt_p2p/stingray_sdk/editor_foundation/types.d.ts create mode 100644 lib/dt_p2p/stingray_sdk/editor_plugin_api/editor_plugin_api.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_actor.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_application.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_assert.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_camera.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_dynamic_script_data.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_entity.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_game_session.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_gui.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_input.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_input_controller.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_keyboard.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_lan.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_level.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_line_object.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_material.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_mesh.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_mover.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_network.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_physics_world.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4_error_dialog.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4_ime_dialog.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4_msg_dialog.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4_np_commerce_dialog.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4_types.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4pad.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_psn.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_save_system.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_scatter_system.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_touch_input.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_types.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_unit.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_unit_synchronizer.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_utilities.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_viewport.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_window.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_world.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_xbox1pad.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_actor_component.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_animation_blender_component.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_animation_state_machine_component.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_data_component.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_debug_name_component.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_flow_component.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_mesh_component.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_render_data_component.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_scene_graph_component.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_tag_component.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_transform_component.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_unit_component.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/default_plugin_suffix.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/plugin_api.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/plugin_api_types.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/plugin_c_api.h create mode 100644 lib/dt_p2p/stingray_sdk/engine_plugin_api/plugin_scene_database_api.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/allocator.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/array.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/array.inl create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/assert.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/bucket_iterator.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/bucket_iterator.inl create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/buffer.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/collection_tools.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/collection_tools.inl create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/color.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/com_ptr.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/com_ptr.inl create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/const_config.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/encoding.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/encoding.inl create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/exception_handling.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/flow.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/functional.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/hash_function.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/hash_function_string.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/hash_map.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/hash_map.inl create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/hash_set.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/hash_set.inl create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/id_string.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/id_string.inl create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/line_shapes.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/line_shapes.inl create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/local_transform.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/local_transform.inl create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/math.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/math.inl create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/matrix4x4.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/matrix4x4.inl create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/memory_utilities.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/option.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/pair.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/path.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/platform.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/quaternion.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/quaternion.inl create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/random.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/scene_flags.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/scene_tree.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/scene_tree.inl create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/scene_tree_api_convert.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/scene_tree_api_convert.inl create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/sort_map.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/sort_map.inl create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/sort_set.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/sort_set.inl create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/stream.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/string.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/string.inl create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/string_stream.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/string_stream.inl create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/template_tools.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/types.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/vector.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/vector.inl create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/vector2.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/vector2.inl create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/vector3.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/vector3.inl create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/vector4.h create mode 100644 lib/dt_p2p/stingray_sdk/plugin_foundation/vector4.inl create mode 100644 lib/nat_traversal/.gitignore create mode 100644 lib/nat_traversal/Cargo.toml create mode 100644 lib/nat_traversal/src/lib.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9ce42ca --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +/target + + +# Added by cargo +# +# already existing elements were commented out + +#/target +/Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..d157fa5 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[workspace] +resolver = "2" +members = [ + "lib/dt_p2p", + "lib/nat_traversal" +] + +# [profile.dev.package.backtrace] +# opt-level = 3 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..53d1f3d --- /dev/null +++ b/LICENSE @@ -0,0 +1,675 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. + diff --git a/README.adoc b/README.adoc new file mode 100644 index 0000000..2930ebc --- /dev/null +++ b/README.adoc @@ -0,0 +1,13 @@ += Darktide P2P +:idprefix: +:idseparator: +:toc: macro +:toclevels: 1 +:!toc-title: +:caution-caption: :fire: +:important-caption: :exclamtion: +:note-caption: :paperclip: +:tip-caption: :bulb: +:warning-caption: :warning: + +An engine plugin for Warhammer 40,000 Darktide that implements peer-to-peer networking. diff --git a/lib/dt_p2p/.gitignore b/lib/dt_p2p/.gitignore new file mode 100644 index 0000000..4fffb2f --- /dev/null +++ b/lib/dt_p2p/.gitignore @@ -0,0 +1,2 @@ +/target +/Cargo.lock diff --git a/lib/dt_p2p/Cargo.toml b/lib/dt_p2p/Cargo.toml new file mode 100644 index 0000000..97ff094 --- /dev/null +++ b/lib/dt_p2p/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "dt_p2p" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] + +[lib] +crate-type = ["cdylib", "lib"] + +[build-dependencies] +bindgen = "0.65.1" diff --git a/lib/dt_p2p/build.rs b/lib/dt_p2p/build.rs new file mode 100644 index 0000000..9cfda19 --- /dev/null +++ b/lib/dt_p2p/build.rs @@ -0,0 +1,22 @@ +extern crate bindgen; + +use std::env; +use std::path::PathBuf; + +const HEADER_NAME: &str = "stingray_sdk.h"; + +fn main() { + println!("cargo:rerun-if-changed={}", HEADER_NAME); + + let bindings = bindgen::Builder::default() + .header(HEADER_NAME) + .clang_arg("-Istingray_sdk/") + .parse_callbacks(Box::new(bindgen::CargoCallbacks)) + .generate() + .expect("Unable to generate bindings"); + + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("Couldn't write bindings!"); +} diff --git a/lib/dt_p2p/src/lib.rs b/lib/dt_p2p/src/lib.rs new file mode 100644 index 0000000..9ebdc78 --- /dev/null +++ b/lib/dt_p2p/src/lib.rs @@ -0,0 +1,6 @@ +mod stingray_sdk; + +#[cfg(test)] +mod tests { + use super::*; +} diff --git a/lib/dt_p2p/src/stingray_sdk.rs b/lib/dt_p2p/src/stingray_sdk.rs new file mode 100644 index 0000000..b6ccf39 --- /dev/null +++ b/lib/dt_p2p/src/stingray_sdk.rs @@ -0,0 +1,7 @@ +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(clippy::type_complexity)] +#![allow(unused)] + +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); diff --git a/lib/dt_p2p/stingray_sdk.h b/lib/dt_p2p/stingray_sdk.h new file mode 100644 index 0000000..9d487c1 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk.h @@ -0,0 +1 @@ +#include "engine_plugin_api/plugin_api.h" diff --git a/lib/dt_p2p/stingray_sdk/LICENSE.md b/lib/dt_p2p/stingray_sdk/LICENSE.md new file mode 100644 index 0000000..33b98cf --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/LICENSE.md @@ -0,0 +1,13 @@ +Copyright 2017 Autodesk Inc. http://www.autodesk.com + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/lib/dt_p2p/stingray_sdk/editor_foundation/stingray.d.ts b/lib/dt_p2p/stingray_sdk/editor_foundation/stingray.d.ts new file mode 100644 index 0000000..89e39e6 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/editor_foundation/stingray.d.ts @@ -0,0 +1,66 @@ +declare module "stingray" { + import 'common/js-extensions'; + const stingray: Stingray; + export = stingray; +} +declare module "app" { + import 'angular-bootstrap'; + import 'angular-growl'; + var app: any; + export = app; +} +declare module "base" { + var baseFileName: string; + function _initModule(): Promise; + function _loadModule(): Promise; + function _keyBinding(): void; + export { baseFileName as name, _initModule as init, _loadModule as run, _keyBinding as initKeyBinding }; +} +declare module "program" { + var baseFileName: string; + function loadSystem(): Promise; + export { baseFileName as name, loadSystem as run }; +} +declare module "service" { + function runService(): Promise; + const name: string | boolean; + export { name, runService as run }; +} +declare module "editor" { + export function run(doNotRunBaseModule?: boolean): any; + export function initKeyBinding(): void; + export const name = "editor"; +} +declare module "window" { + import 'docking/docking-service'; + import 'docking/docking-directive'; +} +declare module "services/thumbnail-service" { + namespace ThumbnailService { + const DISCARDED_REQUEST: Promise; + const THUMBNAIL_SIZE = 256; + class ThumbnailError extends Error { + name: string; + constructor(name: any, msg: any); + } + class Thumbnail { + path: string; + url: string; + time: number; + constructor(path: any, url: any); + } + class ThumbnailJob { + hash: number; + resourcePath: string; + reject: (reason: any) => void; + resolve: (value?: {} | PromiseLike<{}>) => void; + promise: Promise<{}>; + private resourceType; + private resourceName; + constructor(resourceName: any, resourceType: any); + post(): any; + } + function generateThumbnail(resourcePath: any): Promise; + } + export = ThumbnailService; +} diff --git a/lib/dt_p2p/stingray_sdk/editor_foundation/types.d.ts b/lib/dt_p2p/stingray_sdk/editor_foundation/types.d.ts new file mode 100644 index 0000000..ef20a7b --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/editor_foundation/types.d.ts @@ -0,0 +1,271 @@ +/** + * Stingray foundation APIs. + */ +interface Stingray { + + config: string; + + env: { + version: string; + coreDir: string; + } + + /** + * Indicates if the system is ran through Team City. + */ + teamCity: any | boolean; + + /** + * Checks if we are running in development mode. + */ + isDev: () => boolean; + + /** + * Checks the framework is running tests. + * @returns {boolean} true if it is running tests. + */ + isRunningTests: () => boolean; + + /** + * Extract query param value for the window URL chain (e.g. from current window to top window) + * @param {string} name - Name of the query param + * @param {boolean} [firstLevelOnly] - Only check the URL of the current window. + */ + getParameterByName: (name: string, firstLevelOnly?: boolean) => string|boolean; + + /** + * Returns a GUID + * RFC 4122 Version 4 Compliant solution: + * http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript + */ + guid: () => string; + + /** + * @deprecated + * Checks if object is a promise + */ + isPromise: (promise: Promise) => boolean; + + prependToLogMessage: (type, message) => string; + + /** + * Hijack logs to prepend [DEBUG|INFO|ERROR] tags + * @param {string} pageTitle - Page title used if the document don't have any. + */ + hijackConsole: (pageTitle: string) => void; + + /** + * Returns an global angular service by name. + * @param serviceName {string} service to be fetched. + */ + getService: (serviceName: string) => Promise; + + /** + * Emit a global event in the system. + */ + emitEvent: (name: string, ...args) => Promise; + + loadNativeExtension: (path: string) => string; + unloadNativeExtension: (id: string) => boolean; + + loadAsyncExtension: (path: string) => Promise; + unloadAsyncExtension: (id: string) => Promise; + + hostExecute: (type: string, firstArg?: any) => Promise; + + openDevTools: () => void; + + location: LocationApi; + host: HostApi; + fs: FileSystemApi; + path: PathApi; +} + +/** + * Generic functions to manipulate page location. + */ +interface LocationApi { + removeParam: (paramName) => void; + addParam: (paramName, paramValue) => void; + toFilePath: (string) => string; +} + +/** + * Various host interaction API. + */ +interface HostApi { + quit: (exitCode?: number) => Promise; + getCommandLineSwitch: (name: string) => Promise; + createService: (name, path) => Promise; + setCursorStyle: (style: string) => Promise; + openWindow: (url: string, id?: string, options?: object) => Promise; + crash: () => {}; +} + +interface FileStats { + exists: boolean; + dir: string; + url: string; + size: number; + readonly: boolean; + hidden: boolean; + modified: number; +} + +interface FileSystemApi { + exists: (path: string) => boolean; + stats: (path: string) => FileStats; + + Filters: any; + FileNotify: any; + FileAction: any; + Permission: any; +} + +/** + * Stingray path manipulation API. + */ +interface PathApi { + sep: string; + delimiter: string; + + /** + * @description Extract the filename of a path + * @param {string} path + * @param {boolean} [withExtension=true] - Set to false if you want the extension to be omitted. + */ + basename: (path: string, withExtension: boolean) => string; + + dirname: (path: string) => string; + join: (path: string, ...paths: string[]) => string; + + absolute: (base: string, relative: string, isFileName?: boolean) => string; + clean: (path: string, addSeparatorsAtEnd?: boolean) => string; + resolve: (path: string) => string; + relative: (from: string, to: string) => string; + suffix: (path: string, noLeadingDot: boolean) => string; + ensureValid: (path: string) => string; + areEquals: (path1: string, path2: string) => boolean; + getFilePathWithoutExtension: (path: string) => string; + isFileOrFolderNameValid: (name: string) => boolean; +} + +interface Promise { + spread(a: (...args)=>PromiseLike, b?:()=>Promise): Promise; + finally(a, b): Promise; +} + +interface String { + hashCode: () => number; +} + +interface PromiseConstructor { + filter(array, promiseReturningFilter): Promise; + map(collection, promiseReturningTransformer): Promise; + series(items:any[]|Object, next:any, initialValue?:Promise): Promise; + while(predicate, action, result): Promise; + require(modules:string[]): Promise; + waterfall(funcs:Function[]):Promise; +} + +interface Console { + notice: Function; +} + +interface CefRequest { + request: string; + persistent: boolean; + onSuccess: (result: string) => void; + onFailure: (code:number, msg:string) => void; +} + +interface Window { + + stingray: Stingray; + + /** + * @typedef {object} CefRequest + * @property {string} request - JSON string sent to CEF as payload. + * @property {function} onSuccess - Callback if the CEF request succeeds. + * @property {function} onFailure - Callback if the CEF request fails. + * + * This function queries the CEF widget for a function. + * @name window.cefQuery + * @function + * @param {CefRequest} request - Request with success and failure callbacks + * @memberof window + */ + cefQuery: (request: CefRequest) => Promise; + + gc: () => void; + + layoutId: string; + isClosing: boolean; + isMainWindow: boolean; + bindLayout: Function; + saveLayout: Function; + removeLayout: Function; + resetLayout: Function; + reloadTab: Function; + setTitle: Function; + + id: string; + root: string; + rootHref: string; + coreRootHref: string; + debugging: boolean; + runningTest: boolean; + + isProgram: boolean; + isService: boolean; + isFocused: boolean; + aboutToReload: boolean; + + hide: ()=>void; + show: ()=>void; +} + +interface Document { + // Document Editing Model Extensions + getParentTab: Function; + getToolName: () => string; +} + +interface RequireInternals { + contexts: {_:{config:{paths:object}}}; +} + +interface Require { + s: RequireInternals; + resolvable: Function; +} + +interface WindowEventMap extends GlobalEventHandlersEventMap { + "ConsoleMessage": CustomEvent; +} + +interface OffHandler { (): any; promise: Promise; } + +// Module not (yet) ported to TypeScript +declare module 'lodash'; + +declare module 'common/asset-utils'; +declare module 'common/keycodes'; +declare module 'common/context-menu-utils'; + +declare module 'components/mithril-ext'; +declare module 'components/button'; +declare module 'components/textbox'; + +declare module 'extensions/parser-utils'; +declare module 'extensions/services'; +declare module 'extensions/events'; + +declare module 'extensions/menus'; + +declare module 'services/host-service'; +declare module 'services/level-editing-service'; +declare module 'services/log-service'; +declare module 'services/settings-service'; +declare module 'services/plugin-service'; +declare module 'services/event-service'; diff --git a/lib/dt_p2p/stingray_sdk/editor_plugin_api/editor_plugin_api.h b/lib/dt_p2p/stingray_sdk/editor_plugin_api/editor_plugin_api.h new file mode 100644 index 0000000..9d36089 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/editor_plugin_api/editor_plugin_api.h @@ -0,0 +1,339 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/* + This file defines the Plugin API for the editor. + + The plugin interface is based around a single function: + + __declspec(dllexport) void *get_editor_plugin_api(unsigned plugin_api_id); + + The API ID is an integer that uniquely identify a specific version of a particular service. + If the plugin can provide the service it returns a pointer to an API struct that contains + function pointers for using the service. + + For ABI compatibility and simplicity, only C code is used in the interfaces. + + This method is used both by the plugins to provide services to the editor and by the editor + to provide services to the plugins. For the second case, the editor sends a function: + + void *get_editor_api(unsigned api_id); + + To the plugins when they are initialized. The plugins can use this function to query for + editor interfaces. + + If you need to make big changes to an API, so that it is no longer backwards compatible + with the old API, you should create a new API_ID identifier and make sure that the old + API_ID identifier still returns the old API. That way, the code will continue to work + with older plugins that use the old API, while still providing new functionality in the + new API. + + Note that during development, the APIs may change frequently. It is only when we lock an + API down for public release that we need to be careful about version management and + backwards compatibility. + + Note that all the functions in the APIs are not described in this header file, because in + many cases they are just thin wrappers around existing editor systems. +*/ + +/* Plugin API_IDs for the different services that a plugin can implement. */ +enum EditorPluginApiID +{ + EDITOR_PLUGIN_SYNC_API_ID = 0, + EDITOR_PLUGIN_ASYNC_API_ID +}; + +/* Editor API_IDs for the different services the editor offers. */ +enum EditorApiID { + EDITOR_API_ID = 0, + EDITOR_API_V2_ID = 1, + CONFIGDATA_API_ID = 2, + EDITOR_LOGGING_API_ID = 3, + EDITOR_EVAL_API_ID = 4, + EDITOR_ASYNC_API_ID = 5 +#if defined(_FUNCTIONAL_) + , EDITOR_API_V3_ID = 6 +#endif + , EDITOR_ALLOCATOR_ID = 7 +}; + +enum ProcessId +{ + BROWSER = 0, + RENDERER +}; + +#define CONFIG_DATA_VALUE_TYPE_BITS 3 +#define CONFIG_DATA_VALUE_TAG_BITS 29 + +/* Primitive config value types */ +enum { + CD_TYPE_NULL = 0, + CD_TYPE_BOOL = 1, + CD_TYPE_NUMBER = 2, + CD_TYPE_STRING = 3, + CD_TYPE_HANDLE = 4, + CD_TYPE_ARRAY = 5, + CD_TYPE_OBJECT = 6, + CD_TYPE_TRUE, CD_TYPE_FALSE, + CD_TYPE_UNDEFINED = CD_TYPE_NULL +}; + +struct ConfigValueStruct { + struct { + unsigned type : CONFIG_DATA_VALUE_TYPE_BITS; + unsigned tag : CONFIG_DATA_VALUE_TAG_BITS; + }; + + union { + double _number; + bool _bool; + }; + + union { + void* _allocator; + void* _object; + void* _array; + void* _data; + }; +}; +typedef struct ConfigValueStruct* ConfigValue; +typedef const ConfigValue ConstConfigValue; +typedef ConfigValueStruct* ConfigValueArgs; +typedef ConfigValue* ConfigValueResult; + +struct ConfigHandleObject; +typedef ConfigHandleObject* ConfigHandle; + +/* Callback used to deallocate a config value user handle */ +typedef void(*cd_handle_dealloc)(ConfigHandle handle); + +/* This function can be used by the plugin to query for editor API. */ +typedef void *(*GetEditorApiFunction)(unsigned api); + +/* + This is the main interface provided by the plugins. The functions in this interface will + be called at various points during the editor's setup and shutdown sequence. + + The plugin is not obligated to implement all these functions. You can return NULL for the + functions that you do not support. +*/ +struct EditorPluginSyncApi +{ + /* Called once the plugin has been loaded. */ + void (*plugin_loaded)(GetEditorApiFunction get_editor_api); + + /* Returns the name of the plugin. */ + const char *(*get_name)(); + + /* Returns the version of the plugin. A version is a string of format 1.0.0.0 */ + const char *(*get_version)(); + + /* Called when the plugins needs to be shutdown */ + void (*shutdown)(GetEditorApiFunction get_editor_api); +}; + +struct EditorPluginAsyncApi +{ + /* Called once the plugin has been loaded. */ + void (*plugin_loaded)(GetEditorApiFunction get_editor_api); + + /* Returns the name of the plugin. */ + const char *(*get_name)(); + + /* Returns the version of the plugin. A version is a string of format 1.0.0.0 */ + const char *(*get_version)(); + + /* Called when the plugins needs to be shutdown */ + void (*shutdown)(GetEditorApiFunction get_editor_api); +}; + +struct EditorApi +{ + typedef ConfigValue (*NativeFunctionHandler)(ConfigValueArgs args, int num); + + /* Used to register a synchronous function that is executed on the render thread. Can be called using namespace.YOURFUNCTIONNAME(); */ + bool (*register_native_function)(const char *ns, const char *name, NativeFunctionHandler handler); + + /* Used to unregister a previously registered native function. */ + bool (*unregister_native_function)(const char *ns, const char *name); +}; + +struct EditorApi_V2 +{ + typedef ConfigValue (*NativeFunctionHandler)(ConfigValueArgs args, int num, GetEditorApiFunction get_editor_api); + + /* Used to register a synchronous function that is executed on the render thread. Can be called using namespace.YOURFUNCTIONNAME(); */ + bool (*register_native_function)(const char *ns, const char *name, NativeFunctionHandler handler); + + /* Used to unregister a previously registered native function. */ + bool (*unregister_native_function)(const char *ns, const char *name); +}; + +struct EditorAsyncApi +{ + typedef ConfigValue (*AsyncFunctionHandler)(ConfigValueArgs args, int num, GetEditorApiFunction get_editor_api); + + /* Used to register an asynchronous function that is executed on the browser thread. Can be called using stingray.hostExecute('your-function-name', ...); */ + bool (*register_async_function)(const char *name, AsyncFunctionHandler handler); + + /* Used to unregister a previously registered async function. */ + bool (*unregister_async_function)(const char *name); + + /* Used to register an asynchronous function that is executed on the gui thread. Can be called using stingray.hostExecute('your-function-name', ...); */ + bool (*register_async_gui_function)(const char *name, AsyncFunctionHandler handler); + + /* Used to unregister a previously registered async gui function. */ + bool (*unregister_async_gui_function)(const char *name); +}; + +struct EditorAllocatorObject; +typedef EditorAllocatorObject* EditorAllocator; +typedef void * (*EditorAllocateHandler) (size_t size, size_t align, void *param); +typedef size_t (*EditorDeallocateHandler) (void* ptr, void *param); + +struct EditorAllocatorApi +{ + EditorAllocator (*system_default)(); + EditorAllocator (*create)(const char* name, EditorAllocateHandler alloc_handler, EditorDeallocateHandler dealloc_handler, void* user_data); + void (*destroy)(EditorAllocator); +}; + +struct ConfigDataApi +{ + /* Create a new config value. It's type will be defined when you assign a value */ + ConfigValue (*make)(EditorAllocator allocator); + + /* Releases the memory used by the config value. */ + void (*free)(ConfigValue value); + + /* Creates a config value that is null. */ + ConfigValue(*nil)(); + + /* Returns the type of a config value, see CD_TYPE_* */ + int (*type)(ConfigValue value); + + /* Returns the boolean value of the config value. */ + int (*to_bool)(ConfigValue value); + + /* Returns the numerical value of the config value. */ + double (*to_number)(ConfigValue value); + + /* Returns the string value of the config value. */ + const char *(*to_string)(ConfigValue value); + + /* Returns the user handle of the config value. */ + ConfigHandle (*to_handle)(ConfigValue value); + + /* Returns the deallocator of the user handle config value. */ + cd_handle_dealloc (*to_handle_deallocator)(ConfigValue value); + + /* Defines the config value as a boolean value. */ + void(*set_bool)(ConfigValue value, int b); + + /* Defines the config value as a numerical value. */ + void(*set_number)(ConfigValue value, double n); + + /* Defines the config value as a string value. */ + void(*set_string)(ConfigValue value, const char *s); + + /* Defines the config value as a user handle. */ + void(*set_handle)(ConfigValue value, ConfigHandle handle, cd_handle_dealloc deallocator); + + /* Defines the config value as an array. */ + ConfigValueArgs(*set_array)(ConfigValue value, int size); + + /* Defines the config value as an object. */ + void(*set_object)(ConfigValue value); + + /* Returns the number of element of the config value. */ + int (*array_size)(ConfigValue arr); + + /* Returns an element config value of a config value array. */ + ConfigValue (*array_item)(ConfigValue arr, int i); + + /* Adds an elements to a config value array. */ + ConfigValue (*push)(ConfigValue array, ConfigValue item); + + /* Returns the number of properties of a config value object. */ + int (*object_size)(ConfigValue object); + + /* Returns the property name of an object field. */ + const char *(*object_key)(ConfigValue object, int i); + + /* Returns the property value of an object field. */ + ConfigValue(*object_value)(ConfigValue object, int i); + + /* Returns the property value of an object field by matching its property + * key if it exists. */ + ConfigValue(*object_lookup)(ConfigValue object, const char *key); + + /* Adds a null property. */ + ConfigValue(*add_nil)(ConfigValue object, const char *key); + + /* Adds a boolean property. */ + ConfigValue(*add_bool)(ConfigValue object, const char *key, int b); + + /* Adds a numerical property. */ + ConfigValue(*add_number)(ConfigValue object, const char *key, double n); + + /* Adds a string property. */ + ConfigValue(*add_string)(ConfigValue object, const char *key, const char* s); + + /* Adds an object property. */ + ConfigValue(*add_object)(ConfigValue object, const char *key, ConfigValue o); + + /* Adds an array property. */ + ConfigValue(*add_array)(ConfigValue object, const char *key, ConfigValue a); + + /* Alias to object_lookup, to find a property by name. */ + ConfigValue(*get)(ConfigValue object, const char *key); + + /* Sets the config value of a property by name. */ + ConfigValue(*set)(ConfigValue object, const char *key, ConfigValue value); +}; + +struct EditorLoggingApi +{ + /* Used to print only in the dev tools console. */ + void (*debug)(const char *message); + + /* Used to print an information in the stingray console. */ + void (*info)(const char *message); + + /* Used to print a warning in the stingray console. */ + void (*warning)(const char *message); + + /* Used to print an error in the stingray console. */ + void (*error)(const char *message); +}; + +struct EditorEvalApi +{ + /* Used to evaluate a javascript code in the global context. `return_value` and `exception` are optional. + * If an exception is thrown and `exception` is not null, it will be populated with an object + * {'message': exception_message}. + */ + bool (*eval)(const char *js_code, ConfigValue return_value, ConfigValue exception); +}; + +#ifdef __cplusplus +} +#endif + + +#if defined(__cplusplus) && defined(_FUNCTIONAL_) +struct EditorApi_V3 +{ + typedef std::function NativeFunctionHandler; + + /* Used to register a synchronous function that is executed on the render thread. Can be called using namespace.YOURFUNCTIONNAME(); */ + bool (*register_native_function)(const char *ns, const char *name, NativeFunctionHandler handler); + + /* Used to unregister a previously registered native function. */ + bool (*unregister_native_function)(const char *ns, const char *name); +}; +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_actor.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_actor.h new file mode 100644 index 0000000..faf296e --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_actor.h @@ -0,0 +1,72 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct ActorCApi +{ + int (*is_collision_enabled) (ActorPtr actor); + int (*is_scene_query_enabled) (ActorPtr actor); + int (*is_gravity_enabled) (ActorPtr actor); + + void (*set_collision_enabled) (ActorPtr actor, int enabled); + void (*set_scene_query_enabled) (ActorPtr actor, int enabled); + void (*set_gravity_enabled) (ActorPtr actor, int enabled); + + int (*is_static) (ActorPtr actor); + int (*is_dynamic) (ActorPtr actor); + int (*is_physical) (ActorPtr actor); + int (*is_kinematic) (ActorPtr actor); + void (*set_kinematic) (ActorPtr actor, int enabled); + + float (*mass) (ActorPtr actor); + float (*linear_damping) (ActorPtr actor); + float (*angular_damping) (ActorPtr actor); + void (*set_linear_damping) (ActorPtr actor, float value); + void (*set_angular_damping) (ActorPtr actor, float value); + CApiVector3 (*center_of_mass) (ActorPtr actor); + + CApiVector3 (*position) (ActorPtr actor); + CApiQuaternion (*rotation) (ActorPtr actor); + CApiMatrix4x4 (*pose) (ActorPtr actor); + + void (*teleport_position) (ActorPtr actor, ConstVector3Ptr position); + void (*teleport_rotation) (ActorPtr actor, ConstQuaternionPtr rotation); + void (*teleport_pose) (ActorPtr actor, ConstMatrix4x4Ptr pose); + + void (*set_velocity) (ActorPtr actor, ConstVector3Ptr velocity); + void (*set_angular_velocity) (ActorPtr actor, ConstVector3Ptr velocity); + + CApiVector3 (*velocity) (ActorPtr actor); + CApiVector3 (*angular_velocity) (ActorPtr actor); + CApiVector3 (*point_velocity) (ActorPtr actor, ConstVector3Ptr point); + + void (*add_impulse) (ActorPtr actor, ConstVector3Ptr amount); + void (*add_velocity) (ActorPtr actor, ConstVector3Ptr amount); + void (*add_torque_impulse) (ActorPtr actor, ConstVector3Ptr amount); + void (*add_angular_velocity) (ActorPtr actor, ConstVector3Ptr amount); + + void (*add_impulse_at) (ActorPtr actor, ConstVector3Ptr impulse, ConstVector3Ptr position); + void (*add_velocity_at) (ActorPtr actor, ConstVector3Ptr velocity, ConstVector3Ptr position); + + void (*push) (ActorPtr actor, ConstVector3Ptr velocity, float mass); + void (*push_at) (ActorPtr actor, ConstVector3Ptr velocity, float mass, ConstVector3Ptr position); + + int (*is_sleeping) (ActorPtr actor); + void (*wake_up) (ActorPtr actor); + void (*put_to_sleep) (ActorPtr actor); + + void (*debug_draw) (ActorPtr actor, LineObjectPtr line_object, ConstVector4Ptr optional_color, ConstMatrix4x4Ptr optional_camera_pose); + + UnitRef (*unit) (ActorPtr actor); + unsigned (*node) (ActorPtr actor); + void (*set_collision_filter) (ActorPtr actor, unsigned collision_filter_id32); + unsigned (*initial_shape_template) (ActorPtr actor, unsigned shape_index); // returns IdString32.id of the initial shape template name. +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_application.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_application.h new file mode 100644 index 0000000..3359053 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_application.h @@ -0,0 +1,43 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct ApplicationCApi +{ + unsigned (*num_worlds) (); + WorldPtr (*world) (unsigned index); + WorldPtr (*new_world) (ConstWorldConfigPtr optional); + WorldPtr (*main_world) (); + void (*release_world) (WorldPtr); + void (*render_world) (WorldPtr, ConstCameraPtr, ConstViewportPtr, ConstShadingEnvironmentPtr, ConstWindowPtr optional); + CApiWorldConfig (*get_default_world_settings) (); + + const char* (*build) (); + const char* (*platform) (); + const char* (*build_identifier) (); + const char* (*sysinfo) (); + ConstConfigRootPtr (*settings_root) (); + + ViewportPtr (*create_viewport) (WorldPtr, unsigned viewport_template_name_id32); + void (*destroy_viewport) (WorldPtr, ViewportPtr); + unsigned (*can_get) (uint64_t type_id64, uint64_t name_id64); + + void (*quit) (int exit_code); + + double (*time_since_launch) (); + void (*sleep) (unsigned milliseconds); + void (*set_time_step_policy) (const struct TimeStepPolicyWrapper* const policies, unsigned num_policies); + struct TimeStepPolicyWrapper (*get_time_step_policy) (enum TimeStepPolicyType type); + + /* The argv strings will be returned through the MultipleStringsBuffer you provide. + The function call returns the total number of bytes required to store all argv in the buffer. */ + unsigned (*argv) (struct MultipleStringsBuffer* const out_result, unsigned buffer_size); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_assert.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_assert.h new file mode 100644 index 0000000..e878119 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_assert.h @@ -0,0 +1,11 @@ +#pragma once + +namespace plugin_c_api {namespace api_assert_global { + extern void crash_jump(int line, const char *file, const char *assert, const char *msg); +}} + +#if defined(DEVELOPMENT) + #define API_ASSERT(test, msg, ...) if (!(test)) { plugin_c_api::api_assert_global::crash_jump(__LINE__, __FILE__, #test, stingray::eprintf(msg, ## __VA_ARGS__)); } +#else + #define API_ASSERT(test, msg, ...) ((void)0) +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_camera.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_camera.h new file mode 100644 index 0000000..f211ba6 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_camera.h @@ -0,0 +1,58 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct CameraCApi +{ + ConstVector3Ptr (*local_position)(ConstCameraPtr camera_pointer); + CApiQuaternion (*local_rotation)(ConstCameraPtr camera_pointer); + ConstVector3Ptr (*local_scale)(ConstCameraPtr camera_pointer); + ConstLocalTransformPtr (*local_pose)(ConstCameraPtr camera_pointer); + + void (*set_local_position)(CameraPtr camera_pointer, UnitRef unit_ref, ConstVector3Ptr position_pointer); + void (*set_local_rotation)(CameraPtr camera_pointer, UnitRef unit_ref, ConstQuaternionPtr quaternion_pointer); + void (*set_local_scale)(CameraPtr camera_pointer, UnitRef unit_ref, ConstVector3Ptr scale_pointer); + void (*set_local_pose)(CameraPtr camera_pointer, UnitRef unit_ref, ConstLocalTransformPtr local_transform_pointer); + + ConstVector3Ptr (*world_position)(ConstCameraPtr camera_pointer); + ConstMatrix4x4Ptr (*world_pose)(ConstCameraPtr camera_pointer); + // Performance-warning; Fetches the world_pose, extracts a Matrix3x3 from it and returns a copy on the stack. + CApiQuaternion (*world_rotation)(ConstCameraPtr camera_pointer); + + float (*near_range)(ConstCameraPtr camera_pointer); + float (*far_range)(ConstCameraPtr camera_pointer); + void (*set_near_range)(CameraPtr camera_pointer, float near_range); + void (*set_far_range)(CameraPtr camera_pointer, float far_range); + + float (*vertical_fov)(ConstCameraPtr camera_pointer, unsigned index); + void (*set_vertical_fov)(CameraPtr camera_pointer, float fov, unsigned index); + + enum CameraProjectionType (*projection_type)(ConstCameraPtr camera_pointer); + void (*set_projection_type)(CameraPtr camera_pointer, enum CameraProjectionType camera_projection_type); + void (*set_orthographic_view)(CameraPtr camera_pointer, float min_x, float max_x, float min_z, float max_z, unsigned index); + void (*set_post_projection_transform)(CameraPtr camera_pointer, ConstMatrix4x4Ptr transform); + + + void (*set_frustum)(CameraPtr camera_pointer, float left, float right, float bottom, float top, unsigned index); + void (*set_frustum_half_angles)(CameraPtr camera_pointer, float left_tan, float right_tan, float bottom_tan, float top_tan, unsigned index); + float (*inside_frustum)(ConstCameraPtr camera_pointer, ConstVector3Ptr point, ConstWindowPtr optional_window); + CApiMatrix4x4 (*projection)(ConstCameraPtr camera_pointer, float aspect_ratio); + + unsigned (*node)(ConstCameraPtr camera_pointer); + + enum CameraMode (*mode)(ConstCameraPtr camera_pointer); + void (*set_mode)(CameraPtr camera_pointer, enum CameraMode mode); + + void (*set_local)(CameraPtr camera_pointer, ConstMatrix4x4Ptr m, unsigned index); + + CApiVector3 (*screen_to_world)(CameraPtr camera_pointer, ConstVector3Ptr point, float depth, unsigned screen_width, unsigned screen_height); +}; + +#ifdef __cplusplus +} +#endif + diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_dynamic_script_data.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_dynamic_script_data.h new file mode 100644 index 0000000..d888b2d --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_dynamic_script_data.h @@ -0,0 +1,63 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct DynamicScriptDataUnitApi +{ + int (*has_data) (UnitRef, unsigned num_identifiers, ...); + void (*set_data) (UnitRef, DynamicScriptDataItem*, unsigned num_identifiers, ...); + DynamicScriptDataItem (*get_data) (UnitRef, unsigned num_identifiers, ...); +}; + +struct DynamicScriptDataCameraCApi +{ + int (*has_data) (CameraPtr, unsigned num_identifiers, ...); + void (*set_data) (CameraPtr, DynamicScriptDataItem*, unsigned num_identifiers, ...); + DynamicScriptDataItem (*get_data) (CameraPtr, unsigned num_identifiers, ...); +}; + +struct DynamicScriptDataLevelCApi +{ + int (*has_data) (LevelPtr, unsigned num_identifiers, ...); + void (*set_data) (LevelPtr, DynamicScriptDataItem*, unsigned num_identifiers, ...); + DynamicScriptDataItem (*get_data) (LevelPtr, unsigned num_identifiers, ...); +}; + +struct DynamicScriptDataWorldCApi +{ + int (*has_data) (WorldPtr, unsigned num_identifiers, ...); + void (*set_data) (WorldPtr, DynamicScriptDataItem*, unsigned num_identifiers, ...); + DynamicScriptDataItem (*get_data) (WorldPtr, unsigned num_identifiers, ...); +}; + +struct DynamicScriptDataViewportCApi +{ + int (*has_data) (ViewportPtr, unsigned num_identifiers, ...); + void (*set_data) (ViewportPtr, DynamicScriptDataItem*, unsigned num_identifiers, ...); + DynamicScriptDataItem (*get_data) (ViewportPtr, unsigned num_identifiers, ...); +}; + +struct DynamicScriptDataApplicationCApi +{ + int (*has_data) (unsigned num_identifiers, ...); + void (*set_data) (DynamicScriptDataItem*, unsigned num_identifiers, ...); + DynamicScriptDataItem (*get_data) (unsigned num_identifiers, ...); +}; + +struct DynamicScriptDataCApi +{ + struct DynamicScriptDataUnitApi* Unit; + struct DynamicScriptDataCameraCApi* Camera; + struct DynamicScriptDataLevelCApi* Level; + struct DynamicScriptDataWorldCApi* World; + struct DynamicScriptDataViewportCApi* Viewport; + struct DynamicScriptDataApplicationCApi* Application; +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_entity.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_entity.h new file mode 100644 index 0000000..38a9dfd --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_entity.h @@ -0,0 +1,112 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Manages the lifetime of an entity. */ +struct EntityManagerApi +{ + EntityRef (*create)(const void *owner); + void (*destroy)(EntityRef entity); + int (*is_alive)(EntityRef entity); + EntityRef (*spawn)(WorldPtr world, uint64_t entity_name_id64, const char *optional_debug_entity_name, ConstMatrix4x4Ptr transform); +}; + +/* Opaque struct representing the component api extension. */ +struct ComponentExtensionApi; + +/* Component property api. */ +typedef struct ComponentPropertyApi { + + /* Set component propery value. */ + void (*set_property)(ComponentPtr component, Instance i, EntityPropertyKey key, struct EntityPropertyValue value); + + /* Get component property value. */ + struct EntityPropertyValue (*get_property)(ComponentPtr component, Instance i, EntityPropertyKey key, struct AllocatorObject *temp_allocator); + +} ComponentPropertyApi; + +/* Component Api. */ +typedef struct ComponentApi +{ + /* Gets type name of the entity component. */ + uint32_t (*type_name)(); + + /* Gets the component manager for the specified world. */ + ComponentPtr (*component)(void *owner); + + /* Creates a new component instance. */ + Instance (*create)(ComponentPtr component, EntityRef entity, InstanceId instance_id); + + /* Destroy component instance. */ + void (*destroy)(ComponentPtr component, Instance i); + + /* Destroy all instances of the entity. */ + void (*destroy_all)(ComponentPtr component, EntityRef entity); + + /* Gets the component instance from the specified component id. */ + Instance (*lookup_instance)(ComponentPtr component, EntityRef entity, InstanceId id); + + /* Gets the component instance id from the specified component instance. */ + struct EntityInstanceId (*lookup_instance_id)(ComponentPtr component, Instance i); + + /* Spawn component. */ + void (*spawn)(ComponentPtr component, const EntityRef *entities, unsigned num_intances, const unsigned *entity_indicies, const unsigned *instance_ids, const char *data); + + /* Set entity parent. */ + void (*set_parent)(ComponentPtr component, const EntityRef *entities, unsigned num_entities, const unsigned *parent_index); + + /* Called when the entity as been fully constructed and spawned. */ + void (*spawned)(ComponentPtr component, const EntityRef *entities, unsigned num_entities); + + /* Gets the first component instance for the entity. */ + Instance (*first_instance)(ComponentPtr component, EntityRef entity); + + /* Gets the next component instance. */ + Instance (*next_instance)(ComponentPtr component, Instance i); + + /* Gets the component property api. */ + ComponentPropertyApi *(*get_property_api)(); + + /* + Retrieves a pointer to the component type specific API. + To use this cast the ComponentExtensionApi pointer to to the relevant definition represented in it's header file. + */ + struct ComponentExtensionApi *(*get_extension_api)(); + +} ComponentApi; + +typedef ComponentApi *ComponentApiPtr; + +struct EntityCApi +{ + struct EntityManagerApi* Manager; + + /* + Retrieves a pointer to the Component API registered with the specified name. + To use the member functions of the specified Component API cast the ComponentApiPtr to the relevant definition represented in it's header file." + */ + ComponentApiPtr (*component_api)(uint32_t name_id32); + + /* Registers a pointer to a component api with the specified name, the caller is responsible for keeping it allocated. */ + void (*register_component_api)(uint32_t name_id32, ComponentApiPtr component_api); + + /* Returns true (1) if a component api with the specified name has already been registered. */ + int (*has_component_api)(uint32_t name_id32); + + /* Unregisters a component struct with the specified name. */ + void (*unregister_component_api)(uint32_t name_id32); + + /* Registers the entity component to the specified world. */ + void (*register_entity_component)(WorldPtr world_pointer, ComponentPtr component, struct ComponentApi *component_api); + + /* Unregisters the entity component from the specified world. */ + void (*unregister_entity_component)(WorldPtr world_pointer, ComponentPtr component); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_game_session.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_game_session.h new file mode 100644 index 0000000..d669c3b --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_game_session.h @@ -0,0 +1,56 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct GameSessionCApi_BoolPeerWrapper { + int bool_value; + PeerId peer; +}; + +struct GameSessionCApi +{ + int (*in_session_self) (GameSessionPtr); + int (*in_session) (GameSessionPtr, PeerId); + + PeerId (*host) (GameSessionPtr); + void (*make_host) (GameSessionPtr); + void (*shutdown_host) (GameSessionPtr); + int (*host_error_occured) (GameSessionPtr); + void (*migrate_host) (GameSessionPtr); + void (*disconnect_from_host) (GameSessionPtr); + + void (*add_peer) (GameSessionPtr, uint64_t); + PeerId (*peer) (GameSessionPtr, unsigned index); + unsigned (*num_peers) (GameSessionPtr); + int (*peer_is_synchronizing) (GameSessionPtr, unsigned index); + + UnitSynchronizerPtr (*unit_synchronizer) (GameSessionPtr); + + GameObjectId (*create_game_object_with_default_values) (GameSessionPtr, unsigned unit_type_id32); + GameObjectId (*create_game_object) (GameSessionPtr, unsigned unit_type_id32, struct GameObjectField* field_array, unsigned num_elements); + void (*destroy_game_object) (GameSessionPtr, GameObjectId); + int (*game_object_exists) (GameSessionPtr, GameObjectId); + + void (*remove_peer) (GameSessionPtr, PeerId, game_object_callback_function game_object_destroyed); + void (*leave) (GameSessionPtr); + + struct GameSessionCApi_BoolPeerWrapper (*broken_connection) (GameSessionPtr); + struct GameSessionCApi_BoolPeerWrapper (*wants_to_leave) (GameSessionPtr); + + void (*migrate_game_object) (GameSessionPtr, GameObjectId, PeerId new_owner, struct RPCCallback*); + unsigned (*num_game_objects) (GameSessionPtr); + GameObjectId (*game_object_id_from_index) (GameSessionPtr, unsigned); + PeerId (*game_object_owner) (GameSessionPtr, GameObjectId); + int (*game_object_owner_is_self) (GameSessionPtr, GameObjectId); + + void (*set_game_object_fields) (GameSessionPtr, GameObjectId, struct GameObjectField* field_array, unsigned num_elements); + struct GameObjectField (*game_object_field) (GameSessionPtr, GameObjectId, unsigned field_name_id32); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_gui.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_gui.h new file mode 100644 index 0000000..35a54cd --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_gui.h @@ -0,0 +1,104 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct GuiCApi +{ + unsigned (*triangle) (GuiPtr, ConstVector3Ptr p0, ConstVector3Ptr p1, ConstVector3Ptr p2, unsigned layer, ConstVector4Ptr optional_color, + MaterialPtr optional, ConstVector2Ptr optional_uv0, ConstVector2Ptr optional_uv1, ConstVector2Ptr optional_uv2); + void (*update_triangle) (GuiPtr, unsigned id, ConstVector3Ptr p0, ConstVector3Ptr p1, ConstVector3Ptr p2, unsigned layer, ConstVector4Ptr optional_color); + void (*destroy_triangle) (GuiPtr, unsigned id); + + unsigned (*rect) (GuiPtr, ConstVector2Ptr position, unsigned layer, ConstVector2Ptr size, ConstVector4Ptr optional_color, MaterialPtr optional_material); + void (*update_rect) (GuiPtr, unsigned id, ConstVector2Ptr position, unsigned layer, ConstVector2Ptr size, ConstVector4Ptr optional_color); + void (*destroy_rect) (GuiPtr, unsigned id); + + unsigned (*rect_3d) (GuiPtr, ConstMatrix4x4Ptr transform, ConstVector3Ptr position, unsigned layer, ConstVector2Ptr size, ConstVector4Ptr optional_color, MaterialPtr optional_material); + void (*update_rect_3d) (GuiPtr, unsigned id, ConstMatrix4x4Ptr transform, ConstVector3Ptr position, unsigned layer, ConstVector2Ptr size, ConstVector4Ptr optional_color); + void (*destroy_rect_3d) (GuiPtr, unsigned id); + + unsigned (*bitmap) (GuiPtr, MaterialPtr, ConstVector2Ptr position, unsigned layer, ConstVector2Ptr size, ConstVector4Ptr optional_color, ConstVector2Ptr optional_uv00, ConstVector2Ptr optional_uv11); + void (*update_bitmap) (GuiPtr, unsigned id, MaterialPtr, ConstVector2Ptr position, unsigned layer, + ConstVector2Ptr size, ConstVector4Ptr optional_color, ConstVector2Ptr optional_uv00, ConstVector2Ptr optional_uv11); + void (*destroy_bitmap) (GuiPtr, unsigned id); + + unsigned (*bitmap_3d) (GuiPtr, ConstMatrix4x4Ptr transform, MaterialPtr, ConstVector3Ptr position, unsigned layer, ConstVector2Ptr size, + ConstVector4Ptr optional_color, ConstVector2Ptr optional_uv00, ConstVector2Ptr optional_uv11); + void (*update_bitmap_3d) (GuiPtr, unsigned id, ConstMatrix4x4Ptr transform, MaterialPtr, ConstVector3Ptr position, unsigned layer, + ConstVector2Ptr size, ConstVector4Ptr optional_color, ConstVector2Ptr optional_uv00, ConstVector2Ptr optional_uv11); + void (*destroy_bitmap_3d) (GuiPtr, unsigned id); + + + unsigned (*text) (GuiPtr, const char* text, uint64_t font, float font_size, MaterialPtr, ConstVector2Ptr position, unsigned layer, float letter_spacing, ConstVector4Ptr optional_color); + void (*update_text) (GuiPtr, unsigned id, const char* text, uint64_t font, float font_size, MaterialPtr, ConstVector2Ptr position, unsigned layer, float letter_spacing, ConstVector4Ptr optional_color); + void (*destroy_text) (GuiPtr, unsigned id); + + unsigned (*text_3d) (GuiPtr, const char* text_3d, uint64_t font, float font_size, MaterialPtr, ConstMatrix4x4Ptr transform, + ConstVector3Ptr position, unsigned layer, ConstVector4Ptr optional_color, float letter_spacing); + void (*update_text_3d) (GuiPtr, unsigned id, const char* text, uint64_t font, float font_size, MaterialPtr, ConstMatrix4x4Ptr transform, + ConstVector3Ptr position, unsigned layer, ConstVector4Ptr optional_color, float letter_spacing); + void (*destroy_text_3d) (GuiPtr, unsigned id); + + struct TextExtentsResult (*text_extents) (GuiPtr, const char* text, uint64_t font, float font_size, float letter_spacing); + + /* Fills the row_length_buffer with the length of each row after having processed the text with word wrapping. + Returns the total number of rows. */ + unsigned (*word_wrap) (GuiPtr, const char* text, uint64_t font, float font_size, float width, const char* whitespace, + const char* soft_dividers, const char* return_dividers, float letter_spacing, unsigned* row_length_buffer, unsigned buffer_size); + + unsigned (*video)(GuiPtr gui_pointer, VideoPlayerPtr video_player, MaterialPtr material_pointer, + ConstVector2Ptr pos, unsigned layer, ConstVector2Ptr opt_size, ConstVector4Ptr opt_color); + void (*update_video)(GuiPtr gui_pointer, unsigned id, VideoPlayerPtr video_player, MaterialPtr material_pointer, + ConstVector2Ptr pos, unsigned layer, ConstVector2Ptr opt_size, ConstVector4Ptr opt_color); + void (*destroy_video)(GuiPtr gui_pointer, unsigned id); + + unsigned (*video_3d)(GuiPtr gui_pointer, VideoPlayerPtr video_player, ConstMatrix4x4Ptr transform, MaterialPtr material_pointer, + ConstVector3Ptr pos, unsigned layer, ConstVector2Ptr opt_size, ConstVector4Ptr opt_color); + void (*update_video_3d)(GuiPtr gui_pointer, unsigned id, VideoPlayerPtr video_player, ConstMatrix4x4Ptr transform, MaterialPtr material_pointer, + ConstVector3Ptr pos, unsigned layer, ConstVector2Ptr opt_size, ConstVector4Ptr opt_color); + void (*destroy_video_3d)(GuiPtr gui_pointer, unsigned id); + + void (*set_visible) (GuiPtr, int visible); + int (*is_visible) (GuiPtr); + + MaterialPtr (*material)(GuiPtr gui_pointer, uint64_t material_id64, const char *optional_debug_material_name); + MaterialPtr (*create_material)(GuiPtr gui_pointer, uint64_t material_id64, const char *optional_debug_material_name); + + int (*has_all_glyphs) (GuiPtr, const char* text, uint64_t font); + void (*move) (GuiPtr, float x, float y); + void (*move_3d) (GuiPtr, ConstMatrix4x4Ptr transform); + void (*reset) (GuiPtr); + + void (*resolution) (ViewportPtr optional_viewport, ConstWindowPtr optional_window, unsigned int *out_width, unsigned int *out_height); + CApiMatrix4x4 (*rotation_2d) (ConstVector2Ptr position_pointer, float angle, ConstVector2Ptr optional_pivot); + + /* Equivalent to vector4(255, r, g, b). */ + CApiVector4 (*color_rgb) (float r, float g, float b); + /* Equivalent to vector4(a, r, g, b). */ + CApiVector4 (*color_argb) (float a, float r, float g, float b); + + unsigned(*get_id) (GuiPtr); + + void (*set_video_playback_speed)(VideoPlayerPtr video_player, float speed); + void (*set_video_loop)(VideoPlayerPtr video_player, unsigned loop); + unsigned (*video_has_audio)(VideoPlayerPtr video_player); + StreamSourcePtr (*video_sound_stream_source)(VideoPlayerPtr video_player); + void (*set_video_sound_stream_enabled)(VideoPlayerPtr video_player, unsigned enabled); + unsigned (*video_number_of_frames)(VideoPlayerPtr video_player); + unsigned (*video_current_frame)(VideoPlayerPtr video_player); + unsigned (*video_times_looped)(VideoPlayerPtr video_player); + + /* Not available in Release builds. */ + unsigned (*texture_size) (uint64_t resource_id64, unsigned int *out_width, unsigned int *out_height); + GuiThumbnailPtr (*thumbnail_load_texture)(unsigned num_textures, uint64_t* names_id64); + GuiThumbnailPtr (*thumbnail_load_dds)(const char *path, uint64_t name_id64); + void (*thumbnail_unload)(GuiThumbnailPtr thumbnail); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_input.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_input.h new file mode 100644 index 0000000..68f335a --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_input.h @@ -0,0 +1,51 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct InputControllerCApi; +struct KeyboardCApi; +struct PS4PadCApi; +struct TouchInputCApi; +struct XBoxOnePadCApi; + +struct InputCApi +{ + struct InputControllerCApi *InputController; + struct KeyboardCApi *Keyboard; + struct PS4PadCApi *PS4Pad; + struct TouchInputCApi *Touch; + struct XBoxOnePadCApi *XBoxOnePad; + + void (*raw_input_queue) (struct RawInputEventWrapper* buffer, unsigned buffer_size); + unsigned (*raw_input_queue_size) (); + void (*add_remote_events)(unsigned event_count, struct RemoteEventWrapper* remote_events); + + CApiInputControllerPtr (*keyboard)(); + CApiInputControllerPtr (*mouse)(); + CApiInputControllerPtr (*tablet)(); + CApiInputControllerPtr (*touch_panel)(int index); + CApiInputControllerPtr (*simulated_touch_panel)(); + int (*num_touch_panels)(); + int (*num_pads)(); + CApiInputControllerPtr (*pad)(int index); + + void (*flush_controllers_state)(); + + CApiInputControllerPtr (*synergy_mouse)(); + CApiInputControllerPtr (*synergy_keyboard)(); + void (*synergy_connect)(struct SocketAddressWrapper* address, const char *client_name, int client_width, int client_height); + const char *(*synergy_clipboard)(); + + int (*num_windows_ps4_pads)(); + CApiInputControllerPtr (*windows_ps4_pad)(int index); + void (*scan_for_windows_ps4_pads)(); + void (*set_tablet_pen_service_properties)(uint64_t prop); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_input_controller.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_input_controller.h new file mode 100644 index 0000000..22509fc --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_input_controller.h @@ -0,0 +1,49 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct InputControllerCApi +{ + enum InputCategory (*category)(CApiInputControllerPtr input_controller); + const char *(*type)(CApiInputControllerPtr input_controller); + const char *(*name)(CApiInputControllerPtr input_controller); + + unsigned (*num_buttons)(CApiInputControllerPtr input_controller); + float (*button)(CApiInputControllerPtr input_controller, unsigned id); + int (*pressed)(CApiInputControllerPtr input_controller, unsigned id); + int (*released)(CApiInputControllerPtr input_controller, unsigned id); + unsigned (*any_pressed)(CApiInputControllerPtr input_controller); + unsigned (*any_released)(CApiInputControllerPtr input_controller); + void (*set_down_threshold)(CApiInputControllerPtr input_controller, float threshold); + float (*down_threshold)(CApiInputControllerPtr input_controller); + int (*num_axes)(CApiInputControllerPtr input_controller); + struct CApiVector3 (*axis)(CApiInputControllerPtr input_controller, unsigned axis_index, struct DeadZoneSetting *optional_deadzone_setting); + void (*dead_zone)(CApiInputControllerPtr input_controller, unsigned axis_index, struct DeadZoneSetting *out_deadzone_setting); + void (*set_dead_zone)(CApiInputControllerPtr input_controller, unsigned axis_index, struct DeadZoneSetting *deadzone_setting); + void (*set_rumble_enabled)(CApiInputControllerPtr input_controller, unsigned enabled); + unsigned(*num_rumble_motors)(CApiInputControllerPtr input_controller); + void (*set_rumble)(CApiInputControllerPtr input_controller, unsigned motor_id, float value); + unsigned (*rumble_effect)(CApiInputControllerPtr input_controller, unsigned motor_id, struct RumbleParameters *rumble_parameters); + void (*stop_rumble_effect)(CApiInputControllerPtr input_controller, unsigned motor_id, unsigned rumble_effect_id); + unsigned (*is_rumble_effect_playing)(CApiInputControllerPtr input_controller, unsigned motor_id, unsigned rumble_effect_id); + void (*stop_all_rumble_effects)(CApiInputControllerPtr input_controller, unsigned motor_id); + const char *(*button_name)(CApiInputControllerPtr input_controller, unsigned button_id); + const char *(*button_locale_name)(CApiInputControllerPtr input_controller, unsigned button_id); + unsigned (*button_id)(CApiInputControllerPtr input_controller, unsigned button_name_id32); + const char *(*axis_name)(CApiInputControllerPtr input_controller, unsigned axis_id); + unsigned (*axis_id)(CApiInputControllerPtr input_controller, unsigned axis_name_id32); + const char *(*rumble_motor_name)(CApiInputControllerPtr input_controller, unsigned motor_id); + unsigned (*rumble_motor_id)(CApiInputControllerPtr input_controller, unsigned rumble_motor_name_id32); + + unsigned (*active)(CApiInputControllerPtr input_controller); + unsigned (*connected)(CApiInputControllerPtr input_controller); + unsigned (*disconnected)(CApiInputControllerPtr input_controller); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_keyboard.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_keyboard.h new file mode 100644 index 0000000..f545aec --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_keyboard.h @@ -0,0 +1,18 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct KeyboardCApi +{ + const int *(*keystrokes)(CApiInputControllerPtr keyboard_input_controller, unsigned *out_num_keystrokes); +}; + +#ifdef __cplusplus +} +#endif + + diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_lan.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_lan.h new file mode 100644 index 0000000..ca72ec4 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_lan.h @@ -0,0 +1,47 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +enum LanCApi_LanLobbyState { LAN_LB_CREATING, LAN_LB_JOINING, LAN_LB_JOINED, LAN_LB_FAILED }; + +struct LanCApi +{ + void (*init_client) (uint64_t network_config_id64, unsigned port, uint64_t peer_id); + void (*shutdown_client) (); + + LanLobbyPtr (*create_lobby) (unsigned port, unsigned max_members); + LanLobbyPtr (*join_lobby) (const char* server_address, unsigned port); + void (*leave_lobby) (LanLobbyPtr); + enum LanCApi_LanLobbyState (*state) (LanLobbyPtr); + void (*set_data) (LanLobbyPtr, const char* key, const char* value); + const char* (*data) (ConstLanLobbyPtr, const char* key); + + void (*set_game_session_host) (LanLobbyPtr, uint64_t peer_id64); + void (*set_game_session_host_to_none) (LanLobbyPtr); + uint64_t (*game_session_host) (ConstLanLobbyPtr); + uint64_t (*lobby_host) (ConstLanLobbyPtr); + + unsigned (*num_members) (ConstLanLobbyPtr); + uint64_t (*member) (ConstLanLobbyPtr, unsigned index); + void (*kick) (LanLobbyPtr, uint64_t peer_id64); + + void (*set_member_data) (LanLobbyPtr, const char* key, const char* value); + const char* (*own_data) (LanLobbyPtr, const char* key); + const char* (*member_data) (LanLobbyPtr, uint64_t peer_id64, const char* key); + + LanLobbyBrowserPtr (*lobby_browser) (); + struct SocketAddressWrapper (*lobby_address) (ConstLanLobbyBrowserPtr, unsigned index); + unsigned (*num_lobbies) (ConstLanLobbyBrowserPtr); + const char* (*lobby_data) (LanLobbyBrowserPtr, unsigned index, const char* key); + void (*refresh) (LanLobbyBrowserPtr, unsigned port); + int (*is_refreshing) (ConstLanLobbyBrowserPtr); +}; + +#ifdef __cplusplus +} +#endif + diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_level.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_level.h new file mode 100644 index 0000000..cd574f9 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_level.h @@ -0,0 +1,60 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct LevelCApi +{ + WorldPtr (*world) (LevelPtr level_pointer); + void (*spawn_background) (LevelPtr level_pointer); + + UnitRef (*unit_by_index) (LevelPtr level_pointer, unsigned index); + unsigned (*unit_index) (LevelPtr level_pointer, UnitRef unit_ref); + unsigned (*num_units) (LevelPtr level_pointer); + + unsigned (*num_nested_levels) (LevelPtr level_pointer); + LevelPtr (*nested_level) (LevelPtr level_pointer, unsigned index); + + unsigned (*num_entities) (LevelPtr level_pointer); + EntityRef (*entity) (LevelPtr level_pointer, unsigned index); + + CApiVector3 (*random_point_inside_volume) (ConstLevelPtr level_pointer, unsigned volume_name_id32); + CApiVector3 (*next_random_point_inside_volume) (ConstLevelPtr level_pointer, unsigned volume_name_id32, int, int*); + int (*is_point_inside_volume) (ConstLevelPtr level_pointer, unsigned volume_name_id32, ConstVector3Ptr vector3_pointer); + int (*has_volume) (ConstLevelPtr level_pointer, unsigned volume_name_id32); + + void (*flow_event) (LevelPtr level_pointer, unsigned event_name_id32); + unsigned (*flow_variable_type) (LevelPtr level_pointer, unsigned variable_name_id32); + void* (*flow_variable) (LevelPtr level_pointer, unsigned variable_name_id32); + void (*set_flow_variable) (LevelPtr level_pointer, unsigned variable_name_id32, void* value); + + void (*trigger_event) (LevelPtr level_pointer, unsigned event_name_id32); + void (*trigger_level_loaded) (LevelPtr level_pointer); + void (*trigger_level_shutdown) (LevelPtr level_pointer); + void (*trigger_level_update) (LevelPtr level_pointer); + + ConstMatrix4x4Ptr (*pose) (LevelPtr level_pointer); + + ConstNavigationMeshPtr (*navigation_mesh)(ConstLevelPtr level_pointer); + + struct Vector3ArrayWrapper (*spline)(LevelPtr level_pointer, unsigned spline_name_id32); + unsigned (*num_splines)(LevelPtr level_pointer); + struct Vector3ArrayWrapper (*spline_by_index)(LevelPtr level_pointer, unsigned index); + + /* Begin development only functions */ + void (*set_pose)(LevelPtr level_pointer, ConstMatrix4x4Ptr pose); + void (*set_visibility)(LevelPtr level_pointer, int visible); + + struct OOBBWrapper (*box)(LevelPtr level_pointer); + + unsigned (*num_internal_units)(LevelPtr level_pointer); + void (*internal_units)(LevelPtr level_pointer, UnitRef* internal_units); + /* End development only functions */ +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_line_object.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_line_object.h new file mode 100644 index 0000000..d2d212d --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_line_object.h @@ -0,0 +1,29 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct LineObjectCApi +{ + void (*dispatch) (WorldPtr, LineObjectPtr); + void (*reset) (LineObjectPtr); + + void (*add_line) (LineObjectPtr, ConstVector4Ptr color, ConstVector3Ptr from, ConstVector3Ptr to); + void (*add_cone) (LineObjectPtr, ConstVector4Ptr color, ConstVector3Ptr from, ConstVector3Ptr to, float radius, unsigned num_segments, unsigned num_bars); + void (*add_circle) (LineObjectPtr, ConstVector4Ptr color, ConstVector3Ptr center, float radius, ConstVector3Ptr normal, unsigned num_segments); + void (*add_sphere) (LineObjectPtr, ConstVector4Ptr color, ConstVector3Ptr center, float radius, unsigned num_segments, unsigned num_parts); + void (*add_half_sphere) (LineObjectPtr, ConstVector4Ptr color, ConstVector3Ptr center, float radius, ConstVector3Ptr normal, unsigned num_segments, unsigned num_parts); + void (*add_box) (LineObjectPtr, ConstVector4Ptr color, ConstMatrix4x4Ptr pose, float radius, ConstVector3Ptr half_extents); + void (*add_capsule) (LineObjectPtr, ConstVector4Ptr color, ConstVector3Ptr from, ConstVector3Ptr to, float radius, unsigned num_segments, unsigned num_circles, unsigned num_bars); + void (*add_axes) (LineObjectPtr, ConstMatrix4x4Ptr pose, float length); + + /* Not available in Release builds. If camera_direction is supplied, back-facing triangles will get culled. */ + void (*add_unit_meshes) (LineObjectPtr, uint64_t unit_resource_name_id64, const char *optional_debug_unit_resource_name, ConstVector4Ptr color, ConstMatrix4x4Ptr pose, ConstVector3Ptr optional_camera_direction); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_material.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_material.h new file mode 100644 index 0000000..6d64231 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_material.h @@ -0,0 +1,25 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct MaterialCApi +{ + void (*set_scalar)(MaterialPtr material_pointer, unsigned variable_name_id32, float value); + void (*set_vector2)(MaterialPtr material_pointer, unsigned variable_name_id32, ConstVector2Ptr value); + void (*set_vector3)(MaterialPtr material_pointer, unsigned variable_name_id32, ConstVector3Ptr value); + void (*set_vector4)(MaterialPtr material_pointer, unsigned variable_name_id32, ConstVector4Ptr value); + + unsigned (*material_id)(ConstMaterialPtr material_pointer); + void (*set_shader_pass_flag)(MaterialPtr material_pointer, unsigned flag_name_id32, int enabled); + void (*set_texture)(MaterialPtr material_pointer, unsigned slot_name_id32, uint64_t texture_resource_name_id64, const char *optional_debug_texture_resource_name); + void (*set_resource)(MaterialPtr material_pointer, unsigned slot_name_id32, ConstRenderResourcePtr render_resource); + void (*set_matrix4x4)(MaterialPtr material_pointer, unsigned variable_name_id32, ConstMatrix4x4Ptr value); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_mesh.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_mesh.h new file mode 100644 index 0000000..cce4af8 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_mesh.h @@ -0,0 +1,38 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct MeshCApi +{ + unsigned (*num_materials) (ConstMeshPtr); + unsigned (*find_material) (ConstMeshPtr, unsigned name_id32); + MaterialPtr (*material) (MeshPtr, unsigned index); + unsigned (*node) (ConstMeshPtr); + + void (*set_shader_pass_flag) (MeshPtr, unsigned name_id32, int enabled); + struct BoundingVolumeWrapper (*bounding_volume) (MeshPtr); + void (*set_explicit_sort_value) (MeshPtr, unsigned sort_value); + + ConstVector3Ptr (*local_position) (ConstMeshPtr); + struct CApiQuaternion (*local_rotation) (ConstMeshPtr); + ConstVector3Ptr (*local_scale) (ConstMeshPtr); + ConstLocalTransformPtr (*local_pose) (ConstMeshPtr); + + void (*set_local_position) (MeshPtr, UnitRef, ConstVector3Ptr); + void (*set_local_rotation) (MeshPtr, UnitRef, ConstQuaternionPtr); + void (*set_local_scale) (MeshPtr, UnitRef, ConstVector3Ptr); + void (*set_local_pose) (MeshPtr, UnitRef, ConstLocalTransformPtr); + + ConstVector3Ptr (*world_position) (ConstMeshPtr); + ConstMatrix4x4Ptr (*world_pose) (ConstMeshPtr); + // Performance-warning; Fetches the world_pose, extracts a Matrix3x3 from it and returns a copy on the stack. + struct CApiQuaternion (*world_rotation) (ConstMeshPtr); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_mover.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_mover.h new file mode 100644 index 0000000..88f6b71 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_mover.h @@ -0,0 +1,35 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct MoverCApi +{ + UnitRef (*unit) (MoverPtr); + void (*set_position) (MoverPtr, ConstVector3Ptr); + CApiVector3 (*position) (MoverPtr); + + void (*move) (MoverPtr, ConstVector3Ptr offset, float delta_time); + struct MoverSeparateResult (*separate) (MoverPtr, float permitted_move_threshold); + struct MoverFitsAtResult (*fits_at) (MoverPtr, ConstVector3Ptr, float permitted_move_threshold); + + int (*collides_down) (MoverPtr); + int (*collides_up) (MoverPtr); + int (*collides_sides) (MoverPtr); + ActorPtr (*actor_colliding_down) (MoverPtr); + + unsigned (*standing_frames) (MoverPtr); + unsigned (*flying_frames) (MoverPtr); + + void (*set_collision_filter) (MoverPtr, unsigned collision_filter_id32); + float (*max_slope_angle) (MoverPtr); + void (*set_max_slope_angle) (MoverPtr, float); + float (*radius) (MoverPtr); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_network.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_network.h new file mode 100644 index 0000000..192fb44 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_network.h @@ -0,0 +1,32 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif +enum NetworkCApi_LogLevel +{ + NET_LOG_SILENT, NET_LOG_WARNINGS, NET_LOG_MESSAGES, NET_LOG_SPEW +}; + +struct NetworkCApi +{ + GameSessionPtr (*create_game_session) (); + GameSessionPtr (*game_session) (); + void (*shutdown_game_session) (); + PeerId (*peer_self) (); + + void (*update_receive) (float dt, struct RPCCallback* callback_functions); + void (*update_transmit) (); + void (*send_rpc) (unsigned message_name_id32, PeerId peer, struct RPCMessageParameter* parameter_array, unsigned num_parameters); + + int (*fatal_error_occured) (); + void (*write_dump_tag) (const char* msg); + void (*set_log_level) (enum NetworkCApi_LogLevel); +}; + +#ifdef __cplusplus +} +#endif + diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_physics_world.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_physics_world.h new file mode 100644 index 0000000..1cadedb --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_physics_world.h @@ -0,0 +1,41 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct PhysicsWorldCApi +{ + /* + The raycast, sweep and overlap function calls will return the total number of hits made as an unsigned. + Up to num_elements results will be stored in the pre-allocated out_buffer you provide. + */ + + unsigned (*raycast) (struct CollisionHit* out_buffer, unsigned num_elements, PhysicsWorldPtr, ConstVector3Ptr from, ConstVector3Ptr direction, + enum RaycastType, enum ActorTemplate, unsigned collision_filter_id32, float length); + + unsigned (*cast) (RaycastId, struct CollisionHit* out_buffer, unsigned num_elements, ConstVector3Ptr from, ConstVector3Ptr direction, float length); + + /* Returns a unique id that can be used with the cast() function as many times as needed. + The caller is responsible for deallocating this by calling destroy_raycast(). */ + RaycastId (*make_raycast) (PhysicsWorldPtr, enum RaycastType, enum ActorTemplate, unsigned collision_filter_id32); + void (*destroy_raycast) (RaycastId); + + unsigned (*overlap) (ActorPtr* out_buffer, unsigned num_elements, PhysicsWorldPtr, enum OverlapShape, ConstVector3Ptr optional_position, ConstQuaternionPtr optional_rotation, + ConstMatrix4x4Ptr optional_pose, ConstVector3Ptr optional_size, enum ActorTemplate, unsigned collision_filter_id32); + + unsigned (*linear_sphere_sweep) (struct CollisionHit* out_buffer, unsigned num_elements, PhysicsWorldPtr, ConstVector3Ptr from, ConstVector3Ptr to, + float radius, enum ActorTemplate, unsigned collision_filter_id32, int report_initial_overlap); + + unsigned (*linear_capsule_sweep) (struct CollisionHit* out_buffer, unsigned num_elements, PhysicsWorldPtr, ConstVector3Ptr from, ConstVector3Ptr to, ConstQuaternionPtr rotation, + float radius, float half_height, enum ActorTemplate, unsigned collision_filter_id32, int report_initial_overlap); + + unsigned (*linear_obb_sweep) (struct CollisionHit* out_buffer, unsigned num_elements, PhysicsWorldPtr, ConstVector3Ptr from, ConstVector3Ptr to, ConstVector3Ptr extents, + ConstQuaternionPtr rotation, enum ActorTemplate, unsigned collision_filter_id32, int report_initial_overlap); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4.h new file mode 100644 index 0000000..eb69598 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4.h @@ -0,0 +1,13 @@ +#pragma once + +#if defined(PS4) + #include +#else + #ifdef __cplusplus + extern "C" { + #endif + struct Ps4CApi; + #ifdef __cplusplus + } + #endif +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4_error_dialog.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4_error_dialog.h new file mode 100644 index 0000000..ea64237 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4_error_dialog.h @@ -0,0 +1,13 @@ +#pragma once + +#if defined(PS4) + #include +#else + #ifdef __cplusplus + extern "C" { + #endif + struct Ps4ErrorDialogCApi; + #ifdef __cplusplus + } + #endif +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4_ime_dialog.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4_ime_dialog.h new file mode 100644 index 0000000..c77b739 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4_ime_dialog.h @@ -0,0 +1,13 @@ +#pragma once + +#if defined(PS4) + #include +#else + #ifdef __cplusplus + extern "C" { + #endif + struct Ps4ImeDialogCApi; + #ifdef __cplusplus + } + #endif +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4_msg_dialog.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4_msg_dialog.h new file mode 100644 index 0000000..8fa0496 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4_msg_dialog.h @@ -0,0 +1,13 @@ +#pragma once + +#if defined(PS4) + #include +#else + #ifdef __cplusplus + extern "C" { + #endif + struct Ps4MsgDialogCApi; + #ifdef __cplusplus + } + #endif +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4_np_commerce_dialog.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4_np_commerce_dialog.h new file mode 100644 index 0000000..8c90016 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4_np_commerce_dialog.h @@ -0,0 +1,13 @@ +#pragma once + +#if defined(PS4) + #include +#else + #ifdef __cplusplus + extern "C" { + #endif + struct Ps4NpCommerceDialogCApi; + #ifdef __cplusplus + } + #endif +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4_types.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4_types.h new file mode 100644 index 0000000..9192963 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4_types.h @@ -0,0 +1,5 @@ +#pragma once + +#if defined(PS4) + #include +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4pad.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4pad.h new file mode 100644 index 0000000..227724e --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_ps4pad.h @@ -0,0 +1,18 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* This class is solely for managing PS4 Gamepads connected to a PC. */ +struct PS4PadCApi +{ + void (*set_light_bar_color)(CApiInputControllerPtr ps4pad_input_controller, ConstQuaternionPtr color); + unsigned (*user_id)(CApiInputControllerPtr ps4pad_input_controller); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_psn.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_psn.h new file mode 100644 index 0000000..eb070b0 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_psn.h @@ -0,0 +1,13 @@ +#pragma once + +#if defined(PS4) + #include +#else + #ifdef __cplusplus + extern "C" { + #endif + struct PsnCApi; + #ifdef __cplusplus + } + #endif +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_save_system.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_save_system.h new file mode 100644 index 0000000..81dd057 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_save_system.h @@ -0,0 +1,23 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct SaveSystemCApi +{ + int (*exists) (); + void (*close) (SaveToken); + + struct SaveSystemProgress (*get_progress) (SaveToken); + enum SaveSystemError (*get_loaded_data) (SaveToken, save_system_data_callback); + + SaveToken (*auto_load) (const char* filename); + SaveToken (*auto_save) (const char* filename, struct SaveParameter* parameter_array, unsigned num_parameters); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_scatter_system.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_scatter_system.h new file mode 100644 index 0000000..315ee19 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_scatter_system.h @@ -0,0 +1,36 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct ScatterSystemCApi +{ + /* Default values for make_brush parameters are: + ScatterFadeMethod::SCATTER_FADE_POP + fade_range: 5.0 + fade_from: (POP) 0.f (SCALE) 0.f (SLIDE_Z) -2.f + fade_to: (POP) 0.f (SCALE) 1.f (SLIDE_Z) 0.f + pool_size: UINT_MAX + preheat_pool: false + user_setting_density: true + */ + ScatterBrushId (*make_brush) (ScatterSystemPtr, uint64_t unit_id64, float spawn_distance, float unspawn_distance, enum ScatterFadeMethod, + float fade_range, float fade_from, float fade_to, unsigned pool_size, int preheat_pool, int user_setting_density); + + void (*destroy_brush) (ScatterSystemPtr, ScatterBrushId); + void (*destroy_all_brushes) (ScatterSystemPtr); + + ScatterUnitId (*spawn) (ScatterSystemPtr, ScatterBrushId, ConstVector3Ptr position, ConstQuaternionPtr optional_rotation); + void (*unspawn) (ScatterSystemPtr, ScatterUnitId); + + ScatterObserverId (*make_observer) (ScatterSystemPtr, ConstVector3Ptr position, ConstQuaternionPtr optional_rotation); + void (*destroy_observer) (ScatterSystemPtr, ScatterObserverId); + void (*move_observer) (ScatterSystemPtr, ScatterObserverId, ConstVector3Ptr position, ConstQuaternionPtr optional_rotation); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_touch_input.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_touch_input.h new file mode 100644 index 0000000..defa0c6 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_touch_input.h @@ -0,0 +1,37 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct TouchInputCApi +{ + CApiVector3 (*accelerator_resolution)(CApiInputControllerPtr touch_input_controller); + CApiVector2 (*resolution)(CApiInputControllerPtr touch_input_controller); + unsigned (*is_touch_up)(CApiInputControllerPtr touch_input_controller, unsigned contact_id); + unsigned (*is_touch_down)(CApiInputControllerPtr touch_input_controller, unsigned contact_id); + unsigned (*gesture_tap)(CApiInputControllerPtr touch_input_controller, CApiVector2 *out_location); + unsigned (*gesture_tap_sequence)(CApiInputControllerPtr touch_input_controller, CApiVector2 *out_location_sequence); + unsigned (*gesture_long_press)(CApiInputControllerPtr touch_input_controller, CApiVector2 *out_location); + unsigned (*gesture_pinch)(CApiInputControllerPtr touch_input_controller, TouchPinchGesture *out_pinch_gesture); + unsigned (*gesture_rotate)(CApiInputControllerPtr touch_input_controller, TouchRotationGesture *out_rotation_gesture); + enum SwipeDirection (*gesture_swipe)(CApiInputControllerPtr touch_input_controller); + unsigned (*is_primary)(CApiInputControllerPtr touch_input_controller, unsigned contact_id); + float (*size)(CApiInputControllerPtr touch_input_controller, unsigned contact_id); + float (*minor_axis_size)(CApiInputControllerPtr touch_input_controller, unsigned contact_id); + float (*major_axis_size)(CApiInputControllerPtr touch_input_controller, unsigned contact_id); + float (*pressure)(CApiInputControllerPtr touch_input_controller, unsigned contact_id); + enum TouchEdge (*edge)(CApiInputControllerPtr touch_input_controller, unsigned contact_id); + CApiVector3 (*location)(CApiInputControllerPtr touch_input_controller, unsigned contact_id); + CApiVector3 (*location_delta)(CApiInputControllerPtr touch_input_controller, unsigned contact_id); + unsigned (*has_contact)(CApiInputControllerPtr touch_input_controller, unsigned contact_id); + unsigned (*contacts)(CApiInputControllerPtr touch_input_controller, unsigned out_contact_ids[MAX_TOUCH_CONTACTS]); + unsigned (*num_contacts)(CApiInputControllerPtr touch_input_controller); + void (*set_enabled)(CApiInputControllerPtr simulated_touch_input_controller, unsigned enabled); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_types.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_types.h new file mode 100644 index 0000000..6c4b85e --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_types.h @@ -0,0 +1,627 @@ +#pragma once + +/* + * These types mainly exist to simplify the otherwise ambiguous abstracted void pointers used by the ScriptApi. + * They should be able to be casted to and treated the same way their respective plugin_foundation type is. +*/ + +/* +* All functions declared as "unsigned find_x(name)" will return UINT_MAX when no index was found. +*/ + +#include "../plugin_api_types.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + typedef CApiStoryTeller* StoryTellerPtr; + typedef CApiWorld* WorldPtr; + typedef CApiLevel* LevelPtr; + typedef CApiScatterSystem* ScatterSystemPtr; + typedef CApiVectorField* VectorFieldPtr; + typedef CApiCamera* CameraPtr; + typedef CApiViewport* ViewportPtr; + typedef CApiShadingEnvironment* ShadingEnvironmentPtr; + typedef CApiActor* ActorPtr; + typedef void* TerrainPtr; + typedef CApiMover* MoverPtr; + typedef CApiMaterial* MaterialPtr; + typedef void* LanLobbyPtr; + typedef void* LanLobbyBrowserPtr; + typedef void* GameSessionPtr; + typedef CApiUnitSynchronizer* UnitSynchronizerPtr; + typedef CApiMesh* MeshPtr; + typedef void* JointPtr; + typedef void* LodObjectPtr; + typedef CApiLight* LightPtr; + typedef void* VehiclePtr; + typedef void* ClothPtr; + typedef CApiLineObject* LineObjectPtr; + typedef CApiGui* GuiPtr; + typedef CApiQuaternion* QuaternionPtr; + typedef CApiWindow* WindowPtr; + typedef CApiNavigationMesh* NavigationMeshPtr; + typedef CApiVideoPlayer* VideoPlayerPtr; + typedef CApiReplay* ReplayPtr; + typedef CApiCallbackData32* CallbackData32Ptr; + typedef CApiStreamSource* StreamSourcePtr; + typedef CApiTimpaniWorldInterface* TimpaniWorldInterfacePtr; + typedef CApiGuiThumbnail* GuiThumbnailPtr; + typedef CApiCaptureBuffer* CApiCaptureBufferPtr; + typedef CApiInputController* CApiInputControllerPtr; + + typedef CApiTransformComponent* TransformComponentPtr; + typedef CApiMeshComponent* MeshComponentPtr; + typedef CApiActorComponent* ActorComponentPtr; + typedef CApiSceneGraphComponent* SceneGraphComponentPtr; + typedef CApiAnimationBlenderComponent* AnimationBlenderComponentPtr; + typedef CApiAnimationStateMachineComponent* AnimationStateMachineComponentPtr; + typedef CApiDebugNameComponent* DebugNameComponentPtr; + typedef CApiDataComponentPtr* DataComponentPtr; + typedef CApiRenderDataComponent* RenderDataComponentPtr; + typedef CApiTagComponent* TagComponentPtr; + typedef CApiComponent* ComponentPtr; + typedef CApiFlowComponent* FlowComponentPtr; + typedef CApiUnitComponent* UnitComponentPtr; + typedef CApiPhysicsWorld* PhysicsWorldPtr; + + typedef const CApiWorldConfig* ConstWorldConfigPtr; + typedef const void* ConstConfigRootPtr; + typedef const CApiMatrix4x4* ConstMatrix4x4Ptr; + typedef const CApiVector2* ConstVector2Ptr; + typedef const CApiVector3* ConstVector3Ptr; + typedef const CApiVector4* ConstVector4Ptr; + typedef const CApiLocalTransform* ConstLocalTransformPtr; + typedef const CApiViewport* ConstViewportPtr; + + typedef const CApiShadingEnvironment* ConstShadingEnvironmentPtr; + typedef const CApiWindow* ConstWindowPtr; + typedef const CApiCamera* ConstCameraPtr; + typedef const CApiWorld* ConstWorldPtr; + typedef const CApiMaterial* ConstMaterialPtr; + typedef const void* ConstRenderResourcePtr; + typedef const void* ConstLanLobbyPtr; + typedef const void* ConstLanLobbyBrowserPtr; + typedef const CApiQuaternion* ConstQuaternionPtr; + typedef const CApiLevel* ConstLevelPtr; + typedef const CApiMesh* ConstMeshPtr; + typedef const CApiNavigationMesh* ConstNavigationMeshPtr; + typedef CApiMaterialData* MaterialDataPtr; + + typedef CApiUnitRef UnitRef; + typedef unsigned ParticleRef; + typedef unsigned GameObjectId; + typedef uint64_t PeerId; + typedef unsigned EntityRef; + typedef CApiInstance Instance; + typedef CApiInstanceId InstanceId; + typedef CApiInstanceWithId InstanceWithId; + typedef unsigned RaycastId; + typedef unsigned SaveToken; + typedef unsigned ScatterBrushId; + typedef unsigned ScatterUnitId; + typedef unsigned ScatterObserverId; + + struct WindowRectWrapper { + int pos[4]; + }; + + struct OOBBWrapper { + float tm[16]; + float half_ext[3]; + }; + + struct BoundingVolumeWrapper { + CApiVector3 min; + CApiVector3 max; + float radius; + }; + + struct MoverFitsAtResult { + int fits; + CApiVector3 pos; + }; + + struct MoverSeparateResult { + int is_colliding; + int can_be_resolved; + CApiVector3 position_after_resolving; + ActorPtr collides_with; /* Can be nullptr even if is_colliding is true, not all collidables are actors. */ + }; + + /* + UINT_MAX represents a nil AnimationState value. + Currently up to 32 states can be returned, use num_states to find out how many are. + */ + + enum {MAX_ANIMATION_STATES = 32}; + struct AnimationStates { + unsigned states[MAX_ANIMATION_STATES]; + unsigned num_states; + }; + + enum { MAX_ANIMATION_LAYER_SEEDS = 32 }; + struct AnimationLayerSeeds { + unsigned seeds[MAX_ANIMATION_LAYER_SEEDS]; + unsigned num_seeds; + }; + + struct AnimationLayerInfo { + float length; + double t; + }; + + enum { MAX_ANIMATION_EVENT_PARAMETERS = 1 }; + enum { ANIMATION_EVENT_PERCENT_SYNC = 0 }; + + struct AnimationEventParameters + { + unsigned n; + unsigned keys[MAX_ANIMATION_EVENT_PARAMETERS]; + float values[MAX_ANIMATION_EVENT_PARAMETERS]; + }; + + /* + * Specifies how units will be faded in/out when un-/spawned by the ScatterSystem + * POP - pop in place + * SLIDE_Z - slide in along object's z-axis + * SCALE - scale to full size + */ + enum ScatterFadeMethod {SCATTER_FADE_POP, SCATTER_FADE_SLIDE_Z, SCATTER_FADE_SCALE}; + + /* + * Specifies how an animation should be blended with other animations. + * With BT_NORMAL the pose is lerped based on the blend strength. + * With BT_OFFSET the pose is applied as an offset. + */ + enum AnimationBlendType { ANIM_BT_NORMAL, ANIM_BT_OFFSET }; + + enum WindowKeystrokes + { + WINDOW_KEYSTROKE_WINDOWS, + WINDOW_KEYSTROKE_ALT_TAB, + WINDOW_KEYSTROKE_ALT_ENTER, + WINDOW_KEYSTROKE_ALT_F4, + }; + + /* Represents both the animation_root_mode and animation_bone_mode types since they are equal. */ + enum AnimationBoneRootMode + { + BRM_IGNORE = 0, + BRM_POSITION = 1 << 0, + BRM_ROTATION = 1 << 1, + BRM_SCALE = 1 << 2, + BRM_TRANSFORM = BRM_POSITION | BRM_ROTATION | BRM_SCALE, + BRM_POSITION_AND_ROTATION = BRM_POSITION | BRM_ROTATION, + BRM_POSITION_AND_SCALE = BRM_POSITION | BRM_SCALE, + BRM_ROTATION_AND_SCALE = BRM_ROTATION | BRM_SCALE + }; + + /* Take note of the escape characters when reading. Example bone_names_list: "bone_hand_1\0bone_hand_2\0etc\0" */ + struct BoneNamesWrapper { + const char* bone_names_list; + unsigned num_bones; + }; + + enum RawInputEventType + { + BUTTON_PRESSED, + BUTTON_RELEASED, + + AXIS_CHANGED, + + TOUCH_DOWN, + TOUCH_UP, + TOUCH_MOVE, + }; + + enum RawInputEventController + { + KEYBOARD, + MOUSE, + TOUCH_PANEL, + GAMEPAD, + PS4PAD + }; + + struct RawInputEventWrapper { + CApiVector3 delta_value; + unsigned char id; + unsigned char controller_index; + unsigned char type; /* RawInputEventType */ + unsigned char controller; /* RawInputEventController */ + }; + + enum RemoteEventType { + REMOTE_EVENT_TYPE_KEY_DOWN = 0, + REMOTE_EVENT_TYPE_KEY_UP = 1, + REMOTE_EVENT_TYPE_KEY_PRESS = 2, + REMOTE_EVENT_TYPE_MOUSE_DOWN = 3, + REMOTE_EVENT_TYPE_MOUSE_UP = 4, + REMOTE_EVENT_TYPE_MOUSE_MOVE = 5, + REMOTE_EVENT_TYPE_MOUSE_WHEEL = 6 + }; + + struct RemoteEventWrapper { + unsigned input_type; + int button_id; + int x; + int y; + float dx; + float dy; + float dz; + int key_code; + }; + + enum InputCategory + { + INPUT_CATEGORY_GAMEPAD = 0, + INPUT_CATEGORY_TOUCH_PANEL = 1, + INPUT_CATEGORY_MOUSE = 2, + INPUT_CATEGORY_KEYBOARD = 3, + INPUT_CATEGORY_POINTER = 4 + }; + + enum Keystroke + { + KS_CHAR_ARROW_LEFT = 1, + KS_CHAR_ARROW_RIGHT = 2, + KS_CHAR_ARROW_UP = 3, + KS_CHAR_ARROW_DOWN = 4, + KS_CHAR_INSERT = 5, + KS_CHAR_HOME = 6, + KS_CHAR_END = 7, + KS_CHAR_BACKSPACE = 8, + KS_CHAR_TAB = 9, + KS_CHAR_PG_UP = 11, + KS_CHAR_PG_DOWN = 12, + KS_CHAR_ENTER = 13, + KS_CHAR_F1 = 14, + KS_CHAR_F2 = 15, + KS_CHAR_F3 = 16, + KS_CHAR_F4 = 17, + KS_CHAR_F5 = 18, + KS_CHAR_F6 = 19, + KS_CHAR_F7 = 20, + KS_CHAR_F8 = 21, + KS_CHAR_F9 = 22, + KS_CHAR_F10 = 23, // magical, does not work + KS_CHAR_F11 = 24, + KS_CHAR_F12 = 25, + KS_CHAR_DELETE = 26, + KS_CHAR_ESCAPE = 27 + }; + + struct TouchPinchGesture + { + unsigned began_last_frame; + unsigned ended_last_frame; + struct CApiVector2 location; + float scale; + float scale_per_second; + }; + + struct TouchRotationGesture + { + unsigned began_last_frame; + unsigned ended_last_frame; + struct CApiVector2 location; + float accumulated_rotation_rad; + float rotation_per_second_rad; + }; + + enum SwipeDirection { SWIPE_DIRECTION_NONE = -1, SWIPE_DIRECTION_RIGHT = 1, SWIPE_DIRECTION_LEFT = 2, SWIPE_DIRECTION_UP = 4, SWIPE_DIRECTION_DOWN = 8}; + + enum TouchEdge { TOUCH_EDGE_NONE = 0, TOUCH_EDGE_TOP = 0x01, TOUCH_EDGE_BOTTOM = 0x02, TOUCH_EDGE_LEFT = 0x04, TOUCH_EDGE_RIGHT = 0x08 }; + + enum { MAX_TOUCH_CONTACTS = 64 }; + + enum DeadZoneMode { DEADZONE_MODE_CIRCULAR, DEADZONE_MODE_INDEPENDENT, DEADZONE_MODE_RAW }; + + struct DeadZoneSetting { + enum DeadZoneMode mode; + float size; + }; + + struct RumbleParameters + { + float frequency; // Default 0.0f (frequency = 1.0f / period) + float offset; // Default 0.0f + float attack_level; // Default 1.0f + float sustain_level; // Default 1.0f + float attack; // Default 0.0f + float release; // Default 0.0f + float sustain; // Default 0.0f + float decay; // Default 0.0f + }; + + struct SocketAddressWrapper { + char address_and_port[22]; + }; + + enum RPCParameterType + { + RPC_PARAM_BOOL_TYPE, + RPC_PARAM_INT_TYPE, + RPC_PARAM_FLOAT_TYPE, + RPC_PARAM_VECTOR3_TYPE, + RPC_PARAM_QUATERNION_TYPE, + RPC_PARAM_STRING_TYPE, + RPC_PARAM_IDSTRING32_TYPE, + RPC_PARAM_IDSTRING64_TYPE, + RPC_PARAM_RESOURCE_ID_TYPE, + RPC_PARAM_UINT_64_TYPE, + RPC_PARAM_ARRAY_BEGINS, + RPC_PARAM_ARRAY_ENDS + }; + + struct RPCMessageParameter + { + enum RPCParameterType type; + void* data_pointer; + }; + + struct GameObjectField + { + unsigned field_name_id32; + enum RPCParameterType type; + void* data_pointer; + }; + + typedef void (*game_object_callback_function) (int id, uint64_t sending_peer); + + /* These member functions will receive callbacks from the engine during NetworkCApi's update_receive. + You're expected to assign all the function pointers before passing the struct. */ + struct RPCCallback { + game_object_callback_function game_object_created; + game_object_callback_function game_object_destroyed; + game_object_callback_function game_object_migrated_to_me; + game_object_callback_function game_object_migrated_away; + void (*game_object_sync_done) (uint64_t sending_peer); + void (*game_session_disconnect) (uint64_t sending_peer); + /* Note: all data passed in the RPCMessageParameter array are temporary allocated and will get destroyed after the callback. */ + void (*custom_callback) (uint64_t sending_peer, unsigned message_id32, struct RPCMessageParameter* parameter_array, unsigned num_parameters); + }; + + struct EntityInstanceId + { + EntityRef entity; + InstanceId instance_id; + }; + + /* Entity property type. */ + enum EntityPropertyType + { + ENTITY_PROPERTY_TYPE_NIL, + ENTITY_PROPERTY_TYPE_BOOL, + ENTITY_PROPERTY_TYPE_FLOAT, + ENTITY_PROPERTY_TYPE_STRING, + ENTITY_PROPERTY_TYPE_FLOAT_ARRAY + }; + + /* The combined hash of the individual hashes of the separate key strings. */ + typedef unsigned EntityPropertyKey; + + struct EntityPropertyValueFloatArray + { + float *a; + unsigned n; + }; + + struct EntityPropertyValue + { + enum EntityPropertyType type; + union { + unsigned b; + float f; + const char *s; + struct EntityPropertyValueFloatArray a; + }; + }; + + enum RaycastType { RAY_TYPE_ANY, RAY_TYPE_CLOSEST, RAY_TYPE_ALL }; + enum ActorTemplate { ACTOR_T_STATIC = 1, ACTOR_T_DYNAMIC, ACTOR_T_BOTH }; + enum OverlapShape { OVERLAP_SPHERE, OVERLAP_AABB, OVERLAP_OOBB, OVERLAP_CAPSULE }; + + struct CollisionHit + { + CApiVector3 position; + CApiVector3 normal; + float distance; + ActorPtr actor; + }; + + enum SaveSystemError + { + SAVEDATA_ERROR_ERROR_MISSING, /* The specified file does not exist. */ + SAVEDATA_ERROR_INVALID_FILENAME, /* The specified filename is invalid. */ + SAVEDATA_ERROR_IO_ERROR, /* A disk error occurred. */ + SAVEDATA_ERROR_BROKEN, /* The saved data is corrupted. */ + SAVEDATA_ERROR_UNSUPPORTED_VERSION, /* The data was saved using an old version, and cannot be loaded by this version. */ + SAVEDATA_ERROR_INVALID_TOKEN, /* The specified token could not be found. */ + SAVEDATA_ERROR_NOT_DONE, /* The specified token has not finished loading yet. */ + SAVEDATA_ERROR_NONE /* No error occured. */ + }; + + struct SaveSystemProgress + { + int is_done; + float progress; + enum SaveSystemError error_code; + }; + + enum SaveParameterType + { + SAVE_PARAM_TABLE_BEGIN, + SAVE_PARAM_TABLE_END, + SAVE_PARAM_NUMBER_FLOAT, + SAVE_PARAM_STRING, + SAVE_PARAM_BOOL, + SAVE_PARAM_VECTOR3, + SAVE_PARAM_VECTOR3_BOX, + SAVE_PARAM_MATRIX4X4, + SAVE_PARAM_MATRIX4X4_BOX, + SAVE_PARAM_NUMBER_DOUBLE + }; + + struct SaveParameter + { + enum SaveParameterType type; + void* data_pointer; + }; + + /* Note: You still have to close the token to free the data. */ + typedef void (*save_system_data_callback) (struct SaveParameter* parameter_array, unsigned num_parameters); + + /* Access the different null-terminated strings via s[i], i must be less than num_strings. The s must be pre-allocated by the user. */ + struct MultipleStringsBuffer + { + unsigned num_strings; + char** s; + }; + + enum TimeStepPolicyType + { + TSP_FRAME_RATE, + TSP_THROTTLE_FRAME_RATE, + TSP_SMOOTHING, + TSP_DEBT_PAYBACK, + TSP_EXTERNAL_STEP_RANGE, + TSP_EXTERNAL_MULTIPLIER, + TSP_SYSTEM_STEP_RANGE, + TSP_CLEAR_HISTORY, + TSP_JUMP + }; + + struct TimeStepPolicyWrapper + { + enum TimeStepPolicyType type; + + union { + int frames; + int fps; + float multiplier; + float time; + float min; + }; + union { + int outliers; + float max; + }; + union { + float lerp; + }; + }; + + struct WindowOpenParameter + { + int x; + int y; + int width; + int height; + const char* optional_title; + WindowPtr optional_parent; + int explicit_resize; + int main_window; + int visible; + int pass_key_events_to_parent; + int layered; + int frameless; + }; + + struct Vector3ArrayWrapper + { + int count; + CApiVector3* v; + }; + + enum ReplayRecordMode + { + REPLAY_RECORD_MODE_DISABLED, + REPLAY_RECORD_MODE_TRANSFORM, + REPLAY_RECORD_MODE_SCENE_GRAPH + }; + + struct MaterialDecalDrawer { + unsigned material_id32; + unsigned drawer_id32; + }; + + struct TextExtentsResult + { + struct CApiVector2 min; + struct CApiVector2 max; + struct CApiVector2 caret; + }; + + enum WorldCApi_OrphanedParticlePolicy + { + WA_OPP_DESTROY_ORPHAN, + WA_OPP_STOP_SPAWNING_ORPHAN, + WA_OPP_UNLINK_ORPHAN + }; + + enum UnitCApi_VisibilityContext + { + UVC_DEFAULT = 1, + UVC_SHADOW_CASTER = 2, + UVC_OCCLUDER = 4, + UVC_ALL = 255 + }; + + enum DynamicScriptDataType + { + D_DATA_NIL_TYPE, + D_DATA_BOOLEAN_TYPE, + D_DATA_NUMBER_TYPE, + D_DATA_STRING_TYPE, + D_DATA_CUSTOM_TVECTOR2 = 100, + D_DATA_CUSTOM_TVECTOR3, + D_DATA_CUSTOM_TVECTOR4, + D_DATA_CUSTOM_TMATRIX4X4, + D_DATA_CUSTOM_TUNITREFERENCE, + D_DATA_CUSTOM_TPOINTER, + D_DATA_CUSTOM_TLUAREF, /* Custom Lua reference is currently not supported via the C Api's DynamicScriptData. */ + D_DATA_CUSTOM_ID64 + }; + + typedef struct DynamicScriptDataItem { + const void *pointer; + enum DynamicScriptDataType type; + unsigned size; + } DynamicScriptDataItem; + + enum CameraProjectionType { + CAMERA_PROJ_ORTHOGRAPHIC, + CAMERA_PROJ_PERSPECTIVE + }; + + enum CameraMode { + CAMERA_MODE_MONO, + CAMERA_MODE_STEREO + }; + + enum FlowType { + FLOW_NIL_TYPE = 0, + FLOW_UNIT_TYPE = 1, + FLOW_ACTOR_TYPE = 2, + FLOW_MOVER_TYPE = 3, + FLOW_VECTOR3_TYPE = 4, + FLOW_FLOAT_TYPE = 5, + FLOW_BOOL_TYPE = 6, + FLOW_STRING_TYPE = 7, + FLOW_ID64_TYPE = 8, + FLOW_QUATERNION_TYPE = 9, + FLOW_UNSIGNED_TYPE = 10, + FLOW_CAMERA_TYPE = 11, + FLOW_LIGHT_TYPE = 12, + FLOW_MESH_TYPE = 13, + FLOW_MATERIAL_TYPE = 14, + FLOW_ID32_TYPE = 15, + FLOW_ENTITY_TYPE = 16 + }; + +#ifdef __cplusplus +}; +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_unit.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_unit.h new file mode 100644 index 0000000..abc8450 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_unit.h @@ -0,0 +1,207 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct UnitCApi +{ + ConstVector3Ptr (*local_position) (UnitRef, unsigned index); + CApiQuaternion (*local_rotation) (UnitRef, unsigned index); + ConstVector3Ptr (*local_scale) (UnitRef, unsigned index); + ConstLocalTransformPtr (*local_pose) (UnitRef, unsigned index); + + void (*set_local_position) (UnitRef, unsigned index, ConstVector3Ptr); + void (*set_local_rotation) (UnitRef, unsigned index, ConstQuaternionPtr); + void (*set_local_scale) (UnitRef, unsigned index, ConstVector3Ptr); + void (*set_local_pose) (UnitRef, unsigned index, ConstLocalTransformPtr); + + ConstVector3Ptr (*world_position) (UnitRef, unsigned index); + ConstMatrix4x4Ptr (*world_pose) (UnitRef, unsigned index); + // Performance-warning; Fetches the world_pose, extracts a Matrix3x3 from it and returns a copy on the stack. + CApiQuaternion (*world_rotation) (UnitRef, unsigned index); + + void (*teleport_local_position) (UnitRef, unsigned index, ConstVector3Ptr); + void (*teleport_local_rotation) (UnitRef, unsigned index, ConstQuaternionPtr); + void (*teleport_local_scale) (UnitRef, unsigned index, ConstVector3Ptr); + void (*teleport_local_pose) (UnitRef, unsigned index, ConstLocalTransformPtr); + + CApiVector3 (*delta_position) (UnitRef, unsigned index); + CApiQuaternion (*delta_rotation) (UnitRef, unsigned index); + struct CApiMatrix4x4 (*delta_pose) (UnitRef, unsigned index); + + ActorPtr (*create_actor) (UnitRef, unsigned index, float inherit_velocity, const char* optional_debug_actor_name); + void (*destroy_actor) (UnitRef, unsigned index, const char* optional_debug_actor_name); + unsigned (*num_actors) (UnitRef); + unsigned (*find_actor) (UnitRef, unsigned actor_name_id32, const char* optional_debug_actor_name); + ActorPtr (*actor) (UnitRef, unsigned index, const char* optional_debug_actor_name); + + unsigned (*num_movers) (UnitRef); + unsigned (*find_mover) (UnitRef, unsigned mover_name_id32); + MoverPtr (*set_mover) (UnitRef, unsigned index, const char *optional_debug_mover_name); + void (*set_mover_to_none) (UnitRef); + MoverPtr (*mover) (UnitRef); + struct MoverFitsAtResult (*mover_fits_at) (UnitRef unit_ref, unsigned index, ConstVector3Ptr position, float permitted_move_threshold, const char *optional_debug_mover_name); + + void (*trigger_flow_event) (UnitRef, unsigned event_name_id32); + void* (*flow_variable) (UnitRef unit_ref, unsigned variable_name_id32, unsigned *out_type); + void (*set_flow_variable) (UnitRef, unsigned variable_name_id32, void* value); + void (*trigger_unit_spawned)(UnitRef unit_ref); + + uint64_t (*set_material) (UnitRef, unsigned slot_name_id32, uint64_t material_resource_name_id64, const char *optional_debug_material_resource_name, unsigned debug_suppress_slot_assignment_warning); + uint64_t (*set_material_to_none) (UnitRef, unsigned slot_name_id32); + unsigned (*query_material)(UnitRef unit_ref, ConstVector3Ptr start, ConstVector3Ptr end, unsigned context_count, unsigned context_id32s[], unsigned out_material[]); + MaterialDataPtr (*save_instance_material_data)(UnitRef unit_ref); + void (*restore_instance_material_data)(UnitRef unit_ref, MaterialDataPtr data); + int (*is_using_material_set)(UnitRef unit_ref); + + unsigned (*num_meshes) (UnitRef); + unsigned (*find_mesh) (UnitRef, unsigned mesh_name_id32); + MeshPtr (*mesh) (UnitRef, unsigned index, const char *optional_debug_mesh_name); + + struct BoneNamesWrapper (*bones) (UnitRef); + CApiMatrix4x4 (*animation_wanted_root_pose) (UnitRef); + void (*animation_set_bones_lod) (UnitRef, unsigned); + + enum AnimationBoneRootMode (*animation_root_mode) (UnitRef); + enum AnimationBoneRootMode (*animation_bone_mode) (UnitRef); + + void (*set_animation_root_mode) (UnitRef, enum AnimationBoneRootMode); + void (*set_animation_bone_mode) (UnitRef, enum AnimationBoneRootMode); + + unsigned (*animation_find_constraint_target) (UnitRef unit_ref, unsigned constraint_target_name_id32, const char *optional_debug_target_name); + unsigned (*animation_has_constraint_target)(UnitRef unit_ref, unsigned constraint_target_name_id32); + ConstMatrix4x4Ptr (*animation_get_constraint_target) (UnitRef, unsigned index); + void (*animation_set_constraint_target_pose) (UnitRef, unsigned index, ConstMatrix4x4Ptr); + void (*animation_set_constraint_target_position) (UnitRef, unsigned index, ConstVector3Ptr); + void (*animation_set_constraint_target_rotation) (UnitRef, unsigned index, ConstQuaternionPtr); + + unsigned (*crossfade_animation) (UnitRef, uint64_t animation_name_id64, const char *optional_debug_animation_name, unsigned layer, float blend_time, int should_loop, enum AnimationBlendType); + unsigned (*is_crossfading_animation) (UnitRef); + void (*crossfade_animation_set_time) (UnitRef, unsigned id, float time, int should_cap_to_range); + void (*crossfade_animation_set_speed) (UnitRef, unsigned id, float speed); + + void (*disable_animation_state_machine) (UnitRef); + void (*enable_animation_state_machine) (UnitRef); + void (*set_animation_state_machine) (UnitRef, uint64_t machine_name_id64, const char *optional_debug_machine_name); + int (*has_animation_state_machine) (UnitRef); + int (*has_animation_blender) (UnitRef); + int (*has_animation_event) (UnitRef, unsigned event_name_id32); + + void (*animation_trigger_event) (UnitRef unit_ref, unsigned event_name_id32, const char *optional_debug_event_name); + void (*animation_trigger_event_with_parameters) (UnitRef unit_ref, unsigned event_name_id32, const char *optional_debug_event_name, struct AnimationEventParameters *parameters); + + unsigned (*animation_find_variable) (UnitRef, unsigned variable_name_id32, const char *optional_debug_variable_name); + int (*animation_has_variable)(UnitRef unit_ref, unsigned variable_name_id32); + float (*animation_get_variable) (UnitRef, unsigned index); + void (*animation_set_variable) (UnitRef, unsigned index, float value); + + void (*animation_set_state) (UnitRef, struct AnimationStates*); + struct AnimationStates (*animation_get_state) (UnitRef); + + void(*animation_set_seeds) (UnitRef, struct AnimationLayerSeeds*); + struct AnimationLayerSeeds(*animation_get_seeds) (UnitRef); + + struct AnimationLayerInfo (*animation_layer_info) (UnitRef, unsigned index); + void (*set_animation_merge_options) (UnitRef, float max_start_time, float max_drift, float clock_fidelity); + + void (*animation_set_moving)(UnitRef unit_ref, unsigned frames); + int (*animation_get_curve_value)(UnitRef unit_ref, unsigned object_id32, unsigned parameter_id32, unsigned int float_index, float *out_curve_value); + void (*set_animation_logging)(UnitRef unit_ref, int enable); + + void (*play_simple_animation)(UnitRef unit_ref, float from, float to, float speed, int loop, unsigned optional_group, const char *optional_debug_group_name); + void (*stop_simple_animation)(UnitRef unit_ref, unsigned optional_group, const char *optional_debug_group_name); + + unsigned (*num_terrains) (UnitRef); + unsigned (*find_terrain) (UnitRef, unsigned terrain_name_id32); + TerrainPtr (*terrain) (UnitRef, unsigned index, const char *optional_debug_terrain_name); + void (*terrain_update_height_field)(UnitRef unit_ref, void *data); + + JointPtr (*create_joint) (UnitRef, unsigned joint_name_id32, const char *optional_debug_joint_name); + void (*destroy_joint) (UnitRef, unsigned joint_name_id32); + JointPtr (*create_custom_joint) (UnitRef, unsigned joint_name_id32, ActorPtr optional_actor_1, ActorPtr optional_actor_2, ConstVector3Ptr optional_anchor_1, + ConstVector3Ptr optional_anchor_2, ConstVector3Ptr optional_global_anchor, ConstVector3Ptr optional_global_axis, + const char *optional_debug_joint_name); + + // Length of key_id32_array depenends on the path for the property + void (*set_property) (UnitRef unit_ref, float value, unsigned key_id32_array[]); + float (*get_property) (UnitRef unit_ref, unsigned key_id32_array[]); + + unsigned (*num_scene_graph_items) (UnitRef); + unsigned (*find_scene_graph_parent) (UnitRef, unsigned index); + void (*scene_graph_link) (UnitRef, unsigned index, unsigned parent_index); + void (*scene_graph_link_to_none) (UnitRef, unsigned index); + void (*copy_scene_graph_local_from) (UnitRef destination, UnitRef source); + + unsigned (*num_lod_objects) (UnitRef); + unsigned (*find_lod_object) (UnitRef, unsigned lod_name_id32); + LodObjectPtr (*lod_object) (UnitRef, unsigned index, const char *optional_debug_lod_name); + unsigned (*num_steps_lod) (LodObjectPtr lod_obj_ptr); + void (*lod_step_range) (LodObjectPtr lod_obj_ptr, unsigned step_index, float out_range[2]); + unsigned (*num_mesh_lod_step) (LodObjectPtr lod_obj_ptr, unsigned step_index); + const unsigned* (*lod_step_meshes) (LodObjectPtr lod_obj_ptr, unsigned step_index); + + unsigned (*num_lights) (UnitRef); + unsigned (*find_light) (UnitRef, unsigned light_name_id32); + LightPtr (*light) (UnitRef, unsigned index, const char *optional_debug_light_name); + void (*set_light_material)(UnitRef unit_ref, LightPtr light_pointer, uint64_t material_name); + + VehiclePtr (*create_vehicle) (UnitRef); + void (*destroy_vehicle) (UnitRef); + int (*has_vehicle) (UnitRef); + VehiclePtr (*vehicle) (UnitRef); + + void (*enable_physics) (UnitRef); + void (*disable_physics) (UnitRef); + void (*apply_initial_actor_velocities) (UnitRef, int should_wake_sleeping_actors); + + void (*set_unit_visibility) (UnitRef, int enabled); + void (*set_mesh_visibility) (UnitRef unit_ref, unsigned index, unsigned visbility_context_id32, int enabled, const char *optional_debug_mesh_name, const char *optional_debug_visbility_context_name); + void (*set_cloth_visibility) (UnitRef unit_ref, unsigned index, unsigned state, unsigned visbility_context_id32, const char *optional_debug_cloth_name, const char *optional_debug_visbility_context_name); + void (*set_visibility_group) (UnitRef, unsigned group_name_id32, int enabled, const char *optional_debug_group_name); + int (*has_visibility_group) (UnitRef, unsigned group_name_id32); + + ClothPtr (*create_cloth) (UnitRef unit_ref, unsigned index, const char *optional_debug_cloth_name); + void (*destroy_cloth) (UnitRef unit_ref, unsigned index, const char *optional_debug_cloth_name); + unsigned (*num_cloths) (UnitRef unit_ref); + unsigned (*find_cloth) (UnitRef unit_ref, unsigned cloth_name_id32); + ClothPtr (*cloth) (UnitRef unit_ref, unsigned index, const char *optional_debug_cloth_name); + + unsigned (*num_cameras) (UnitRef); + unsigned (*find_camera) (UnitRef, unsigned camera_name_id32); + CameraPtr (*camera) (UnitRef, unsigned index, const char *optional_debug_camera_name); + + int (*has_node) (UnitRef, unsigned node_name_id32); + unsigned (*node) (UnitRef, unsigned node_name_id32, const char *optional_debug_node_name); + + int (*resource_has_node)(uint64_t unit_resource_id64, unsigned node_id32, const char *optional_debug_unit_resource_name); + unsigned (*resource_node)(uint64_t unit_resource_id64, unsigned node_id32, const char *optional_debug_unit_resource_name, const char *optional_debug_node_name); + // Performance-warning; Fetches the local_pose, extracts a Matrix4x4 from it and returns a copy on the stack. + CApiMatrix4x4 (*resource_local_pose)(uint64_t unit_resource_id64, unsigned node_index, const char *optional_debug_unit_resource_name); + + WorldPtr (*world) (UnitRef); + LevelPtr (*level) (UnitRef); + int (*is_alive) (UnitRef); + uint64_t (*id_in_level) (UnitRef); + int (*is_of_resource_type) (UnitRef, uint64_t resource_name); + const char *(*unit_name_s)(UnitRef unit_ref); + + struct OOBBWrapper (*box) (UnitRef unit_ref, unsigned ignore_invisible_meshes); + const char * (*debug_name)(UnitRef unit_ref); + void (*name_hash)(UnitRef unit_ref, char out_name[8]); + int (*is_a)(UnitRef unit_ref, uint64_t resource_id64); + void (*set_id_in_level)(UnitRef unit_ref, uint64_t id); + void (*draw_tree)(UnitRef unit_ref); + + unsigned (*mesh_raycast)(UnitRef unit_ref, ConstVector3Ptr from, ConstVector3Ptr dir, float threshold, int include_hidden_meshes, + float *out_distance, CApiVector3 *out_normal_world); + unsigned (*mesh_pick_raycast)(UnitRef unit_ref, ConstVector3Ptr from, ConstVector3Ptr dir, float threshold, int include_hidden_meshes, + float *out_distance, CApiVector3 *out_normal_world, unsigned *out_best_mesh_index, unsigned *out_best_triangle_index); + unsigned (*mesh_closest_point_raycast)(UnitRef unit_ref, ConstVector3Ptr from, ConstVector3Ptr dir, float ray_length, + CApiVector3 *out_best_point_world, float *out_best_point_distance_along_ray, float *out_best_point_distance_to_ray); +}; +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_unit_synchronizer.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_unit_synchronizer.h new file mode 100644 index 0000000..04f1ec0 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_unit_synchronizer.h @@ -0,0 +1,21 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct UnitSynchronizerCApi +{ + void (*set_world) (UnitSynchronizerPtr unit_synchronizer_pointer, WorldPtr world_pointer); + UnitRef (*spawn_unit)(UnitSynchronizerPtr unit_synchronizer_pointer, unsigned type_id32, uint64_t unit_name_id64, ConstMatrix4x4Ptr transform, const char *optional_debug_unit_name); + void (*destroy_unit)(UnitSynchronizerPtr unit_synchronizer_pointer, UnitRef unit_ref); + + UnitRef (*game_object_id_to_unit)(UnitSynchronizerPtr unit_synchronizer_pointer, GameObjectId id); + GameObjectId (*unit_to_game_object_id)(UnitSynchronizerPtr unit_synchronizer_pointer, UnitRef unit_ref); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_utilities.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_utilities.h new file mode 100644 index 0000000..8a19b78 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_utilities.h @@ -0,0 +1,24 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct UtilitiesProfilerApi +{ + void (*start) (const char* name); + void (*stop) (); + void (*record_statistics_float) (const char* name, float); + void (*record_statistics_vector3) (const char* name, ConstVector3Ptr); +}; + +struct UtilitiesCApi +{ + struct UtilitiesProfilerApi* Profiler; +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_viewport.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_viewport.h new file mode 100644 index 0000000..0cd24b5 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_viewport.h @@ -0,0 +1,16 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct ViewportCApi +{ + void (*set_rect) (ViewportPtr, float x, float y, float width, float height); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_window.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_window.h new file mode 100644 index 0000000..e038d12 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_window.h @@ -0,0 +1,85 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void(*WindowCApi_KeyDownFunction)(void *obj, int virtual_key, int repeat_count, int scan_code, int extended, int previous_state); +typedef void(*WindowCApi_CharDownFunction)(void *obj, int char_code); +typedef void(*WindowCApi_KeyUpFunction)(void *obj, int virtual_key, int scan_code, int extended); +typedef void(*WindowCApi_MouseButtonFunction)(void *obj, int button); +typedef void(*WindowCApi_MouseMoveFunction)(void *obj, ConstVector3Ptr delta); +typedef void(*WindowCApi_CursorPosFunction)(void *obj, unsigned x, unsigned y); +typedef void(*WindowCApi_ActivateFunction)(void *obj, int active); +typedef void(*WindowCApi_ResizeFunction)(void *obj, WindowPtr window, int x, int y, int width, int heigh); +typedef void(*WindowCApi_ToggleFullscreenFunction)(void *obj, WindowPtr window); +typedef void(*WindowCApi_SetFocusFunction)(void *obj); + +struct WindowCApi +{ + int (*has_mouse_focus) (ConstWindowPtr optional); + int (*has_focus) (ConstWindowPtr optional); + void (*set_mouse_focus) (WindowPtr optional, int enabled); + void (*set_focus) (WindowPtr optional); + + int (*show_cursor) (WindowPtr optional); + int (*clip_cursor) (WindowPtr optional); + void (*set_cursor) (WindowPtr optional, const char* optional_mouse_cursor); + void (*set_show_cursor) (WindowPtr optional, int enabled, int restore_cursor_pos); + void (*set_clip_cursor)(WindowPtr optional, int enabled); + + int (*is_resizable)(ConstWindowPtr optional); + void (*set_resizable) (WindowPtr optional, int enabled); + void (*set_resolution) (WindowPtr optional, unsigned width, unsigned height); + float (*get_dpi_scale) (); + + void (*set_title) (WindowPtr optional, const char* title); + int (*has_window) (ConstWindowPtr); + WindowPtr (*get_main_window)(); + + void (*minimize) (WindowPtr optional); + void (*maximize) (WindowPtr optional); + void (*restore) (WindowPtr optional); + int (*is_closing) (WindowPtr optional); + void (*close) (WindowPtr optional); + void (*trigger_resize) (WindowPtr optional); + void (*set_ime_enabled) (WindowPtr optional, int enabled); + void (*set_foreground) (WindowPtr optional); + void (*set_keystroke_enabled) (enum WindowKeystrokes, int enabled); + void (*fill_default_open_parameter) (struct WindowOpenParameter* out_result); + unsigned (*id) (WindowPtr optional); + WindowPtr (*open) (struct WindowOpenParameter* const); + struct WindowRectWrapper (*rect) (WindowPtr optional); + void (*set_rect)(WindowPtr optional, struct WindowRectWrapper rect); + + void (*add_key_down_callback)(WindowPtr window, void *obj, WindowCApi_KeyDownFunction f); + void (*remove_key_down_callback)(WindowPtr window, void *obj, WindowCApi_KeyDownFunction f); + void (*add_char_down_callback)(WindowPtr window, void *obj, WindowCApi_CharDownFunction f); + void (*remove_char_down_callback)(WindowPtr window, void *obj, WindowCApi_CharDownFunction f); + void (*add_key_up_callback)(WindowPtr window, void *obj, WindowCApi_KeyUpFunction f); + void (*remove_key_up_callback)(WindowPtr window, void *obj, WindowCApi_KeyUpFunction f); + void (*add_mouse_down_callback)(WindowPtr window, void *obj, WindowCApi_MouseButtonFunction f); + void (*remove_mouse_down_callback)(WindowPtr window, void *obj, WindowCApi_MouseButtonFunction f); + void (*add_mouse_up_callback)(WindowPtr window, void *obj, WindowCApi_MouseButtonFunction f); + void (*remove_mouse_up_callback)(WindowPtr window, void *obj, WindowCApi_MouseButtonFunction f); + void (*add_mouse_move_callback)(WindowPtr window, void *obj, WindowCApi_MouseMoveFunction f); + void (*remove_mouse_move_callback)(WindowPtr window, void *obj, WindowCApi_MouseMoveFunction f); + void (*add_wheel_move_callback)(WindowPtr window, void *obj, WindowCApi_MouseMoveFunction f); + void (*remove_wheel_move_callback)(WindowPtr window, void *obj, WindowCApi_MouseMoveFunction f); + void (*add_cursor_pos_callback)(WindowPtr window, void *obj, WindowCApi_CursorPosFunction f); + void (*remove_cursor_pos_callback)(WindowPtr window, void *obj, WindowCApi_CursorPosFunction f); + void (*add_activate_callback)(WindowPtr window, void *obj, WindowCApi_ActivateFunction f); + void (*remove_activate_callback)(WindowPtr window, void *obj, WindowCApi_ActivateFunction f); + void (*add_resize_callback)(WindowPtr window, void *obj, WindowCApi_ResizeFunction f); + void (*remove_resize_callback)(WindowPtr window, void *obj, WindowCApi_ResizeFunction f); + void (*add_toggle_fullscreen_callback)(WindowPtr window, void *obj, WindowCApi_ToggleFullscreenFunction f); + void (*remove_toggle_fullscreen_callback)(WindowPtr window, void *obj, WindowCApi_ToggleFullscreenFunction f); + void (*add_set_focus_callback)(WindowPtr window, void *obj, WindowCApi_SetFocusFunction f); + void (*remove_set_focus_callback)(WindowPtr window, void *obj, WindowCApi_SetFocusFunction f); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_world.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_world.h new file mode 100644 index 0000000..d1e6cc7 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_world.h @@ -0,0 +1,100 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Defines what should happen if a linked effect becomes orphaned. Should it + be destroyed, stop spawning or be unlinked and continue to spawn. */ +struct WorldCApi +{ + UnitRef (*spawn_unit) (WorldPtr world_pointer, uint64_t unit_name_id64, const char *optional_debug_unit_name, ConstMatrix4x4Ptr transform); + void (*destroy_unit) (WorldPtr world_pointer, UnitRef unit_ref); + unsigned (*num_units) (ConstWorldPtr world_pointer); + + UnitRef (*unit_by_name) (WorldPtr world_pointer, uint64_t unit_name); + UnitRef (*unit_by_id) (WorldPtr world_pointer, uint64_t unit_id); + UnitRef (*unit_by_index) (WorldPtr world_pointer, unsigned index); + unsigned (*num_units_by_resource) (WorldPtr world_pointer, uint64_t resource_name); + unsigned (*units_by_resource)(WorldPtr world_pointer, uint64_t resource_name, unsigned max_unit_count, UnitRef* units); + + void (*link_unit) (WorldPtr world_pointer, UnitRef child, unsigned child_node_index, UnitRef parent, unsigned parent_node_index); + void (*unlink_unit) (WorldPtr world_pointer, UnitRef child); + void (*update_unit) (WorldPtr world_pointer, UnitRef unit_ref); + ParticleRef (*create_particles) (WorldPtr world_pointer, uint64_t name_id64, const char *optional_debug_name, ConstMatrix4x4Ptr transform); + void (*destroy_particles) (WorldPtr world_pointer, ParticleRef id); + void (*stop_spawning_particles) (WorldPtr world_pointer, ParticleRef id); + int (*are_particles_playing) (ConstWorldPtr world_pointer, ParticleRef id); + void (*set_particles_collision_filter) (ConstWorldPtr world_pointer, uint32_t collision_filter_name); + + void (*move_particles) (WorldPtr world_pointer, ParticleRef id, ConstMatrix4x4Ptr transform); + void (*link_particles) (WorldPtr world_pointer, ParticleRef id, UnitRef unit_ref, unsigned unit_node_index, ConstMatrix4x4Ptr local_pose, enum WorldCApi_OrphanedParticlePolicy orphaned_policy); + + unsigned (*find_particles_variable) (ConstWorldPtr world_pointer, uint64_t name_id64, const char *optional_debug_name, unsigned variable_name_id32); + void (*set_particles_variable) (WorldPtr world_pointer, ParticleRef id, unsigned variable, ConstVector3Ptr value); + + LevelPtr (*load_level) (WorldPtr world_pointer, uint64_t level_name_id64, const char *optional_debug_level_name, ConstMatrix4x4Ptr transform, uint64_t optional_level_id); + void (*destroy_level) (WorldPtr world_pointer, LevelPtr level_pointer); + unsigned (*num_levels) (ConstWorldPtr world_pointer); + LevelPtr (*level) (WorldPtr world_pointer, unsigned index); + + void (*update) (WorldPtr world_pointer, float dt); + void (*update_animations) (WorldPtr world_pointer, float dt, CApiCallbackFunction optional_callback, CallbackData32Ptr callback_data32); + void (*update_scene) (WorldPtr world_pointer, float dt); + + float (*delta_time) (ConstWorldPtr world_pointer); + float (*time) (ConstWorldPtr world_pointer); + + StoryTellerPtr (*storyteller) (WorldPtr world_pointer); + VectorFieldPtr (*vector_field) (WorldPtr world_pointer, unsigned vector_field_name_id32); + ScatterSystemPtr (*scatter_system) (WorldPtr world_pointer); + + ShadingEnvironmentPtr (*create_shading_environment) (WorldPtr world_pointer, uint64_t name_id64, const char *optional_debug_name); + ShadingEnvironmentPtr (*create_default_shading_environment) (WorldPtr world_pointer); + void (*destroy_shading_environment) (WorldPtr world_pointer, ShadingEnvironmentPtr shading_environment_pointer); + void (*set_shading_environment) (WorldPtr world_pointer, ShadingEnvironmentPtr shading_environment, uint64_t name_id64, const char *optional_debug_name); + + LineObjectPtr (*create_line_object) (WorldPtr world_pointer, int disable_depth_test); + void (*destroy_line_object) (WorldPtr world_pointer, LineObjectPtr line_object_pointer); + void (*clear_permanent_lines) (WorldPtr world_pointer); + + GuiPtr (*create_screen_gui) (WorldPtr world_pointer, ConstVector2Ptr optional_position, ConstVector2Ptr optional_scale, int immediate, int dock_right, int dock_top); + GuiPtr (*create_world_gui) (WorldPtr world_pointer, ConstMatrix4x4Ptr transform, float width, float height, int shadow_caster, int immediate); + void (*destroy_gui) (WorldPtr world_pointer, GuiPtr gui_pointer); + GuiPtr (*get_gui_by_id) (WorldPtr world_pointer, unsigned gui_id); + + PhysicsWorldPtr (*physics_world) (WorldPtr world_pointer); + + VideoPlayerPtr (*create_video_player) (WorldPtr world_pointer, uint64_t resource_id64, int loop); + void (*destroy_video_player) (WorldPtr world_pointer, VideoPlayerPtr video_player); + + ConstMatrix4x4Ptr (*debug_camera_pose) (WorldPtr world_pointer); + + /* Begin Development functions */ + void (*set_flow_enabled) (WorldPtr world_pointer, int enable); + void (*set_editor_flow_enabled) (WorldPtr world_pointer, int enable); + + unsigned (*num_particles)(WorldPtr world_pointer, unsigned* optional_effect_id, unsigned* optional_cloud_index); + void (*advance_particles_time)(WorldPtr world_pointer, unsigned id, float time); + + void (*set_frustum_inspector_camera) (WorldPtr world_pointer, CameraPtr camera_pointer); + + ReplayPtr (*replay)(WorldPtr world_pointer); + void (*start_playback)(ReplayPtr replay_ptr); + void (*stop_playback)(ReplayPtr replay_ptr); + int (*is_playing_back)(ReplayPtr replay_ptr); + int (*num_frames)(ReplayPtr replay_ptr); + int (*frame)(ReplayPtr replay_ptr); + void (*set_frame)(ReplayPtr replay_ptr, unsigned frame_index); + void (*record_debug_line)(ReplayPtr replay_ptr, ConstVector4Ptr color, ConstVector2Ptr p1, ConstVector2Ptr p2); + void (*record_screen_debug_text)(ReplayPtr replay_ptr, ConstVector4Ptr color, ConstVector2Ptr screen_position, const char* text); + void (*record_world_debug_text)(ReplayPtr replay_ptr, ConstVector4Ptr color, ConstVector3Ptr world_position, const char* text); + void (*set_unit_record_mode)(ReplayPtr replay_ptr, UnitRef unit, enum ReplayRecordMode replay_record_mode); + /* End Development functions */ +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_xbox1pad.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_xbox1pad.h new file mode 100644 index 0000000..3eae0ca --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/c_api_xbox1pad.h @@ -0,0 +1,16 @@ +#pragma once + +#include "c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct XBoxOnePadCApi +{ + unsigned (*user_id)(CApiInputControllerPtr xboxone_pad_input_controller); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_actor_component.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_actor_component.h new file mode 100644 index 0000000..22145af --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_actor_component.h @@ -0,0 +1,25 @@ +#pragma once + +#include "../c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct ActorComponentCApi +{ + Instance (*create_capsule)(ActorComponentPtr comp, EntityRef e_ref, unsigned instance_id, ConstMatrix4x4Ptr pose_pointer, float radius, float height, + unsigned actor_template_id32, unsigned shape_template_id32, unsigned material_template_id32); + Instance (*create_plane)(ActorComponentPtr comp, EntityRef e_ref, unsigned instance_id, ConstMatrix4x4Ptr pose_pointer, ConstVector3Ptr normal_pointer, + unsigned actor_template_id32, unsigned shape_template_id32, unsigned material_template_id32); + Instance (*create_box)(ActorComponentPtr comp, EntityRef e_ref, unsigned instance_id, ConstMatrix4x4Ptr pose_pointer, ConstVector3Ptr half_extents_pointer, + unsigned actor_template_id32, unsigned shape_template_id32, unsigned material_template_id32); + Instance (*create_sphere)(ActorComponentPtr comp, EntityRef e_ref, unsigned instance_id, ConstMatrix4x4Ptr pose_pointer, float radius, + unsigned actor_template_id32, unsigned shape_template_id32, unsigned material_template_id32); + Instance (*create_mesh)(ActorComponentPtr comp, EntityRef e_ref, unsigned instance_id, ConstMatrix4x4Ptr pose_pointer, void *physics_mesh, + unsigned actor_template_id32, unsigned shape_template_id32, unsigned material_template_id32); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_animation_blender_component.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_animation_blender_component.h new file mode 100644 index 0000000..33b7539 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_animation_blender_component.h @@ -0,0 +1,27 @@ +#pragma once + +#include "../c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct AnimationBlenderComponentCApi +{ + unsigned (*crossfade)(AnimationBlenderComponentPtr comp, EntityRef e_ref, uint64_t animation_name_id64, + const char *optional_debug_animation_name, unsigned layer, float blend_time, int should_loop, enum AnimationBlendType anim_blend_type); + void (*set_time)(AnimationBlenderComponentPtr comp, EntityRef e_ref, unsigned id, float time, int should_cap_to_range); + void (*set_speed)(AnimationBlenderComponentPtr comp, EntityRef e_ref, unsigned id, float speed); + int (*is_crossfading)(AnimationBlenderComponentPtr comp, EntityRef e_ref); + void (*set_root_mode)(AnimationBlenderComponentPtr comp, EntityRef e_ref, enum AnimationBoneRootMode mode); + void (*set_bone_mode) (AnimationBlenderComponentPtr comp, EntityRef e_ref, enum AnimationBoneRootMode mode); + void (*set_bones_lod)(AnimationBlenderComponentPtr comp, EntityRef e_ref, unsigned lod_level); + CApiMatrix4x4 (*delta_transform)(AnimationBlenderComponentPtr comp, EntityRef e_ref); + enum AnimationBoneRootMode (*root_mode)(AnimationBlenderComponentPtr comp, EntityRef e_ref); + enum AnimationBoneRootMode (*bone_mode)(AnimationBlenderComponentPtr comp, EntityRef e_ref); +}; + + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_animation_state_machine_component.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_animation_state_machine_component.h new file mode 100644 index 0000000..9a0ba10 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_animation_state_machine_component.h @@ -0,0 +1,25 @@ +#pragma once + +#include "../c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct AnimationStateMachineComponentCApi +{ + int (*has_event)(AnimationStateMachineComponentPtr comp, EntityRef e_ref, unsigned event_name_id32); + void (*trigger_event)(AnimationStateMachineComponentPtr comp, EntityRef e_ref, unsigned event_name_id32, const char *optional_debug_event_name); + unsigned (*find_variable)(AnimationStateMachineComponentPtr comp, EntityRef e_ref, unsigned variable_name_id32); + float (*get_variable)(AnimationStateMachineComponentPtr comp, EntityRef e_ref, unsigned index); + void (*set_variable)(AnimationStateMachineComponentPtr comp, EntityRef e_ref, unsigned index, float value); + void (*set_logging)(AnimationStateMachineComponentPtr comp, EntityRef e_ref, int enabled); + void (*set_constraint_target)(AnimationStateMachineComponentPtr comp, EntityRef e_ref, unsigned index, ConstMatrix4x4Ptr pose); + void (*set_constraint_target_position)(AnimationStateMachineComponentPtr comp, EntityRef e_ref, unsigned index, ConstVector3Ptr pos); + void (*set_constraint_target_rotation)(AnimationStateMachineComponentPtr comp, EntityRef e_ref, unsigned index, ConstQuaternionPtr rot); + ConstMatrix4x4Ptr (*get_constraint_target)(AnimationStateMachineComponentPtr comp, EntityRef e_ref, unsigned index); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_data_component.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_data_component.h new file mode 100644 index 0000000..64e0269 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_data_component.h @@ -0,0 +1,16 @@ +#pragma once + +#include "../c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct DataComponentCApi +{ + unsigned (*instance_ids_with_tag)(DataComponentPtr comp, EntityRef e_ref, unsigned tag_id32, InstanceId *buffer, unsigned buffer_size); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_debug_name_component.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_debug_name_component.h new file mode 100644 index 0000000..2656d21 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_debug_name_component.h @@ -0,0 +1,16 @@ +#pragma once + +#include "../c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct DebugNameComponentCApi +{ + void (*set_debug_name)(DebugNameComponentPtr comp, EntityRef entity, const char *debug_name); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_flow_component.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_flow_component.h new file mode 100644 index 0000000..6dd7d44 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_flow_component.h @@ -0,0 +1,20 @@ +#pragma once + +#include "../c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct FlowComponentCApi +{ + /* Triggers an event on the Flow attached to the specified Flow component instance. */ + void (*trigger_flow_event)(FlowComponentPtr component, Instance instance, unsigned event_id32); + + /* Returns a pointer to an external flow variable and an identifier specifying its type. */ + char *(*external_variable)(FlowComponentPtr component, Instance instance, unsigned variable_id32, unsigned *flow_variable_type); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_mesh_component.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_mesh_component.h new file mode 100644 index 0000000..0eb46db --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_mesh_component.h @@ -0,0 +1,20 @@ +#pragma once + +#include "../c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct MeshComponentCApi +{ + void (*set_mesh_resource)(MeshComponentPtr comp, Instance instance, uint64_t scene_resource_id64, + const char *optional_debug_scene_resource_name, unsigned mesh_name_id32, const char *optional_debug_mesh_name); + void (*set_mesh_object)(MeshComponentPtr comp, Instance instance, MeshPtr mesh_object); + void (*set_material)(MeshComponentPtr comp, Instance instance, unsigned key_id32, uint64_t material_resource_id64, + const char *optional_debug_material_resource_name, unsigned material_id32, const char *optional_debug_material_name); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_render_data_component.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_render_data_component.h new file mode 100644 index 0000000..572bf91 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_render_data_component.h @@ -0,0 +1,23 @@ +#pragma once + +#include "../c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct EntityWithInstanceId +{ + EntityRef entity; + InstanceId instance_id; +}; + +struct RenderDataComponentCApi +{ + unsigned (*instance_ids_with_tag)(RenderDataComponentPtr comp, unsigned tag, EntityWithInstanceId* out_buffer, unsigned buffer_size); + void (*add_instance_to_tags)(RenderDataComponentPtr comp, Instance instance, const unsigned* tags, const unsigned num_tags); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_scene_graph_component.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_scene_graph_component.h new file mode 100644 index 0000000..f7d44f4 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_scene_graph_component.h @@ -0,0 +1,32 @@ +#pragma once + +#include "../c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct SceneGraphComponentCApi +{ + unsigned (*num_nodes)(SceneGraphComponentPtr comp, EntityRef e_ref); + unsigned (*node_index)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_name_id32); + unsigned (*parent)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_index); + + void (*set_local_position)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_index, ConstVector3Ptr new_pos); + void (*set_local_rotation)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_index, ConstQuaternionPtr new_rot); + void (*set_local_scale)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_index, ConstVector3Ptr new_scale); + void (*set_local_pose)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_index, ConstLocalTransformPtr new_pose); + + ConstVector3Ptr (*local_position)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_index); + CApiQuaternion (*local_rotation)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_index); + ConstVector3Ptr (*local_scale)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_index); + ConstLocalTransformPtr (*local_pose)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_index); + + ConstVector3Ptr (*world_position)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_index); + CApiQuaternion (*world_rotation)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_index); + ConstMatrix4x4Ptr (*world_pose)(SceneGraphComponentPtr comp, EntityRef e_ref, unsigned node_index); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_tag_component.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_tag_component.h new file mode 100644 index 0000000..2c8830b --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_tag_component.h @@ -0,0 +1,22 @@ +#pragma once + +#include "../c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct TagComponentCApi +{ + // Fills the specified buffer with up to (buffer_size) number of entities that has the tag. + // Returns the total number of entities the tag has. + unsigned (*get_entities)(TagComponentPtr comp, unsigned tag_id32, EntityRef *buffer, unsigned buffer_size); + + void (*add_tag)(TagComponentPtr comp, EntityRef e_ref, unsigned tag_id32); + void (*remove_tag)(TagComponentPtr comp, EntityRef e_ref, unsigned tag_id32); + int (*has_tag)(TagComponentPtr comp, EntityRef e_ref, unsigned tag_id32); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_transform_component.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_transform_component.h new file mode 100644 index 0000000..1830062 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_transform_component.h @@ -0,0 +1,37 @@ +#pragma once + +#include "../c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct TransformComponentCApi +{ + // Fills the specified buffer with up to (buffer_size) number of children of the component. + // Returns the total number of children the component has. + unsigned (*children)(TransformComponentPtr comp, Instance the_parent, EntityRef *buffer, unsigned buffer_size); + + EntityRef (*parent)(TransformComponentPtr comp, Instance the_child); + void (*unlink)(TransformComponentPtr comp, Instance the_child); + void (*link)(TransformComponentPtr comp, Instance the_child, Instance the_parent, ConstLocalTransformPtr child_local_pose); + void (*link_to_scene_graph)(TransformComponentPtr comp, Instance the_child, Instance the_parent, unsigned parent_node_index, ConstLocalTransformPtr child_local_pose); + + void (*set_local_position)(TransformComponentPtr comp, Instance instance, ConstVector3Ptr new_pos); + void (*set_local_rotation)(TransformComponentPtr comp, Instance instance, ConstQuaternionPtr new_rot); + void (*set_local_scale)(TransformComponentPtr comp, Instance instance, ConstVector3Ptr new_scale); + void (*set_local_pose)(TransformComponentPtr comp, Instance instance, ConstLocalTransformPtr new_pose); + + ConstVector3Ptr (*local_position)(TransformComponentPtr comp, Instance instance); + CApiQuaternion (*local_rotation)(TransformComponentPtr comp, Instance instance); + ConstVector3Ptr (*local_scale)(TransformComponentPtr comp, Instance instance); + ConstLocalTransformPtr (*local_pose)(TransformComponentPtr comp, Instance instance); + + ConstVector3Ptr (*world_position)(TransformComponentPtr comp, Instance instance); + CApiQuaternion (*world_rotation)(TransformComponentPtr comp, Instance instance); + ConstMatrix4x4Ptr (*world_pose)(TransformComponentPtr comp, Instance instance); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_unit_component.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_unit_component.h new file mode 100644 index 0000000..6f003fe --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/c_api/entity_components/c_api_unit_component.h @@ -0,0 +1,17 @@ +#pragma once + +#include "../c_api_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +struct UnitComponentCApi +{ + /* Gets the unit attached to the unit component. */ + CApiUnitRef (*unit)(UnitComponentPtr component, Instance instance); +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/default_plugin_suffix.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/default_plugin_suffix.h new file mode 100644 index 0000000..07fc098 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/default_plugin_suffix.h @@ -0,0 +1,19 @@ +#pragma once + +#if defined(WINDOWSPC) + #ifdef PLATFORM_64BIT + #define ENGINE_DEFAULT_PLUGIN_SUFFIX_BIT "w64" + #else + #define ENGINE_DEFAULT_PLUGIN_SUFFIX_BIT "w32" + #endif + + #if defined(_DEBUG) + #define ENGINE_DEFAULT_PLUGIN_SUFFIX_CONFIG "debug" + #elif defined(DEVELOPMENT) + #define ENGINE_DEFAULT_PLUGIN_SUFFIX_CONFIG "dev" + #else + #define ENGINE_DEFAULT_PLUGIN_SUFFIX_CONFIG "release" + #endif + + #define ENGINE_DEFAULT_PLUGIN_SUFFIX "_plugin" ENGINE_DEFAULT_PLUGIN_SUFFIX_BIT "_" ENGINE_DEFAULT_PLUGIN_SUFFIX_CONFIG ".dll" +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/plugin_api.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/plugin_api.h new file mode 100644 index 0000000..afc543b --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/plugin_api.h @@ -0,0 +1,2745 @@ +#pragma once + +#include "plugin_api_types.h" +#include "plugin_c_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* + This file defines the Plugin API for the engine. + + The plugin interface is based around a single function: + + __declspec(dllexport) void *get_plugin_api(unsigned api_id); + + The API ID is an integer that uniquely identify a specific version of a particular service. + If the plugin can provide the service it returns a pointer to an API struct that contains + function pointers for using the service. + + For ABI compatibility and simplicity, only C code is used in the interfaces. + + This method is used both by the plugins to provide services to the engine and by the engine + to provide services to the plugins. For the second case, the engine sends a function: + + void *get_engine_api(unsigned api_id); + + to the plugins when they are initialized. The plugins can use this function to query for + engine interfaces. Plugins can also use this to call on services provided by other plugins + through the get_next_plugin_api() in the PluginManagerApi. + + Starting with the 1.7 release of the engine, we will make an effort to keep the plugin + APIs backwards compatible. This means that you cannot remove functions or change the + signature of functions in the API, only add new ones in the reserved functions. Old functions + can be marked as deprecated but should be left in the API. + + If you need to make big changes to an API, that cannot easily be covered by just adding + new functions, you should make a completely new API with a new ID (i.e. + APPLICATION_API_V2_ID), while keeping the old one intact. That way, backwards compatibility + is ensured. +*/ + +#include + +/* API IDs for the different services. */ +enum PluginApiID { + PLUGIN_API_ID = 0, + LUA_API_ID = 1, + DATA_COMPILER_API_ID = 2, + DATA_COMPILE_PARAMETERS_API_ID = 3, + ALLOCATOR_API_ID = 4, + RESOURCE_MANAGER_API_ID = 5, + LOGGING_API_ID = 6, + UNIT_API_ID = 8, + SCENE_GRAPH_API_ID = 9, + FUTURE_INPUT_ARCHIVE_API_ID = 10, + INPUT_ARCHIVE_API_ID = 11, + APPLICATION_API_ID = 12, + APPLICATION_OPTIONS_API_ID = 13, + UNIT_REFERENCE_API_ID = 14, + ERROR_CONTEXT_API_ID = 15, + RENDER_INTERFACE_API_ID = 16, + RAYCAST_API_ID = 17, + RENDER_CALLBACKS_PLUGIN_API_ID = 18, + RENDER_OVERRIDES_PLUGIN_API_ID = 19, + FILESYSTEM_API_ID = 20, + PLUGIN_MANAGER_API_ID = 21, + WORLD_API_ID = 22, + LINE_OBJECT_DRAWER_API_ID = 23, + PROFILER_API_ID = 24, + ERROR_API_ID = 25, + RENDER_BUFFER_API_ID = 26, + MESH_API_ID = 27, + INPUT_BUFFER_API_ID = 28, + RENDER_SCENE_GRAPH_API_ID = 29, + SOUND_STREAM_SOURCE_API_ID = 30, + C_API_ID = 31, + THREAD_API_ID = 32, + TIMER_API_ID = 33, + MATERIAL_API_ID = 34, + SCENE_DATABASE_API_ID = 35, + STREAM_CAPTURE_API_ID = 36, + FLOW_NODES_API_ID = 37, + CAMERA_API_ID = 38, + ENTITY_COMPILE_DATA_API_ID = 39, + PHYSICS_RUNTIME_COOKING_API_ID = 40, + END_OF_ENGINE_RESERVED_RANGE = 65535, + + /* API IDs in the range 0--65535 are reserved by the engine. If you want to + provide your own API in your plugin, we suggest using a hash of the API's + name as ID. */ +}; + +/* ---------------------------------------------------------------------- + Common types +---------------------------------------------------------------------- */ + +/* These types are used in multiple plugins. */ + +/* Opaque struct representing an input file archive that data can be read from. */ +struct InputArchive; + +/* Opaque struct representing a buffer that an input archive gets information from. */ +struct InputBuffer; + +/* ---------------------------------------------------------------------- + Plugin +---------------------------------------------------------------------- */ + +/* This function can be used by the plugin to query for engine APIs. */ +typedef void *(*GetApiFunction)(unsigned api); + +/* Opaque struct representing a stream of state changes sent from the main thread to the render + thread. */ +struct StateReflectionStream; + +/* Deprecated. */ +struct RD_DeviceData { + struct Context *context; + struct RenderTarget* render_target; + struct DepthStencilTarget* depth_stencil_target; +}; + +/* Deprecated. */ +struct RD_EngineData { + /* A custom rendering environment returned by the plugin in get_render_env(). */ + void* render_env; + void* render_target; + void* depth_stencil_target; +}; + +/* Deprecated. */ +struct RenderDevicePluginArguments { + struct RD_DeviceData device_data; + struct RD_EngineData engine_data; +}; + +/* + This is the main interface provided by the plugins. The functions in this interface will + be called at various points during the engine's setup and shutdown sequence. + + The plugin is not obligated to implement all these functions. You can return NULL for the + functions that you do not support. +*/ +struct PluginApi +{ + /* Returns the name of the plugin. */ + const char *(*get_name)(); + + /* Called to initialize the plugin once it has been loaded into memory. For plugins loaded at + boot, this function is called once all plugins have been loaded (so you can query for other + plugins in this function). For plugins loaded on demand, this function is called as soon + as the plugin have been loaded. */ + void (*loaded)(GetApiFunction get_engine_api); + + /* Called just before the plugin is unloaded. */ + void (*unloaded)(); + + /* Called at the start of a "hot reload" of the plugin DLL. Should return a + pointer to a serialized "state" for the plugin.*/ + void *(*start_reload)(GetApiFunction get_engine_api); + + /* Called to finalized the "hot reload" after the plugin has been reloaded with + the new code. Should restore the state from the serialized state data. Note + that it is the responsibility of the plugin to free the state data. */ + void (*finish_reload)(GetApiFunction get_engine_api, void *state); + + /* Called when the engine sets up the DataCompiler. You can use the functions in the DataCompiler + API to add custom data types to the DataCompiler. */ + void (*setup_data_compiler)(GetApiFunction get_engine_api); + + /* Called when the engine shuts down the data compiler. */ + void (*shutdown_data_compiler)(); + + /* Called when the engine sets up the ResourceManager. At this point you can use the ResourceManagerApi + to add support for resource manager loading of your custom data types. */ + void (*setup_resources)(GetApiFunction get_engine_api); + + /* Called when the engine shuts down the ResourceManager. */ + void (*shutdown_resources)(); + + /* Called when the engine reloads its resources. The plugin should return true if it is able + to hot-reload resources of the specified type. */ + int (*can_refresh)(uint64_t type); + + /* Called when the engine reloads its resources, to tell the plugin to refresh the given resource. */ + void (*refresh)(uint64_t type, uint64_t name); + + /* Called when the engine sets up the game. At this point, you can use the functions in the LuaApi + to add functions to the engine's Lua API. */ + void (*setup_game)(GetApiFunction get_engine_api); + + /* Called per game frame. */ + void (*update_game)(float dt); + + /* Called when the engine shuts down the game. */ + void (*shutdown_game)(); + + /* Called after the world has been created and is about to be added to the engines list of worlds */ + void (*register_world)(CApiWorld * world); + + /* Called before a world is about to be destroyed and removed from the engines list of worlds. */ + void (*unregister_world)(CApiWorld * world); + + /* Called when units are spawned by the engine. */ + void (*units_spawned)(CApiUnit **units, unsigned count); + + /* Called when units are unspawned by the engine. */ + void (*units_unspawned)(CApiUnit **units, unsigned count); + + /* Called by the engine to draw debug visuals into the world. */ + void (*debug_draw)(CApiWorld * world, struct StateReflectionStream * srs); + + /* Deprecated. */ + void * (*get_render_env)(); + + /* Deprecated. */ + void (*render)(struct RenderDevicePluginArguments *arguments); + + /* Reserved for expansion of the API. */ + void *reserved[32]; +}; + +/* + This is the interface implemented by plugins who are interested in callbacks from the rendering + thread. + + The plugin is not obligated to implement all these functions. You can return NULL for the + functions that you do not support. +*/ +struct RenderCallbacksPluginApi +{ + /* Called when a new swapchain is created. */ + void (*create_swap_chain)(unsigned swap_chain_handle, unsigned width, unsigned height); + + /* Called just before a swap chain is resized. */ + void (*prepare_resize_swap_chain)(unsigned swap_chain_handle, unsigned width, unsigned height); + + /* Called when a swap chain has been resized. */ + void (*resize_swap_chain)(unsigned swap_chain_handle, unsigned width, unsigned height); + + /* Called when a swap chain is destroyed. */ + void (*destroy_swap_chain)(unsigned swap_chain_handle); + + /* Called when rendering of a frame starts. */ + void (*begin_frame)(); + + /* Called when rendering of a frame finishes. */ + void (*end_frame)(); + + /* Reserved for expansion of the API. */ + void *reserved[32]; +}; + +/* + This is the interface implemented by plugins who are interested in overriding certain functionality + on the rendering thread. + + The plugin is not obligated to implement all these functions. You can return NULL for the + functions that you do not support. + + TODO: How do we best deal with multiple plugins overriding the same function? +*/ +struct RenderOverridesPluginApi +{ + /* Called when the engine presents the rendered data. + + You should return 0 from this function if you still want the default present functionality + to be executed. Otherwise, return 1. */ + int (*present)(unsigned swap_chain_handle); + + /* Reserved for expansion of the API. */ + void *reserved[32]; +}; + +/* ---------------------------------------------------------------------- + Lua +---------------------------------------------------------------------- */ + +/* Opaque struct representing a Lua state. */ +typedef struct lua_State lua_State; + +/* Types from Lua. */ +typedef int (*lua_CFunction) (lua_State *L); +typedef struct lua_Debug lua_Debug; +typedef double lua_Number; +typedef ptrdiff_t lua_Integer; +typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); +typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); +typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); +typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); +typedef struct luaL_Reg luaL_Reg; + +/* + Interface to access Lua services. +*/ +struct LuaApi +{ + /* ----------------------------------------------------------------------- + Extending Lua + ----------------------------------------------------------------------- */ + + /* Adds a new lua function in the module with the specified name. + + The function will be callable as stingray.{module}.{name}() */ + void (*add_module_function)(const char *module, const char *name, lua_CFunction f); + + /* As add_module_function() but prints a deprecation warning when the function is used. */ + void (*deprecated_warning)(const char *module, const char *name, lua_CFunction f, const char* message); + + /* As add_module_function() but prints a deprecation error when the function is used. */ + void (*deprecated_error)(const char *module, const char *name, const char* message); + + /* Sets a bool constant in a module. */ + void (*set_module_bool)(const char *module, const char *key, int value); + + /* Sets a number constant in a module. */ + void (*set_module_number)(const char *module, const char *key, double value); + + /* Sets a number constant in a namespace in a module. */ + void (*set_module_namespace_number)(const char *module, const char* name_space, const char *key, double value); + + /* Sets a string constant in a module. */ + void (*set_module_string)(const char *module, const char *key, const char *value); + + /* Adds a new console command. Console commands are Lua functions in the stingray.Console + module that only takes string parameters. They can be used from the console: + + > memory_resources all + + is equivalent to + + > Console.memory_resources("all") + + The vararg is a sequence of documentation strings, ended by a nullptr -- like this: + + add_console_command("memory_resources", memory_resources_f, + "Print memory usage per resource", + "all", "print memory use of all resources", + "sound", "print memory use of sound resources", + "texture_categories [details]", "print memory usage per texture category", + "list ", "list memory use of specified types", + (void*)nullptr); */ + void (*add_console_command)(const char *command, lua_CFunction f, const char *desc, ...); + + /* Removes all entries from the specified module. */ + void (*remove_all_module_entries)(const char *module); + + /* Removes the specified module entry from the runtime. */ + void (*remove_module_entry)(const char *module, const char *entry); + + /* ----------------------------------------------------------------------- + Lua standard functions + + See the Lua API for documentation. + ----------------------------------------------------------------------- */ + + /* State manipulation */ + void (*close) (lua_State *L); + lua_State *(*newthread) (lua_State *L); + lua_CFunction (*atpanic) (lua_State *L, lua_CFunction panicf); + + /* Basic stack manipulation */ + int (*gettop) (lua_State *L); + void (*settop) (lua_State *L, int idx); + void (*pushvalue) (lua_State *L, int idx); + void (*remove) (lua_State *L, int idx); + void (*insert) (lua_State *L, int idx); + void (*replace) (lua_State *L, int idx); + int (*checkstack) (lua_State *L, int sz); + void (*xmove) (lua_State *from, lua_State *to, int n); + + /* Access functions */ + int (*isnumber) (lua_State *L, int idx); + int (*isstring) (lua_State *L, int idx); + int (*iscfunction) (lua_State *L, int idx); + int (*isuserdata) (lua_State *L, int idx); + int (*type) (lua_State *L, int idx); + const char *(*lua_typename) (lua_State *L, int tp); + + int (*equal) (lua_State *L, int idx1, int idx2); + int (*rawequal) (lua_State *L, int idx1, int idx2); + int (*lessthan) (lua_State *L, int idx1, int idx2); + + lua_Number (*tonumber) (lua_State *L, int idx); + lua_Integer (*tointeger) (lua_State *L, int idx); + int (*toboolean) (lua_State *L, int idx); + const char *(*tolstring) (lua_State *L, int idx, size_t *len); + size_t (*objlen) (lua_State *L, int idx); + lua_CFunction (*tocfunction) (lua_State *L, int idx); + void *(*touserdata) (lua_State *L, int idx); + lua_State *(*tothread) (lua_State *L, int idx); + const void *(*topointer) (lua_State *L, int idx); + + /* Push functions */ + void (*pushnil) (lua_State *L); + void (*pushnumber) (lua_State *L, lua_Number n); + void (*pushinteger) (lua_State *L, lua_Integer n); + void (*pushlstring) (lua_State *L, const char *s, size_t l); + void (*pushstring) (lua_State *L, const char *s); + const char *(*pushvfstring) (lua_State *L, const char *fmt, va_list argp); + const char *(*pushfstring) (lua_State *L, const char *fmt, ...); + void (*pushcclosure) (lua_State *L, lua_CFunction fn, int n); + void (*pushboolean) (lua_State *L, int b); + void (*pushlightuserdata) (lua_State *L, void *p); + int (*pushthread) (lua_State *L); + + /* Get functions */ + void (*gettable) (lua_State *L, int idx); + void (*getfield) (lua_State *L, int idx, const char *k); + void (*rawget) (lua_State *L, int idx); + void (*rawgeti) (lua_State *L, int idx, int n); + void (*createtable) (lua_State *L, int narr, int nrec); + void *(*newuserdata) (lua_State *L, size_t sz); + int (*getmetatable) (lua_State *L, int objindex); + void (*getfenv) (lua_State *L, int idx); + + /* Set functions */ + void (*settable) (lua_State *L, int idx); + void (*setfield) (lua_State *L, int idx, const char *k); + void (*rawset) (lua_State *L, int idx); + void (*rawseti) (lua_State *L, int idx, int n); + int (*setmetatable) (lua_State *L, int objindex); + int (*setfenv) (lua_State *L, int idx); + + /* Load and call functions */ + void (*call) (lua_State *L, int nargs, int nresults); + int (*pcall) (lua_State *L, int nargs, int nresults, int errfunc); + int (*cpcall) (lua_State *L, lua_CFunction func, void *ud); + int (*load) (lua_State *L, lua_Reader reader, void *dt, const char *chunkname); + int (*dump) (lua_State *L, lua_Writer writer, void *data); + + /* Coroutine functions */ + int (*yield) (lua_State *L, int nresults); + int (*resume) (lua_State *L, int narg); + int (*status) (lua_State *L); + + /* Garbage collection */ + int (*gc) (lua_State *L, int what, int data); + + /* Miscellaneous functions */ + int (*error) (lua_State *L); + int (*next) (lua_State *L, int idx); + void (*concat) (lua_State *L, int n); + + /* Debugging */ + int (*getstack) (lua_State *L, int level, lua_Debug *ar); + int (*getinfo) (lua_State *L, const char *what, lua_Debug *ar); + const char *(*getlocal) (lua_State *L, const lua_Debug *ar, int n); + const char *(*setlocal) (lua_State *L, const lua_Debug *ar, int n); + const char *(*getupvalue) (lua_State *L, int funcindex, int n); + const char *(*setupvalue) (lua_State *L, int funcindex, int n); + + int (*sethook) (lua_State *L, lua_Hook func, int mask, int count); + lua_Hook (*gethook) (lua_State *L); + int (*gethookmask) (lua_State *L); + int (*gethookcount) (lua_State *L); + + /* Library functions */ + void (*lib_openlib) (lua_State *L, const char *libname, const luaL_Reg *l, int nup); + void (*lib_register) (lua_State *L, const char *libname, const luaL_Reg *l); + int (*lib_getmetafield) (lua_State *L, int obj, const char *e); + int (*lib_callmeta) (lua_State *L, int obj, const char *e); + int (*lib_typerror) (lua_State *L, int narg, const char *tname); + int (*lib_argerror) (lua_State *L, int numarg, const char *extramsg); + const char *(*lib_checklstring) (lua_State *L, int numArg, size_t *l); + const char *(*lib_optlstring) (lua_State *L, int numArg, const char *def, size_t *l); + lua_Number (*lib_checknumber) (lua_State *L, int numArg); + lua_Number (*lib_optnumber) (lua_State *L, int nArg, lua_Number def); + lua_Integer (*lib_checkinteger) (lua_State *L, int numArg); + lua_Integer (*lib_optinteger) (lua_State *L, int nArg, lua_Integer def); + void (*lib_checkstack) (lua_State *L, int sz, const char *msg); + void (*lib_checktype) (lua_State *L, int narg, int t); + void (*lib_checkany) (lua_State *L, int narg); + int (*lib_newmetatable) (lua_State *L, const char *tname); + void*(*lib_checkudata) (lua_State *L, int ud, const char *tname); + void (*lib_where) (lua_State *L, int lvl); + int (*lib_error) (lua_State *L, const char *fmt, ...); + int (*lib_checkoption) (lua_State *L, int narg, const char *def, const char *const lst[]); + int (*lib_ref) (lua_State *L, int t); + void (*lib_unref) (lua_State *L, int t, int ref); + int (*lib_loadfile) (lua_State *L, const char *filename); + int (*lib_loadbuffer) (lua_State *L, const char *buff, size_t sz, const char *name); + int (*lib_loadstring) (lua_State *L, const char *s); + lua_State *(*lib_newstate) (void); + const char *(*lib_gsub) (lua_State *L, const char *s, const char *p, const char *r); + const char *(*lib_findtable) (lua_State *L, int idx, const char *fname, int szhint); + void (*lib_openlibs)(lua_State *L); + + /* ----------------------------------------------------------------------- + Lua Stingray extensions + ----------------------------------------------------------------------- */ + + /* Gets an index integer from the stack. This will automatically convert + from 1-based (Lua convention) to 0-based (C convention). */ + int (*getindex) (lua_State *L, int idx); + + /* Pushes an index integer to the stack. This will automatically convert + from 0-based (C convention) to 1-based (lua convention). */ + void (*pushindex) (lua_State *L, int n); + + /* As getindex() but uses either 0 or 1 based convention on the Lua side, + depending on user project settings. */ + int (*getindex_0_or_1_based) (lua_State *L, int idx); + + /* As pushindex() but uses either 0 or 1 based convention on the Lua side, + depending on user project settings. */ + void (*pushindex_0_or_1_based) (lua_State *L, int n); + + /* Pushes a Vector2 to the stack. */ + void (*pushvector2) (lua_State *L, float v[2]); + + /* Pushes a Vector3 to the stack. */ + void (*pushvector3) (lua_State *L, float v[3]); + + /* Pushes a Vector4 to the stack. */ + void (*pushvector4) (lua_State *L, float v[4]); + + /* Pushes a Quaternion to the stack. */ + void (*pushquaternion) (lua_State *L, float q[4]); + + /* Pushes a Matrix4x4 to the stack. */ + void (*pushmatrix4x4) (lua_State *L, float m[16]); + + /* Gets a Vector2 at the specified index. */ + float * (*getvector2) (lua_State *L, int i); + + /* Gets a Vector3 at the specified index. */ + float * (*getvector3) (lua_State *L, int i); + + /* Gets a Vector4 at the specified index. */ + float * (*getvector4) (lua_State *L, int i); + + /* Gets a Quaternion at the specified index. */ + float * (*getquaternion) (lua_State *L, int i); + + /* Gets a Matrix4x4 at the specified index. */ + float * (*getmatrix4x4) (lua_State *L, int i); + + /* Gets a Unit at the specified index. */ + CApiUnit * (*getunit) (lua_State *L, int i); + + /* Gets the Lua state where the main scripts execute. */ + lua_State* (*getscriptenvironmentstate)(); + + /* Returns true if the stack entry is a table. */ + int (*istable) (lua_State *L, int i); + + /* Returns true if the stack entry is a Vector2. */ + int (*isvector2) (lua_State *L, int i); + + /* Returns true if the stack entry is a Vector3. */ + int (*isvector3) (lua_State *L, int i); + + /* Returns true if the stack entry is a Vector4. */ + int (*isvector4) (lua_State *L, int i); + + /* Returns true if the stack entry is a Quaternion. */ + int (*isquaternion) (lua_State *L, int i); + + /* Returns true if the stack entry is a Matrix4x4. */ + int (*ismatrix4x4) (lua_State *L, int i); + + /* Returns true if the stack entry is a UnitReference. */ + int (*isunitreference) (lua_State *L, int i); + + /* Pops the top value from the Lua stack. */ + void (*pop) (lua_State *L); + + /* Gets an Entity at the specified index. */ + EntityRef (*getentity)(lua_State *L, int i); + + /* Pushes an Entity to the stack. */ + void (*pushentity)(lua_State *L, EntityRef e_ref); + + /* Returns true if the stack entry is a nil. */ + int(*isnil) (lua_State *L, int i); + + /* Returns true if the stack entry is a boolean. */ + int(*isbool) (lua_State *L, int i); + + /* Reserved for expansion of the API. */ + void *reserved[28]; +}; + +/* ---------------------------------------------------------------------- + DataCompiler +---------------------------------------------------------------------- */ + +/* Represents a buffer of data. */ +struct Buffer +{ + /* Pointer to data. */ + char *p; + + /* Size of data. */ + unsigned len; +}; + +struct ConfigErrorState +{ + const char *file; + struct Buffer source; + const char *error; +}; + +/* Represents the result of a data compile operation. */ +struct DataCompileResult +{ + /* The memory resident compiled data. */ + struct Buffer data; + + /* Compiled data available for streaming. */ + struct Buffer stream; + + /* NULL if compiled successfully, an error message otherwise. */ + const char *error; +}; + +/* Opaque struct representing parameters for a data compile operation. */ +struct DataCompileParameters; + +/* Opaque struct representing parameters for a entity compile operation. */ +struct EntityComponentCompileData; + +/* Opaque struct representing parameters for a entity compile operation. */ +struct EntityComponentPackageIncludeData; + +/* Function type for compiling data. Based on the compile parameters that include + among other things the source data, the compile function should produce a + binary blob that can be accessed as a resource by the runtime. */ +typedef struct DataCompileResult (*CompileFunction)(struct DataCompileParameters *data_compile_params); + +/* Function for compiling preprocessed data for a closed platform. This is called from a normal + resource compiler to do closed platform specific compilation for a particular platform. The + format of the input data depends on the resource type (note: it is not the raw source data). */ +typedef struct DataCompileResult (*RawCompileFunction)(const char *input, unsigned len, struct AllocatorObject *allocator); + +/* Function type for compiling additional dependencies. You can use this to add new dependencies + for an existing resource type, such as .level, without changing how that type is compiled. + The function should return NULL if successful and an error string otherwise. */ +typedef const char * (*PackageIncludeCompileFunction)(struct DataCompileParameters *data_compile_params); + +/* Function type for compiling entity component data. */ +typedef struct DataCompileResult (*EntityComponentCompileFunction)(struct EntityComponentCompileData *compile_data, struct EntityComponentPackageIncludeData *package_include_data); + +/* Enumerates the texture types that can be returned by custom texture readers. */ +enum SourceTextureReadResult_ResultType { + DC_STRR_RT_IMAGE2D, + DC_STRR_RT_IMAGE3D, + DC_STRR_RT_IMAGECUBE, + DC_STRR_RT_UNKNOWN +}; + +/* Enumerates the texture pixel formats that can be returned by customer texture readers. */ +enum SourceTextureReadResult_ResultPixelFormat { + DC_STRR_RPF_R8G8B8A8, + DC_STRR_RPF_R16F, + DC_STRR_RPF_R16G16B16A16F, + DC_STRR_RPF_R16G16F, + DC_STRR_RPF_NUM_FORMATS, + DC_STRR_RPF_UNKNOWN +}; + +/* Format of the texture data returned by custom texture readers. Currently only one format is + supported, the one described by SourceTextureReadResult */ +#define SOURCE_TEXTURE_READ_RESULT_DEFAULT_FORMAT 1 + +/* Used to return the result of a custom texture read operation. */ +struct SourceTextureReadResult { + /* Format of the returned data. This should be equal to SOURCE_TEXTURE_READ_RESULT_DEFAULT_FORMAT. */ + unsigned format; + + /* Texture dimensions. */ + unsigned width; + unsigned height; + + /* Format of the pixel data. */ + enum SourceTextureReadResult_ResultPixelFormat pixel_format; + + /* Type of image. */ + enum SourceTextureReadResult_ResultType image_type; + + /* Pixel data container. */ + struct Buffer data; + + /* NULL if read successfully, an error message otherwise. */ + const char *error; +}; + +/* Function type for custom texture readers. */ +typedef struct SourceTextureReadResult (*SourceTextureReadFunction)(const char *type, const void *data, unsigned len, struct AllocatorObject *allocator); + +/* + API for extending Stingray with your own custom data types. +*/ +struct DataCompilerApi +{ + /* Adds a data compiler for a new data type to the Stingray engine. The version + parameter specifies the version number of the binary data. Increase the number if + you make any changes to the binary format. */ + void (*add_compiler)(const char *type, unsigned version, CompileFunction compile); + + /* Adds a data compiler for one of the closed platforms (XB1, PS4). (Since these + compilers contain closed code, they can't be in the main engine, but must be + loaded as plugins. */ + void (*add_closed_platform_compiler)(const char *platform, const char *type, RawCompileFunction compile); + + /* Adds a compile step that can add additional dependencies to an existing resource format, + without otherwise changing how that resource format is compiled. For example, it can be + used to add new dependencies to .level files. */ + void (*add_extra_package_include_compiler)(const char *type, int id, int version, PackageIncludeCompileFunction compile); + + /* Adds a new texture reader to Stingray. This lets Stingray support additional texture + formats. */ + void (*add_texture_reader)(const char *type, SourceTextureReadFunction read); + + /* Specifies that the compiler for the specified type uses the FBX SDK. This is needed because + the FBX SDK is not thread safe, so compilers that use the FBX SDK must be serialized + on a single thread. */ + void (*set_uses_fbx)(const char *type); + + /* Adds an entity component compiler for the specified component typename. */ + void(*add_entity_component_compiler)(const char *name, EntityComponentCompileFunction compile, int spawn_order); + + /* Reserved for expansion of the API. */ + void *reserved[32]; +}; + +/* ---------------------------------------------------------------------- + DataCompileParameters +---------------------------------------------------------------------- */ + +/* + Used to get information about a resource that is being compiled. +*/ +struct DataCompileParametersApi +{ + /* Path to the resource on disk. */ + const char * (*source_path)(struct DataCompileParameters *input); + + /* Name of the resource. */ + const char * (*name)(struct DataCompileParameters *input); + + /* Gets the string name of the destination platform that the data is compiled for. */ + const char * (*destination_platform)(struct DataCompileParameters *input); + + /* Parses the input data as a SJSON file and returns a buffer describing the data. + The buffer uses the ConstConfig format and can be interpreted using the ConstConfig + API in plugin_foundation. */ + struct DataCompileResult (*parse)(struct DataCompileParameters *input); + + /* Reads the input data and returns it as a raw buffer. */ + struct DataCompileResult (*read)(struct DataCompileParameters *input); + + /* Used to read the content of file folders, i.e. folders that are treated as a single + resource by the data compiler (like .s2d folders). + + The entire content of the folder will be returned in a buffer with the following layout: + + [number_of_files] + [offset_to_path_1] [size_of_path_1] [offset_to_file_data_1] [size_of_file_data_1] + [offset_to_path_2] [size_of_path_2] [offset_to_file_data_2] [size_of_file_data_2] + ... + [offset_to_path_n] [size_of_path_n] [offset_to_file_data_n] [size_of_file_data_n] + [buffer_data] + + All the sizes and offsets are uint32_t. */ + struct DataCompileResult (*read_file_folder)(struct DataCompileParameters *input); + + /* Returns the allocator that should be used to allocate the data returned by the compile + function. */ + struct AllocatorObject *(*allocator)(struct DataCompileParameters *input); + + /* Creates a package include of the resource specified by (type, name) for the resource that + is being compiled. What this means is that the compiled resource has an automatic dependency + on (type, name), so whenever the compiled resource is included in a package, its + dependencies will follow. This is used for example to ensure that when you include a level + in a package, all its units and their textures follow along. */ + void (*include_in_package)(struct DataCompileParameters *input, const char *type, const char *name); + + /* Creates a package include of all the resources of the type that match the pattern + `{prefix}*{suffix}`. */ + void (*glob_include_in_package)(struct DataCompileParameters *input, const char *prefix, const char *suffix, const char *type); + + /* Returns true if the path exists. */ + int (*exists)(struct DataCompileParameters *input, const char *path); + + /* Reserved for expansion of the API. */ + void *reserved[32]; +}; + +/* ---------------------------------------------------------------------- + EntityCompileDataApi +---------------------------------------------------------------------- */ + +/* API for working with entity compile data. */ +struct EntityCompileDataApi +{ + /* Returns the allocator to use for compiled data. */ + struct AllocatorObject *(*allocator)(struct EntityComponentCompileData *compile_data); + + /* Returns the component type definition. */ + struct Buffer (*type_definition)(struct EntityComponentCompileData *compile_data, struct AllocatorObject *allocator); + + /* Returns the component meta data. */ + struct Buffer (*type_metadata)(struct EntityComponentCompileData *compile_data, struct AllocatorObject *allocator); + + /* Returns the property for the specified property key. */ + struct Buffer (*get_property)(struct EntityComponentCompileData *compile_data, const char *property_key, struct AllocatorObject *allocator, struct ConfigErrorState *es); + + /* Returns the merged property for the specified property key. */ + struct Buffer (*get_merged_property)(struct EntityComponentCompileData *compile_data, const char *property_key, struct AllocatorObject *allocator, struct ConfigErrorState *es); +}; + +/* ---------------------------------------------------------------------- + Allocator +---------------------------------------------------------------------- */ + +/* + API used to allocate memory through an AllocatorObject. +*/ +struct AllocatorApi +{ + /* Create a new allocator for use by the plugin. */ + struct AllocatorObject *(*make_plugin_allocator)(const char *plugin_name); + + /* Destroys an allocator created by make_plugin_allocator(). You must free all the memory + allocated by the allocator before you destroy it. */ + void (*destroy_plugin_allocator)(struct AllocatorObject *); + + /* Makes a physical allocator for the plugin. This is an allocator that is guaranteed to + allocate physical (i.e. not virtual) memory. This is needed by certain resource + types that cannot reside in virtual memory. + + The allocator should be destroyed by destroy_plugin_allocator(). */ + struct AllocatorObject *(*make_plugin_physical_allocator)(const char *plugin_name); + + /* Creates a temporary memory allocator. Temporary memory allocators should be used + for short-term memory allocations that are released before a function exits (i.e. + similar to alloca()). Allocations made with the temporary memory allocator do not + have to be explicitly freed. They are automatically freed when you destroy the allocator. + + You should call destroy_temp_allocator() to destroy the allocator before exiting the + function. + + Temporary allocators are not thread safe and can only be used on the thread that creates + them. */ + struct AllocatorObject *(*make_temp_allocator)(); + + /* Destroys a temporary memory allocator created by make_temp_allocator(). */ + void (*destroy_temp_allocator)(struct AllocatorObject *); + + /* Allocates memory using the specified allocator. The align parameter specifies the + desired alignment of the allocated memory. */ + void *(*allocate)(struct AllocatorObject *allocator, size_t size, unsigned align); + + /* Frees memory allocated by allocate(). */ + size_t (*deallocate)(struct AllocatorObject *allocator, void *p); + + /* Returns the size of the memory block allocated at p. p must be a block of memory allocated + by the specified allocator. Note that the allocated_size() might be greater than the size + requested in the call to allocate(). (Some allocators round up the allocations.) */ + size_t (*allocated_size)(struct AllocatorObject *allocator, void *p); +}; + +/* ---------------------------------------------------------------------- + ResourceManager +---------------------------------------------------------------------- */ + +/* Opaque struct representing an InputArchive that will become readable at some point in the + future. */ +struct FutureInputArchive; + +/* Hashed version of a resource names. */ +typedef uint64_t ResourceID; + +/* Opaque struct representing a context in which changes can be applied to GPU residing resources. */ +struct RenderResourceContext; + +/* Struct of callbacks used to implement a custom resource type on the runtime side. You don't + need to implement all the functions in this interface. Use NULL for the functions you don't + implement. */ +struct RM_ResourceTypeCallbacks +{ + /* User data that will be supplied to you in the obj parameter of the callback functions. */ + void *user_data; + + /* Called to load a resource into memory. `name` is the name of the resource and `archive` its + serialized data. The function should allocate an in-memory representation of the resource + with the `allocator` and return it. + + You only need to implement this callback if you want the in-memory representation to be + different than the disk serialized one. The recommendation is to use the same format on + disk as in-memory. Then you can use NULL for this callback and the disk data will + automatically be loaded into memory. */ + void *(*load) (void *obj, ResourceID name, struct InputArchive *archive, struct AllocatorObject *allocator, struct RenderResourceContext *rrc); + + /* A companion to load(), this is used to destroy the in-memory representation. You only need + to implement this if you implement load(), to destroy the data allocated by load(). */ + void (*destroy) (void *obj, void *resource, struct AllocatorObject *allocator, struct RenderResourceContext *rrc); + + /* This is called on the main thread, once the resource data has been loaded. Implement this + if you need to register the loaded data in some global structure. */ + void (*bring_in) (void *obj, void *resource); + + /* Implement this to unregister what you registered in bring_in(). */ + void (*bring_out) (void *obj, void *resource); + + /* Allocator used to allocate the data if using default load. Use NULL to use the default + allocator. */ + struct AllocatorObject *allocator; + + /* Desired alignment of the loaded resource data into memory if using default load. Use 0 to + use default alignment. */ + unsigned int align; + + /* Reserved for expansion of the API. */ + void *reserved[32]; +}; + +/* + Interface to the Stingray ResourceManager. The ResourceManager can be used to query for loaded + resources as well as to implement custom loaders for custom types. +*/ +struct ResourceManagerApi +{ + /* Returns the version number of the resource manager. The version number is changed + whenever resources are added or removed. */ + unsigned int (*version)(); + + /* Gets a list of loaded resources for the specified type. The function returns the total + number of loaded resources of the specified type, and the first names_size of these + resources are copied into the names array. You can call the function with zero to size + the array. */ + unsigned (*loaded_resources)(const uint64_t type_id, uint64_t *names, unsigned names_size); + + /* Registers a new resource type with the resource manager. The type uses the default load + mechanism (i.e. the serialized data will be loaded directly into memory as a data blob, + with no additional patching). */ + void (*register_type)(const char *type); + + /* Registers a new resource type with custom load functionality. */ + void (*register_type_with_callbacks)(const char *type, struct RM_ResourceTypeCallbacks * data); + + /* Returns true if there is a loaded resource with the specified type and name. */ + int (*can_get)(const char *type, const char *name); + + /* As can_get(), but uses a hashed type and name instead. */ + int (*can_get_by_id)(uint64_t type_id, uint64_t name_id); + + /* Returns the loaded resource identified by (type, name). This will assert if there is no + resource loaded with the specified type and name. */ + void *(*get)(const char *type, const char *name); + + /* As get() but uses a hashed type and name instead. */ + void *(*get_by_id)(uint64_t type_id, uint64_t name_id); + + /* Opens the streamed data belonging to the resource. When you are done with using the data + you should destroy it with delete_stream(). + + The data is returned as a FutureInputArchive... this is an input stream that will be + ready for reading at some point in the future. */ + struct FutureInputArchive * (*new_open_stream)(struct AllocatorObject * allocator, + const char * type, const char * name); + + /* As new_open_stream() but uses a hashed type and name instead. */ + struct FutureInputArchive * (*new_open_stream_by_id)(struct AllocatorObject * allocator, + uint64_t type_id, uint64_t name_id); + + /* Destroys a stream opened by new_open_stream(). */ + void (*delete_stream)(struct FutureInputArchive * fia, struct AllocatorObject * allocator); + + /* Returns true if the specified resource is online. */ + int(*is_online)(const char *type, const char *name); + + /* As is_online() but uses a hashed type and name instead. */ + int(*is_online_by_id)(uint64_t type_id, uint64_t name_id); + + /* Reserved for expansion of the API. */ + void *reserved[30]; +}; + +/* ---------------------------------------------------------------------- + FutureInputArchive +---------------------------------------------------------------------- */ + +/* + Interface for FutureInputArchives. A FutureInputArchive is used to represent a file that will + become readable at some point in the future. A future is used, since accessing the file + immediately might cause a stall. +*/ +struct FutureInputArchiveApi +{ + /* Returns true if the archive is ready to be used, i.e. if new_archive() will succeed without + stalling. */ + int (*ready)(struct FutureInputArchive * fia); + + /* Waits for the archive to be ready for usage. Note that this will stall the waiting thread. */ + void (*wait)(struct FutureInputArchive * fia); + + /* Cancels the request for the InputArchive. You can use this if you decide that you are no + longer interested in reading from the archive. + + A FutureInputArchive should always be properly closed, either by calling cancel() on it, + or by calling new_archive() to explicitly create an InputArchive from it. */ + void (*cancel)(struct FutureInputArchive * fia); + + /* Creates an InputArchive from the FutureInputArchive. The created archive must be destroyed + with delete_archive(). This function will stall if the archive is not ready to be opened. */ + struct InputArchive * (*new_archive)(struct FutureInputArchive * fia, + struct AllocatorObject * allocator); + + /* Deletes an archive created by new_archive(). You must delete the archive when done with it. */ + void (*delete_archive)(struct InputArchive * fia, struct AllocatorObject * allocator); + + /* Reserved for expansion of the API. */ + void *reserved[32]; +}; + +/* ---------------------------------------------------------------------- + InputArchive +---------------------------------------------------------------------- */ + +/* + Interface that represents a stream of data from disk or memory. +*/ +struct InputArchiveApi +{ + /* Reads size bytes from the archive into the buffer. */ + void (*read)(struct InputArchive * input_archive, void *buffer, unsigned size); + + /* Sets the read position of the archive to the specified offset. */ + void (*set_position)(struct InputArchive * input_archive, int64_t position); + + /* Returns the size of the archive. */ + int64_t (*size)(struct InputArchive * input_archive); + + /* Provides raw access to the input buffer that feeds the archive. Accessing the input + buffer directly is needed if you want to be able to stream data from the archive + without stalling. (Just calling read() on a disk archive might stall your thread.) */ + struct InputBuffer * (*buffer)(struct InputArchive * input_archive); + + /* Reserved for expansion of the API. */ + void *reserved[32]; +}; + +/* ---------------------------------------------------------------------- + InputBuffer +---------------------------------------------------------------------- */ + +/* + Interface for performing low level operations (such as streaming) on a stream of input data. +*/ +struct InputBufferApi +{ + /* The total size of the input buffer data. A never ending buffer will return INT64_MAX. */ + int64_t (*size)(struct InputBuffer * input_buffer); + + /* The number of bytes available to be read directly from the pointer without streaming in + more data. */ + unsigned (*available)(struct InputBuffer * input_buffer); + + /* Consumes `bytes` bytes. Note that that many bytes must be available in the buffer. */ + void (*consume)(struct InputBuffer * input_buffer, unsigned bytes); + + /* Ensures that at least the specified number of bytes are available in + the buffer. Will flush (stall) to fetch the bytes if necessary. */ + void (*ensure)(struct InputBuffer * input_buffer, unsigned bytes); + + /* Returns a raw pointer to the start of the input stream. You can read available() bytes + from the stream and then consume() those bytes to advance the stream pointer. */ + void * (*ptr)(struct InputBuffer * input_buffer); + + /* Returns the current offset of the readhead. */ + int64_t (*position)(struct InputBuffer * input_buffer); + + /* Sets the stream readhead to the specified position. */ + void (*set_position)(struct InputBuffer * input_buffer, int64_t offset); + + /* Sets the size of the "chunks" used to stream in data from disk. + Typically an input buffer keeps two chunks in flight, and when you have consumed one chunk + fully, a new one is streamed in, in the background. */ + void (*set_read_chunk)(struct InputBuffer * input_buffer, unsigned size); + + /* Fetches more data from the source, ensuring that at least the specified number of + bytes are available. This might stall. */ + void (*flush)(struct InputBuffer * input_buffer, unsigned bytes); + + /* Returns true if a flush with a byte size of 0 will succeed without stalling. + (I.e. if all pending I/O operations have finished.) */ + int (*can_flush_without_stalling)(struct InputBuffer * input_buffer); + + /* Reserved for expansion of the API. */ + void *reserved[32]; +}; + +/* ---------------------------------------------------------------------- + Logging +---------------------------------------------------------------------- */ + +/* + Interface to log messages to the editor console. +*/ +struct LoggingApi +{ + /* Logs an informational message */ + void (*info)(const char *system, const char *info); + + /* Logs a warning message. */ + void (*warning)(const char *system, const char *warning); + + /* Logs an error message. */ + void (*error)(const char *system, const char *error); +}; + +/* ---------------------------------------------------------------------- + RendererInterface +---------------------------------------------------------------------- */ + +/* Opaque struct representing the render device. On a D3D platform, this will be ID3D11Device. */ +struct RI_Device; + +/* Enum describing the different resource types used by the renderer. */ +enum RI_ResourceType { + RI_RESOURCE_TEXTURE, + RI_RESOURCE_RENDER_TARGET, + RI_RESOURCE_NOT_INITIALIZED = 0x00FFFFFF +}; + +/* Used to identify a render resource. */ +struct RenderResource { + unsigned handle; +}; + +#if defined(WINDOWSPC) || defined(XBOXONE) || defined(UWP) + /* D3D rendering interface. */ + struct ID3D11RenderTargetView; + struct ID3D11ShaderResourceView; + struct ID3D11Texture2D; + struct IDXGISwapChain; + + struct RI_PlatformTexture2d + { + struct ID3D11Texture2D *texture; + struct ID3D11ShaderResourceView *resource_view; + struct ID3D11ShaderResourceView *resource_view_srgb; + }; + + struct RI_PlatformRenderTarget + { + struct ID3D11RenderTargetView *render_target_view; + }; + + struct RI_PlatformSwapChain + { + struct IDXGISwapChain *dxgi_swap_chain; + }; + + struct RI_PlatformWindow + { + void *window; + }; +#else + /* TODO: Implement RI_PlatformRenderTarget for other platforms. */ + struct RI_PlatformRenderTarget { char unused; }; + + #if defined(ANDROID) + /* cf. gl::Context */ + struct RI_Device { + void* context; /* EGLContext */ + void* display; /* EGLDisplay */ + void* surface; /* EGLSurface */ + void* config; /* EGLConfig */ + }; + #endif + + #if defined(MACOSX) || defined(IOS) || defined(ANDROID) || defined(WEB) || defined(LINUXPC) + struct RI_PlatformTexture2d { + unsigned int handle; /* binding handle */ + unsigned int format; /* internal pixel format, e.g., GL_DEPTH24_STENCIL8, GL_R16F */ + unsigned int type; /* channel type info, e.g., GL_UNSIGNED_INT_24_8, GL_UNSIGNED_BYTE */ + unsigned int width; + unsigned int height; + unsigned int size; /* size in bytes used by the texture */ + }; + #else + /* TODO: Implement Texture2D for other platforms. */ + struct RI_PlatformTexture2d { char unused; }; + #endif + + /* TODO: Implement SwapChain and Window for other platforms. */ + struct RI_PlatformSwapChain { char unused; }; + struct RI_PlatformWindow { char unused; }; +#endif + +/* + Interface to the Stingray renderer. +*/ +struct RenderInterfaceApi +{ + /* Creates a fence for the GPU. */ + int (*create_fence)(); + + /* Wait for the GPU to reach the specified fence. */ + void (*wait_for_fence)(int); + + /* Run the specified callback function on the render thread. */ + void (*run_callback)(void(*callback)(void* data), void* user_data, uint32_t user_data_size); + + /* Returns the render device. */ + struct RI_Device* (*device)(); + + /* Returns the named global render resource. */ + struct RenderResource* (*global_render_resource)(const char *name); + + /* Returns a texture. */ + struct RI_PlatformTexture2d (*texture_2d)(struct RenderResource *render_resource); + + /* Returns the swap chain. */ + struct RI_PlatformSwapChain (*swap_chain)(unsigned handle); + + /* Returns the render target for the specified swap chain, layer and mip_level. */ + struct RI_PlatformRenderTarget (*render_target)(unsigned handle, int layer, int mip_level); + + /* Returns the window corresponding to the specified handle. */ + struct RI_PlatformWindow (*window)(unsigned handle); + + /* Sets render setting values that are applied to the render configuration */ + void (*set_render_setting)(const char* name, ConstConfigRootPtr value); + + /* Reserved for expansion of the API. */ + void *reserved[31]; +}; + +/* ---------------------------------------------------------------------- + Unit +---------------------------------------------------------------------- */ + +/* Enum for the different kinds of physics actors supported. */ +enum U_ActorType { + U_ACTOR_SPHERE = 0, + U_ACTOR_PLANE = 1, + U_ACTOR_CAPSULE = 2, + U_ACTOR_BOX = 3, + U_ACTOR_CONVEXMESH = 4, + U_ACTOR_TRIANGLEMESH = 5, + U_ACTOR_HEIGHTFIELD = 6 +}; + +/* Opaque struct representing a collision filter, that specifies which actors collide with which + other actors. */ +struct CollisionFilter; + +/* Represents a triangle mesh. */ +struct U_TriangleMesh +{ + const char *indices; + unsigned num_triangles; + unsigned index_stride; + const char *vertices; + unsigned vertex_stride; + float transform[16]; +}; + +/* Represents a convex mesh. */ +struct U_ConvexMesh +{ + const char *indices; + unsigned num_polygons; + unsigned index_stride; + const char *vertices; + unsigned vertex_stride; + float transform[16]; +}; + +/* Represents a height field. */ +struct U_HeightField +{ + unsigned num_rows; + unsigned num_columns; + float row_scale; + float column_scale; +}; + +/* Represents a sphere. */ +struct U_Sphere +{ + float transform[16]; + float radius; +}; + +/* Represents a capsule. */ +struct U_Capsule +{ + float transform[16]; + float radius; + float half_height; +}; + +/* Represents a box. */ +struct U_Box +{ + float transform[16]; + float half_extents[3]; +}; + +/* Represents a position in the height field. */ +struct U_HeightFieldPos +{ + float pos[3]; +}; + +/* Represents animation clip playback information */ +struct U_AnimationPlayingInfo +{ + uint64_t clip_resource_id; + double time; + double length; + uint8_t loop; +}; + +/* Opaque struct representing a hierarchy of objects in a Unit. */ +struct SceneGraph; + +/* + Interface for interacting with units. +*/ +struct UnitApi +{ + /* Returns the unit's scene graph. */ + struct SceneGraph * (*scene_graph)(CApiUnit *unit); + + /* Returns a reference to the unit. Unit references are weak pointers that get invalidated when + the unit dies. */ + CApiUnitRef (*reference)(CApiUnit * unitobject); + + /* Returns the number of meshes in the unit. */ + int (*num_meshes)(CApiUnit *unit); + + /* Returns the mesh at the specified index. */ + void (*mesh)(CApiUnit *unit, int mesh_index, struct U_TriangleMesh *mesh); + + /* Returns the hashed name of the mesh at the specified index. */ + uint32_t (*mesh_name)(CApiUnit *unit, int mesh_index); + + /* Returns the index of the scene graph node that owns the mesh at the specified index. */ + int (*mesh_node)(CApiUnit *unit, int mesh_index); + + /* True if the specified mesh is visible. */ + int (*is_mesh_visible)(CApiUnit *unit, int mesh_index); + + /* Returns the number of actors in the unit. */ + int (*num_actors)(CApiUnit *unit); + + /* Returns the actor at the specified index. */ + CApiActor* (*actor)(CApiUnit *unit, int index); + + /* True if collisions are enabled for the specified actor. */ + int (*is_collision_enabled)(CApiActor *ao); + + /* True if the specified actor is static. */ + int (*is_static)(CApiActor *ao); + + /* True if the specified actor is kinematic. */ + int (*is_kinematic)(CApiActor * ao); + + /* Returns the number of shapes in the actor. */ + int (*num_shapes)(CApiActor* ao); + + /* Returns the type of the shape at the specified index. */ + int (*shape_type)(CApiActor *ao, int shape_index); + + /* Gets shape data for a sphere shape. Returns false if shape is not a sphere. */ + int (*sphere)(CApiActor *ao, int shape_index, struct U_Sphere *so); + + /* Gets shape data for a capsule shape. Returns false if shape is not a capsule. */ + int (*capsule)(CApiActor *ao, int shape_index, struct U_Capsule *co); + + /* Gets shape data for a box shape. Returns false if shape is not a box. */ + int (*box)(CApiActor *ao, int shape_index, struct U_Box *bo); + + /* Gets shape data for a mesh shape. Returns false if shape is not a mesh. */ + int (*triangle_mesh)(CApiActor *ao, int shape_index, struct U_TriangleMesh *mesh); + + /* Gets shape data for a convex shape. Returns false if shape is not a convex. */ + int (*convex_mesh)(CApiActor *ao, int shape_index, struct U_ConvexMesh *convexmesh); + + /* Returns the number of vertices of the specified polygon in the convex shape. */ + int (*convex_mesh_polygon_num_vertices)(CApiActor *ao, int shape_index, int polygon_index); + + /* Returns the index at which the polygon's vertices start in the convex mesh's + vertex buffer. */ + int (*convex_mesh_polygon_base_index)(CApiActor *ao, int shape_index, int polygon_index); + + /* Gets shape data for a height field shape. Returns false if shape is not a height field. */ + int (*height_field)(CApiActor *ao, int shape_index, struct U_HeightField *height_field); + + /* Returns the height field position at the specified coordinates. */ + int (*height_field_position)(CApiActor *ao, int shape_index, float x, float y, struct U_HeightFieldPos *pos); + + /* Returns the unit's mover (character controller). */ + CApiMover* (*mover)(CApiUnit *unit); + + /* Returns the collision filter of the mover. */ + struct CollisionFilter* (*collision_filter)(CApiMover *mo); + + /* Returns the hash of the unit's resource name. */ + uint64_t (*unit_resource_name)(CApiUnit *unit); + + /* Gets the value of the unit animation curve for the specified object and parameter. + Returns true if the curve value was successfully fetched. */ + uint8_t (*get_curve_value)(CApiUnit *unit, uint32_t object, uint32_t parameter, unsigned count, float* floats); + + /* The world that the unit lives in. */ + CApiWorld* (*world)(CApiUnit *unit); + + /* Query number of playing animation clips and fill in playback details. */ + uint32_t (*get_playing_animation_infos)(CApiUnit *unit, uint32_t layer_id, struct U_AnimationPlayingInfo *playing_infos, uint32_t maximum); + + + /* Reserved for expansion of the API. */ + void *reserved[31]; +}; + +/* + Interface for working with unit references. Unit references are weak pointers that get + invalidated when the unit is destroyed. +*/ +struct UnitReferenceApi +{ + /* Dereferences the reference into a unit pointer. Returns NULL if the unit has been + destroyed. */ + CApiUnit * (*dereference)(CApiUnitRef ref); + + /* Reserved for expansion of the API. */ + void *reserved[32]; +}; + +/* ---------------------------------------------------------------------- + SceneGraph +---------------------------------------------------------------------- */ + +/* Opaque struct that represents the "dirty" state of nodes in a unit's scene graph. I.e. a bit + flag for each node that is dirty and needs its transform updated. */ +struct SceneFlags; + +/* + Interface for manipulating scene graphs (i.e., node hierarchies inside units). +*/ +struct SceneGraphApi +{ + /* Returns the world matrix of the node in the scene graph with specified index. The matrix + is returned as an array of 16 floats. */ + const float * (*world)(struct SceneGraph * scene_graph, int index); + + /* Returns the local transform of the node with the specified index. */ + const CApiLocalTransform * (*local)(struct SceneGraph *scene_graph, int index); + + /* Returns the scene graph's render handle to be used with the RenderSceneGraphApi. */ + uint32_t (*render_handle)(struct SceneGraph *scene_graph); + + /* Transforms the scene graph using the specified node as root. This updates the world + transforms of all objects based on their parent's transform and their local transforms. */ + void (*transform_with_root)(struct SceneGraph *scene_graph, int index, ConstMatrix4x4Ptr root); + + /* Unlinks the node at the index from its current parent. */ + void (*unlink_internal)(struct SceneGraph *scene_graph, int index); + + /* Relinks a node back to its parent. */ + void (*relink_internal)(struct SceneGraph *scene_graph, int index); + + /* Returns the total number of nodes in the scene graph. */ + uint32_t (*num_nodes)(struct SceneGraph *scene_graph); + + /* Returns the index of the parent node to the node at the specified index. If the node + doesn't have a parent, this function returns -1. */ + int (*parent)(struct SceneGraph *scene_graph, int index); + + /* Returns true if the node with the specified index is a root (i.e., does not have a parent + node). */ + uint8_t (*is_root)(struct SceneGraph * scene_graph, int index); + + /* Returns the 32 bit hash of the node's name. */ + uint32_t (*name)(struct SceneGraph *scene_graph, int index); + + /* Returns a pointer to an array with the hashes of all the node names in the scene graph. */ + uint32_t * (*names_array_pointer)(struct SceneGraph *scene_graph); + + /* Returns the array of dirty flags. This is a bit array with the bit set for each node that + has a local transform change that has not yet been reflected to its world transform. This + array can be(useful when defining a post animation callback that changes local node transforms. */ + struct SceneFlags * (*dirty_array_pointer)(struct SceneGraph *scene_graph); + + /* Reserved for expansion of the API. */ + void *reserved[32]; +}; + +/* ---------------------------------------------------------------------- + Application +---------------------------------------------------------------------- */ + +/* Opaque struct that represents the command-line options that were passed to the application at + launch. */ +struct ApplicationOptions; + +/* Abstract struct that can be cast to either ANativeActivity or UIApplication based on the + platform. */ +struct AP_PlatformActivity; + +/* Specifies whether callbacks should be called before the activity happens or after it happens. */ +enum AP_PlatformCallbackOrder +{ + AP_PRE_ACTIVITY, + AP_POST_ACTIVITY +}; + +/* Callbacks for Android activity events. See Android documentation. */ +struct AndroidActivityCallbacks +{ + void (*start)(struct AP_PlatformActivity*); + void (*resume)(struct AP_PlatformActivity*); + void * (*save_instance_state)(struct AP_PlatformActivity*, size_t*); + void (*pause)(struct AP_PlatformActivity*); + void (*stop)(struct AP_PlatformActivity*); + void (*destroy)(struct AP_PlatformActivity*); + void (*window_focus_changed)(struct AP_PlatformActivity*, int); + void (*native_window_created)(struct AP_PlatformActivity*, void*); + void (*native_window_resized)(struct AP_PlatformActivity*, void*); + void (*native_window_redraw_needed)(struct AP_PlatformActivity*, void*); + void (*native_window_destroyed)(struct AP_PlatformActivity*, void*); + void (*input_queue_created)(struct AP_PlatformActivity*, void*); + void (*input_queue_destroyed)(struct AP_PlatformActivity*, void*); + void (*content_rect_changed)(struct AP_PlatformActivity*, const void*); + void (*configuration_changed)(struct AP_PlatformActivity*); + void (*low_memory)(struct AP_PlatformActivity*); +}; + +/* Callbacks for iOS activity events. See iOS documentation. */ +struct IOSActivityCallbacks +{ + void (*did_finish_launching)(struct AP_PlatformActivity*); + void (*will_enter_foreground)(struct AP_PlatformActivity*); + void (*will_terminate)(struct AP_PlatformActivity*); + void (*did_receive_memory_warning)(struct AP_PlatformActivity*); + void (*will_resign_active)(struct AP_PlatformActivity*); + void (*did_enter_background)(struct AP_PlatformActivity*); + void (*did_become_active)(struct AP_PlatformActivity*); +}; + +/* Abstract struct representing platform activity callbacks that should be either an + AndroidActivityCallbacks or an IOSActivityCallbacks. */ +struct PlatformActivityCallbacks; + +/* Function type for receiving console commands. client_id is the ID of the console client + instigating the command. ConstConfigRootPtr is a ConstConfig representation of the console + command's JSON data. data and data_length is any binary data that was sent with the command. */ +typedef void (*AP_ReceiverFunction)(void *user_data, int client_id, ConstConfigRootPtr dv, + const char *data, uint32_t data_length); + +/* Wraps a console command receiver callback with a user_data value that will be passed to the + callback. */ +struct AP_ReceiverUserDataWrapper +{ + void * user_data; + AP_ReceiverFunction function; +}; + +/* + Interface for manipulating the application. +*/ +struct ApplicationApi +{ + /* Returns the command-line options that were passed to the application at launch. */ + const struct ApplicationOptions * (*options)(); + + /* Returns a representation of the settings.ini file used with the application. The settings + are returned as a pointer to a ConstConfigRoot item and can be parsed using the ConstConfig + API in the plugin foundation. */ + const void * (*settings)(); + + /* Returns the activity interface for native lifecycle handling. */ + struct AP_PlatformActivity * (*platform_activity)(); + + /* Register platform activity callbacks to be called on platform activity events. */ + void (*register_platform_callbacks)(enum AP_PlatformCallbackOrder, + const struct PlatformActivityCallbacks*); + + /* Unregisters callbacks registered with register_platform_callbacks(). */ + void (*unregister_platform_callbacks)(enum AP_PlatformCallbackOrder, + const struct PlatformActivityCallbacks*); + + /* Returns the number of worlds managed by the application. */ + int (*num_worlds)(); + + /* Returns the world at the specified index. */ + CApiWorld * (*world)(int index); + + /* Returns a string identifying the Stingray version. */ + const char * (*product_version)(); + + /* Hooks a receiver function for console connection commands. This allows you to extend the + console interface with your own commands. */ + void (*hook_console_receiver)(const char *type, struct AP_ReceiverUserDataWrapper *user_wrapper); + + /* Unhooks a receiver hooked with hook_console_receiver(). */ + void (*unhook_console_receiver)(const char *type); + + /* Can be used in console receivers to get the id of the console connection that originated + the command. */ + int (*current_client_id)(); + + /* Returns the holographic space created early in the app lifecycle when on the Hololens platform. + Null otherwise. TODO: Adding a plugin hook early enough in the app lifecycle (pre-window activation) + would alleviate the need for this API member. */ + void * (*holographic_space)(); + + /* Sends data over a console connection. The data sent can be a combination of textual data + (JSON) and a binary payload. If sync is true, the send is synchronized. If client_id is + not -1, then the message is only sent to that particular console client instead of + broadcast to everybody. */ + void (*console_send_with_binary_data)(const char *text, uint32_t text_len, const char *data, + uint32_t data_len, uint8_t sync, int client_id); + + /* Reserved for expansion of the API. */ + void *reserved[32]; +}; + +/* ---------------------------------------------------------------------- + ApplicationOptions +---------------------------------------------------------------------- */ + +/* + Interface to read the command options used when launching the application. +*/ +struct ApplicationOptionsApi +{ + /* Returns the bundle directory if the engine was launched in bundle mode. */ + const char * (*bundle_directory)(const struct ApplicationOptions * application_options); + + /* Returns the data directory if the engine was launched in data directory mode. */ + const char * (*data_directory)(const struct ApplicationOptions * application_options); + + /* Returns true if rendering is enabled. */ + int (*is_rendering_enabled)(const struct ApplicationOptions * application_options); + + /* Reserved for expansion of the API. */ + void *reserved[31]; +}; + +/* ---------------------------------------------------------------------- + ErrorContext +---------------------------------------------------------------------- */ + +/* + Allows plugins to use the error context functionality on custom threads created by + the plugin. +*/ +struct ErrorContextApi +{ + /* Creates a thread error context stack for the current thread. */ + void (*make_thread_error_context_stack)(struct AllocatorObject *allocator); + + /* Deletes the thread error context stack for the current thread. */ + void (*delete_thread_error_context_stack)(struct AllocatorObject *allocator); + + /* Returns true if the current thread has en error context stack and false otherwise. */ + int (*has_thread_error_context_stack)(); + + /* Reserved for expansion of the API. */ + void *reserved[32]; +}; + +/* ---------------------------------------------------------------------- + Raycast +---------------------------------------------------------------------- */ + +/* + Interface for performing raycasts. +*/ +struct RaycastApi +{ + /* Casts a ray into the world, from the origin in the specified direction. Only actors matching + the collision filter are considered. If a hit is found, the function returns true and sets + the hit position and normal in the out parameters. */ + int (*find_first_collision)( + CApiWorld *world, + float ray_origin_x, float ray_origin_y, float ray_origin_z, + float ray_direction_x, float ray_direction_y, float ray_direction_z, + float ray_length, + struct CollisionFilter *collision_filter, + float *hit_position_x, float *hit_position_y, float *hit_position_z, + float *hit_normal_x, float *hit_normal_y, float *hit_normal_z); + + /* Reserved for expansion of the API. */ + void *reserved[32]; +}; + +/* ---------------------------------------------------------------------- + FileSystem +---------------------------------------------------------------------- */ + +/* Opaque struct representing a file system. */ +struct FileSystem; + +/* + Interface for accessing a file system. +*/ +struct FileSystemApi +{ + /* Returns true if a file with the specified name exists in the file system. */ + int (*exists)(struct FileSystem *filesystem, const char *filename); + + /* Creates a new disk file system with the specified directory as its root. You can use + the empty string for the directory if you want a file system that represents the entire + disk. */ + struct FileSystem * (*create)(const char *directory); + + /* Destroys a file syste created by create(). */ + void (*destroy)(struct FileSystem *filesystem); + + /* Returns true if the specified path is a directory, false if it isn't or if there + was an error. If there was an error, the error message is returned in the error + parameter. */ + int (*is_directory)(struct FileSystem *filesystem, const char *file, const char **error); + + /* Creates a directory at the specified path. Returns NULL if successful and an + error message otherwise. */ + const char * (*make_directory)(struct FileSystem *filesystem, const char *file); + + /* Reads file, parses it into ConstConfig */ + ConstConfigRootPtr (*parse_sjson)(struct FileSystem *filesystem, const char *file, struct AllocatorObject *allocator, const char **error); + + /* Reserved for expansion of the API. */ + void *reserved[31]; +}; + +/* ---------------------------------------------------------------------- + PluginManager +---------------------------------------------------------------------- */ + +/* + Interface for manipulating the plugin system. +*/ +struct PluginManagerApi +{ + /* On-demand loads the plugin at the specified path. */ + void (*load_relative_plugin)(const char *plugin_relative_path); + + /* Used to enumerate services exposed by plugins. Call it with an API ID and NULL to retrieve + a pointer to the first interface that implements a certain API. Repeat the call with the + previously returned pointer to continue enumerating implementations. The function will + return NULL when all interfaces have been enumerated. + + Note that this function will only enumerate services implemented in plugins, not the ones + implemented in the engine. */ + void *(*get_next_plugin_api)(unsigned api_id, void *prev_api); + + /* Reserved for expansion of the API. */ + void *reserved[32]; +}; + +/* ---------------------------------------------------------------------- + World +---------------------------------------------------------------------- */ + +/* Opaque struct representing a scope for drawing lines. */ +struct LineObjectDrawer; + +/* Callback to be called after animations have been evaluated. */ +typedef void (*PostAnimationCallback)(CApiWorld * world_object, float dt); + +/* + Interface for accessing the world. +*/ +struct WorldApi +{ + /* Returns a LineObjectDrawer that can be used to draw debug lines into the world. */ + struct LineObjectDrawer * (*line_object_drawer)(CApiWorld * world); + + /* Registers a callback that will run after animations (forward kinematics) have been run. + This can be used to implement IK and other animation controllers. */ + void (*register_post_animation_callback)(CApiWorld * world, PostAnimationCallback function); + + /* Unregisters a callback registered with register_post_animation_callback(). */ + void (*unregister_post_animation_callback)(CApiWorld * world, PostAnimationCallback function); + + /* Finds all the instances of the named unit resource in the level. The unit resource is + identified by a 64 bit hash. + + The function returns the total number of units of the specified type found in the level + and the first units_size of these are copied into the array. */ + unsigned (*find_units_by_resource_name)(CApiWorld *world, uint64_t resource_name, + CApiUnit **units, unsigned units_size); + + /* Reserved for expansion of the API. */ + void *reserved[32]; +}; + +/* ---------------------------------------------------------------------- + LineObjectDrawer +---------------------------------------------------------------------- */ + +/* Opaque struct that represents a collection of drawn lines. */ +struct LineObject; + +/* + Interface for drawing debug lines. +*/ +struct LineObjectDrawerApi +{ + /* Creates a new line object for drawing a number of lines. */ + struct LineObject *(*new_line_object)(struct LineObjectDrawer * drawer); + + /* Frees a line object created by new_line_object(). */ + void (*release_line_object)(struct LineObjectDrawer * drawer, struct LineObject *lo); + + /* Dispatches the lines drawn into the specified line object to the renderer for rendering. */ + void (*dispatch)(struct LineObjectDrawer * drawer, struct StateReflectionStream *srs, + struct LineObject *lo); + + /* Clears the lines from the line object. */ + void (*reset)(struct LineObject * lo); + + /* Adds a number of lines to the line objects. The colors array encodes the color of each line + as an ARGB unsigned. The line_starts and line_ends array encode interleaved x, y, z coordinates + for the start points and end points of each line respectively. n is the total number of lines + added. */ + void (*add_lines)(struct LineObject * lo, unsigned * colors, float * line_starts, float * line_ends, unsigned n); + + /* Reserved for expansion of the API. */ + void *reserved[32]; +}; + +/* ---------------------------------------------------------------------- + Profiler +---------------------------------------------------------------------- */ + +/* + Interface to the Stingray profiler. +*/ +struct ProfilerApi +{ + /* Starts a new profiler scope with the specified name. Each call to profile_start() should + be matched by a corresponding call to profile_stop(). */ + void (*profile_start)(const char *name); + + /* Ends a profile scope started by profile_start(). */ + void (*profile_stop)(); + + /* Function for creating a profiler for a specific thread. + Must be called on the thread that the profiler should be created for. */ + void (*make_thread_profiler)(struct AllocatorObject *allocator); + + /* Function for deleting a profiler for a specific thread. + Must be called on the thread that the profiler should be deleted for. */ + void (*delete_thread_profiler)(struct AllocatorObject *allocator); + + /* Checks if the current thread already has a thread profiler. */ + int (*has_thread_profiler)(); + + /* Reserved for expansion of the API. */ + void *reserved[29]; +}; + +/* ---------------------------------------------------------------------- + Error +---------------------------------------------------------------------- */ + +/* + Interface for reporting errors. +*/ +struct ErrorApi +{ + /* printf() function for generating error messages. The messages will be generated into a ring + buffer that eventually gets recycled. */ + const char *(*eprintf)(const char *msg, ...); + + /* Reports a crash with the specified error message. */ + void (*report_crash)(const char *msg); + + /* Reports an assert() failure at the specified line and file. */ + void (*report_assert_failure)(int line, const char *file, const char *assert_test, const char *msg); + + /* Reserved for expansion of the API. */ + void *reserved[32]; +}; + +/* ---------------------------------------------------------------------- + RenderBuffer +---------------------------------------------------------------------- */ + +/* Enum for all the texture compression formats supported by the engine. This gets encoded into the + buffer_format (uint32_t) when the user creates a format using + RenderBufferApi::compressed_format(). */ +typedef enum +{ + /* https://en.wikipedia.org/wiki/S3_Texture_Compression */ + RB_BLOCK_COMPRESSED_1 = 0x0, /* BC1 */ + RB_BLOCK_COMPRESSED_2, /* BC2 */ + RB_BLOCK_COMPRESSED_3, /* BC3 */ + RB_BLOCK_COMPRESSED_4, /* BC4 */ + RB_BLOCK_COMPRESSED_5, /* BC5 */ + RB_BLOCK_COMPRESSED_6, /* BC6 */ + RB_BLOCK_COMPRESSED_7, /* BC7 */ + /* https://en.wikipedia.org/wiki/PVRTC */ + RB_PVR_RGB_2BPP = 0x100, /* PVR RGB 2BPP */ + RB_PVR_RGBA_2BPP, /* PVR RGBA 2BPP */ + RB_PVR_RGB_4BPP, /* PVR RGB 4BPP */ + RB_PVR_RGBA_4BPP, /* PVR RGBA 4BPP */ + /* https://en.wikipedia.org/wiki/Ericsson_Texture_Compression */ + RB_ETC2_RGB8 = 0x200, /* ETC2 RGB8 */ + RB_ETC2_RGB8A1, /* ETC2 RGB8A1 */ + RB_ETC2_RGBA8, /* ETC2 RGBA8 */ + RB_ETC2_R11, /* ETC2 R11 */ + RB_ETC2_RG11 /* ETC2 RG11 */ +} RB_CompressedFormat; + +/* Buffer component type. */ +typedef enum +{ + RB_FLOAT_COMPONENT = 0, + RB_INTEGER_COMPONENT = 1 +} RB_ComponentType; + +/* RenderBuffer Descriptors ---------------------------------------------*/ + +/* Vertex channel semantic names. */ +typedef enum +{ + RB_POSITION_SEMANTIC, + RB_NORMAL_SEMANTIC, + RB_TANGENT_SEMANTIC, + RB_BINORMAL_SEMANTIC, + RB_TEXCOORD_SEMANTIC, + RB_COLOR_SEMANTIC, + RB_BLEND_INDICES_SEMANTIC, + RB_BLEND_WEIGHTS_SEMANTIC, + RB_UNKNOWN_SEMANTIC, + RB_SEMANTIC_COUNT = RB_UNKNOWN_SEMANTIC +} RB_VertexSemantic; + +/* Describes a vertex channel inside a vertex buffe.r */ +struct RB_VertexChannel +{ + uint32_t format; /* Created using RenderBufferApi::format(). */ + uint8_t semantic; /* Semantic name from RB_VertexSemantic. */ + uint8_t vb_index; /* Vertex buffer index. */ + uint8_t set; /* Semantic set (TEXCOORD0, TEXCOORD1, etc..). */ + uint8_t instance; /* true if vertex channel contains per instance data. */ +}; + +/* Describes a vertex format as a collection of vertex channels. */ +struct RB_VertexDescription +{ + struct RB_VertexChannel channels[16]; + uint32_t n_channels; +}; + +typedef enum +{ + RB_VERTEX_DESCRIPTION /* View of RB_VertexDescription. */ +} RB_Description; + +/* RenderBuffer Views -----------------------------------------*/ + +struct RB_VertexBufferView +{ + uint32_t stride; /* Per vertex stride in bytes. */ + uint32_t reserved[7]; /* Reserved for future use - must be zero. */ +}; + +struct RB_IndexBufferView +{ + uint32_t stride; /* Per index stride in bytes (must be 2 or 4). */ + uint32_t reserved[7]; /* Reserved for future use - must be zero. */ +}; + +struct RB_RawBufferView +{ + uint32_t format; /* Format descriptor. */ + uint32_t reserved[7]; /* Reserved for future use - Must be zero. */ +}; + +/* Enum for the supported texture types. */ +typedef enum +{ + RB_TEXTURE_TYPE_2D = 0, + RB_TEXTURE_TYPE_CUBE = 1, + RB_TEXTURE_TYPE_3D = 2 +} RB_TextureBufferType; + +/* View into a texture buffer. */ +struct RB_TextureBufferView +{ + uint32_t format; /* Format of texture buffer. */ + uint32_t type; /* Type of texture, should be any of the available types in RB_TextureBufferType. */ + uint32_t width; /* Width of texture. */ + uint32_t height; /* Height of texture. */ + uint32_t depth; /* Depth of texture (Only used if type == RB_TEXTURE_TYPE_3D). */ + uint32_t slices; /* Number of slices (1 for regular textures, >1 for texture arrays). */ + uint32_t mip_levels; /* Number of mip levels in buffer. */ + uint32_t reserved[7]; /* Reserved for future use - must be zero. */ +}; + +/* Enum enumerating view types. */ +typedef enum +{ + RB_VERTEX_BUFFER_VIEW, /* View of RB_VertexBufferView */ + RB_INDEX_BUFFER_VIEW, /* View of RB_IndexBufferView */ + RB_RAW_BUFFER_VIEW, /* View of RB_RawBufferView */ + RB_TEXTURE_BUFFER_VIEW /* View of RB_TextureBufferView */ +} RB_View; + +/* RenderBuffer API----------------------------------------------*/ + +/* Represents updatability of a buffer. */ +typedef enum +{ + /* The buffer is immutable. The content of the buffer must be passed in create_buffer() and + cannot change after that. */ + RB_VALIDITY_STATIC, + + /* The content of the buffer can be updated with update_buffer(). */ + RB_VALIDITY_UPDATABLE +} RB_Validity; + +struct RenderBufferApi +{ + /* Creates a format descriptor describing a piece of data in a buffer. + type = RB_FLOAT_COMPONENT or RB_INTEGER_COMPONENT + signed_bool = true if component should be treated as signed + normalize_bool = true if component should be as a normalized value when read in a shader + bit_depth_ = number of bits per x,y,z,w component + */ + uint32_t (*format)(RB_ComponentType type, uint8_t signed_bool, uint8_t normalize_bool, uint8_t bit_depth_x, uint8_t bit_depth_y, uint8_t bit_depth_z, uint8_t bit_depth_w); + + /* Creates a format descriptor describing a compressed buffer. */ + uint32_t (*compressed_format)(RB_CompressedFormat compression); + + /* Returns true if format is a compressed format. */ + uint8_t (*is_compressed)(uint32_t format); + + /* Returns total number of bits used by the format.*/ + uint32_t (*num_bits)(uint32_t format); + + /* Returns the number of components in the format. */ + uint32_t (*num_components)(uint32_t format); + + /* Returns the component type for the format */ + RB_ComponentType (*component_type)(uint32_t format); + + /* Creates a descriptor object of the specified type and returns a handle to it. + desc should be an appropriate RB_*Description object. */ + uint32_t (*create_description)(RB_Description view, const void *desc); + + /* Updates the specified descriptor object. */ + void (*update_description)(uint32_t handle, const void *desc); + + /* Destroys a descriptor object created by create_description(). */ + void (*destroy_description)(uint32_t handle); + + /* Creates a buffer with the specified parameters and returns a handle to it. + view_data should be an appropriate RB_*View object and data should be the raw buffer data. */ + uint32_t (*create_buffer)(uint32_t size, RB_Validity validity, RB_View view, const void *view_data, const void *data); + + /* Updates the buffer with the specified content. */ + void (*update_buffer)(uint32_t handle, uint32_t size, const void *data); + + /* Destroys a buffer created by create_buffer(). */ + void (*destroy_buffer)(uint32_t handle); + + /* Translates a handle to a RenderResource that can be piped to MeshObjectApi::add_resource(), + remove_resource() as well as the Lua interface Material.set_resource(). */ + struct RenderResource* (*lookup_resource)(uint32_t handle); + + /* Overrides a resource with another resource. */ + void (*resource_override)(struct RenderResource *resource_to_override, struct RenderResource *resource); + + /* Releases the override done to the resource.*/ + void (*release_resource_override)(struct RenderResource *overriden_resource); + + /* Partial update of a buffer, offset and size in bytes. Partial updates are not allowed to grow a buffer, use update_buffer if you need to resize the buffer. */ + void(*partial_update_buffer)(uint32_t handle, uint32_t offset, uint32_t size, const void *data); + + /* Partial update of a texture buffer, offset[] and size[] are in pixels. Partial updates are not allowed to grow a buffer, use update_buffer if you need to resize the buffer. */ + /* array_index, slice_index and mip_index describes which surface of the image to update. for now array_index must always be 0. */ + /* Valid ranges for slice_index and mip_index depends on RB_TextureBufferView used when creating the texture. */ + void(*partial_update_texture)(uint32_t handle, uint32_t array_index, uint32_t slice_index, uint32_t mip_index, uint32_t offset[3], uint32_t size[3], const void *data); + + /* Updates the specified descriptor object. */ + void(*update_description_from_resource)(struct RenderResource *resource, const void *desc); + + /* Updates the buffer with the specified content. */ + void(*update_buffer_from_resource)(struct RenderResource *resource, uint32_t size, const void *data); + + /* Reserved for expansion of the API. */ + void *reserved[26]; +}; + +/* ---------------------------------------------------------------------- + MeshObject +---------------------------------------------------------------------- */ + +/* Describes the primitive type for a render batch. */ +typedef enum { MO_TRIANGLE_LIST, MO_LINE_LIST } MO_PrimitiveType; + +/* Describes a render batch in a mesh. */ +struct MO_BatchInfo +{ + MO_PrimitiveType primitive_type; /* Primitive type.e */ + uint32_t material_index; /* Index into material array set by MeshObjectApi::set_materials() function. */ + uint32_t vertex_offset; /* Offset to first vertex to read from vertex buffer. (If set when indexed this value is added to the index fetched from the index buffer before fetching the vertex.) */ + uint32_t primitives; /* Number of primitives to draw. */ + uint32_t index_offset; /* Offset to the first index to read from the index buffer (only valid when batch is indexed). */ + uint32_t vertices; /* Number of vertices in batch (only valid if batch is non indexed). */ + uint32_t instances; /* Number of instances of this batch to draw (1 equals no instancing). */ +}; + +/* Describes a piece of mesh geometry for rendering. */ +struct MO_Geometry +{ + void *vertices[8]; /* Holds 0-8 different vertex buffers, contents described by vertex_channels[]. If mesh references more than 8 vertex buffers MeshObjectApi will generate an error. */ + uint32_t vertex_stride[8]; /* Holds 0-8 strides, one for each buffer in vertices[]. */ + uint32_t num_vertices; /* Total number of vertices. */ + struct RB_VertexDescription vertex_description;/* Vertex description. */ + + void *indices; /* Pointer to index list. */ + uint32_t index_stride; /* Stride of index list (2 or 4). */ + uint32_t num_indices; /* Total number of indices. */ +}; + +/* Describes a piece of mesh geometry for rendering. */ +struct MO_MeshGeometry +{ + struct RenderResource *vertex_stream; + struct RenderResource *vertex_description; + struct RenderResource *index_stream; +}; + +/* Culling flags for meshes. */ +typedef enum +{ + MO_VIEWPORT_VISIBLE_FLAG = 0x1, /* Mesh is part of regular rendering */ + MO_SHADOW_CASTER_FLAG = 0x2, /* Mesh is part of shadow rendering */ + MO_DISABLE_CULLING_FLAG = 0x4 /* Mesh always passes culling, i.e its bounding volume state is ignored. Note: might significantly impact performance */ +} MO_Flags; + +/* A context in which the mesh is either visible or not. */ +typedef enum +{ + MO_VIEWPORT_CONTEXT, /* Visibility context for regular rendering */ + MO_SHADOW_CASTER_CONTEXT, /* Visibility context for shadow casting */ + MO_ALL_CONTEXTS /* Visibility context for both regular rendering and shadow casting */ +} MO_VisibilityContexts; + +struct MeshObjectApi +{ + /* Tries to retrieve the geometry of an existing mesh and if successful returns it in + MO_Geometry (this will only give valid results when a representation of the geometry exist + on the CPU side). */ + uint8_t (*read_geometry)(CApiUnit *unit, uint32_t mesh_name, struct MO_Geometry *geometry); + + /* Creates a new mesh object linked to the node referenced by node_name within the Unit + referenced by unit. The mesh_name is given to the new MeshObject and can be used to + retrieve the object from the Unit interface. flags is a combination of MO_Flags */ + uint32_t (*create)(CApiUnit *unit, uint32_t node_name, uint32_t mesh_name, uint32_t flags); + + /* Lookup an existing mesh object by name */ + uint32_t (*lookup)(CApiUnit *unit, uint32_t mesh_name); + + /* Destroy a mesh object created using create() or lookup(), for meshes looked up using + lookup() this just releases the plugin handle. */ + void (*destroy)(uint32_t handle); + + /* Assigns an array of materials to the mesh. material_resources is an array of material + resources retrieved using ResourceManagerApi::get() */ + void (*set_materials)(uint32_t handle, uint32_t num_materials, void **material_resources); + + /* Returns the number of materials assigned to the mesh */ + uint32_t (*num_materials)(uint32_t handle); + + /* Returns a pointer to the material instance at the specified index. */ + void * (*material)(uint32_t handle, uint32_t material_index); + + /* Sets batch/drawcall information of the mesh */ + void (*set_batch_info)(uint32_t handle, uint32_t num_infos, struct MO_BatchInfo *batch_infos); + + /* Adds resources such as vertex buffers, index buffers and vertex declarations created through + the RenderBufferApi or piped down from Lua. */ + void (*add_resource)(uint32_t handle, struct RenderResource *r); + + /* Removes a resource added with add_resource(). */ + void (*remove_resource)(uint32_t handle, struct RenderResource *r); + + /* Clears any already assigned resources from a mesh */ + void (*clear_resources)(uint32_t handle); + + /* Sets min & max bounds in mesh local coordinates to be used for culling. */ + void (*set_bounding_box)(uint32_t handle, float min[3], float max[3]); + + /* Sets visibility of the mesh for a specific MO_VisibilityContext */ + void (*set_visibility)(uint32_t handle, uint32_t visibility_context, uint8_t visibility_bool); + + /* Returns the visibility of the mesh in the specified context. */ + uint8_t (*visibility)(uint32_t handle, uint32_t visibility_context); + + /* Sets the culling MO_Flags for object (will overrride the flags passed in create()). */ + void (*set_flags)(uint32_t handle, uint32_t flags); + + /* Returns the culling flags of the object. */ + uint32_t (*flags)(uint32_t handle); + + /* Creates a new empty mesh object. A scene graph must be associated to it and it must be dispatched + to the render thread through a render interface before use with the mesh api. (this is currently + used for the mesh component api) */ + uint32_t (*create_mesh)(WorldPtr world, uint32_t mesh_name, uint32_t flags); + + /* Lookup an existing mesh object by its handle */ + MeshPtr(*lookup_mesh)(uint32_t handle); + + /* Tries to retrieve the mesh geometry of an existing mesh and if successful returns it in + MO_MeshGeometry. */ + uint8_t (*read_mesh_geometry)(void *unit_resource, uint32_t mesh_name, struct MO_MeshGeometry *geometry); + + /* Reserved for expansion of the API. */ + void *reserved[29]; +}; + +/* ---------------------------------------------------------------------- + SoundStreamSourceApi +---------------------------------------------------------------------- */ + +#pragma pack(push, 1) + +/* Represents the format for sound data. */ +struct WaveFormat +{ + unsigned short format_tag; /* Tag specifying the format (e.g. WAVE_FORMAT_PCM). */ + unsigned short num_channels; /* Number of sound channels (e.g. 2). */ + unsigned samples_per_second; /* Samples per second (e.g. 44100). */ + unsigned average_bytes_per_second; /* Not used. */ + unsigned short block_align; /* For MP3 files, samples per frame. */ + unsigned short bits_per_sample; /* Bits per sample (e.g. 16). */ + unsigned short size; /* Number of extra bytes of header data. */ +}; + +#pragma pack(pop) + +/* Sound debug information. */ +struct SoundData +{ + unsigned id; /* IdString32 equivalent */ + char debug_name[32]; +}; + +/* Header for a piece of sound data. */ +struct SoundHeader +{ + unsigned offset; /* Offset of sample data in the file */ + unsigned size; /* Size of sample data */ + unsigned num_samples; /* Total number of samples (when unpacked) */ + struct SoundData sound_data; /* Debug information */ +}; + +/* Opaque struct representing a compiled piece of sound. */ +struct SoundResource; + +/* The result of streaming sound data. Contains the next chunk of streamed data. The + is_finished flag is set to true if this is the last chunk of sound data in the stream. */ +struct GetNextChunkResult +{ + struct SoundResource * data; + int is_finished; +}; + +/* Opaque struct representing a sound source for streaming sounds. */ +struct SoundStreamSource; + +/* + Interface for streaming sounds. +*/ +struct SoundStreamSourceApi +{ + /* Get the next chunk of streaming data from the stream source. */ + struct GetNextChunkResult (*get_next_chunk)(struct SoundStreamSource * ss); + + /* Gets the sound resource for the stream source. */ + struct SoundResource * (*get_resource)(struct SoundStreamSource * ss); + + /* Gets the sound header for the specified sound resource. */ + struct SoundHeader (*resource_header)(struct SoundResource * sr); + + /* Gets the sound format for the specified sound resource. */ + struct WaveFormat (*resource_format)(struct SoundResource * sr); +}; + +/* ---------------------------------------------------------------------- + MaterialApi +---------------------------------------------------------------------- */ + +/* + Interface for manipulating materials. +*/ +struct MaterialApi +{ + /* Sets a number of resources to be used by the material. The resources are identified + by their hashed names. */ + void (*set_resources)(void *material, uint32_t num_resources, const uint32_t *resource_names, + const struct RenderResource **resources); + + /* Sets a number of constants for the material. */ + void (*set_constants)(void *material, uint32_t num_constants, const uint32_t *constant_names, + const uint32_t *strides, const uint32_t *sizes, const void **constants); + + /* Reserved for expansion of the API. */ + void *reserved[32]; +}; + +/* ---------------------------------------------------------------------- + RenderSceneGraphApi +---------------------------------------------------------------------- */ + +/* + Interface for accessing the render thread copy of the scene graph. These functions should + only be called on the render thread. +*/ +struct RenderSceneGraphApi +{ + /* Returns the world matrix of the specified scene graph node. */ + ConstMatrix4x4Ptr (*world)(uint32_t render_handle, CApiWorld *world, unsigned index); + + /* Sets the world matrix of the specified scene graph node. */ + void (*set_world)(uint32_t render_handle, CApiWorld *world, unsigned index, ConstMatrix4x4Ptr m); + + /* Sets the world matrix of the specified scene graph node and transform its children + accordingly */ + void (*transform_hierarchy)(uint32_t render_handle, CApiWorld *world, const struct SceneGraph *graph, unsigned index, ConstMatrix4x4Ptr m); + + /* Reserved for expansion of the API. */ + void *reserved[32]; +}; + +/* ---------------------------------------------------------------------- + ThreadApi +---------------------------------------------------------------------- */ + +/* Defines for thread priorities. */ +#define PLUGIN_THREAD_PRIORITY_IDLE -15 +#define PLUGIN_THREAD_PRIORITY_LOWEST -2 +#define PLUGIN_THREAD_PRIORITY_BELOW_NORMAL -1 +#define PLUGIN_THREAD_PRIORITY_NORMAL 0 +#define PLUGIN_THREAD_PRIORITY_ABOVE_NORMAL 1 +#define PLUGIN_THREAD_PRIORITY_HIGHEST 2 +#define PLUGIN_THREAD_PRIORITY_TIME_CRITICAL 15 + +/* ID for identifying a particular thread. */ +typedef void* ThreadID; + +/* Thread entry point callback function. */ +typedef void (*ThreadEntry)(void* user_data); + +/* Opaque struct representing an event. */ +struct ThreadEvent; + +/* Opaque struct representing a critical section. */ +struct ThreadCriticalSection; + +/* + Interface for accessing threading functionality. +*/ +struct ThreadApi +{ + /* Creates a new thread and returns its ID. The user_data is passed to the thread entry point. */ + ThreadID (*create_thread)(const char *thread_name, ThreadEntry entry, void *user_data, int priority); + + /* Returns true if the thread is alive. */ + int (*is_thread_alive)(ThreadID thread_id); + + /* Returns the name of the specified thread. */ + const char* (*thread_name)(ThreadID thread_id); + + /* Waits until the thread has finished. */ + void (*wait_for_thread)(ThreadID thread_id); + + /* Creates an event for thread signaling. If manual_reset is false, the event will be + auto-reset after being triggered. initial_state specifies the initial state of the + event (set or not). */ + struct ThreadEvent* (*create_event)(struct AllocatorObject *allocator, int manual_reset, int initial_state, const char *debug_name); + + /* Destroys an event created by create_event(). */ + void (*destroy_event)(struct ThreadEvent* evt, struct AllocatorObject *allocator ); + + /* Resets the event manually. */ + void (*reset_event)(struct ThreadEvent* evt); + + /* Sets the event. */ + void (*set_event)(struct ThreadEvent* evt); + + /* Returns true if the event is set. */ + int (*is_event_set)(struct ThreadEvent* evt); + + /* Wait for the event to become set. */ + void (*wait_for_event)(struct ThreadEvent* evt); + + /* Wait for the event to become set with a maximum timeout specified in milliseconds. */ + int (*wait_for_event_timeout)(struct ThreadEvent* evt, unsigned timeout_ms); + + /* Creates a critical section for thread protection and locking. */ + struct ThreadCriticalSection* (*create_critical_section)(struct AllocatorObject *allocator); + + /* Destroys a critical section created by create_critical_section(). */ + void (*destroy_critical_section)(struct ThreadCriticalSection* cs, + struct AllocatorObject *allocator); + + /* Enters the critical section. This will block if any other thread is already in the + critical section. */ + void (*enter_critical_section)(struct ThreadCriticalSection* cs); + + /* Leaves the critical section. */ + void (*leave_critical_section)(struct ThreadCriticalSection* cs); + + /* Tries to enter the critical section. This function won't block, instead it will return + false if another thread is already in the critical section, and true otherwise. */ + int (*try_to_enter_critical_section)(struct ThreadCriticalSection* cs); + + /* Returns the current assigned thread index. */ + unsigned (*worker_thread_index)(); + + /* Assign to the current thread a worker thread index */ + void (*assign_worker_thread_index)(); + + /* Reserved for expansion of the API. */ + void *reserved[30]; +}; + +/* ---------------------------------------------------------------------- + TimerApi +---------------------------------------------------------------------- */ + +/* + API for accessing the game timer. +*/ +struct TimerApi +{ + /* Returns the number of ticks elapsed. The length of a tick is platform dependent, you need + to use ticks_to_seconds() to convert it to a real world number. */ + uint64_t (*ticks)(); + + /* Converts ticks to seconds. */ + double (*ticks_to_seconds)(uint64_t ticks); + + /* Reserved for expansion of the API. */ + void *reserved[32]; +}; + +/* ---------------------------------------------------------------------- + StreamCaptureApi +---------------------------------------------------------------------- */ + +/* Describes a captured buffer. */ +struct SC_Buffer { + /* Frame number. */ + uint32_t frame; + + /* Format descriptor, use RenderBufferApi to interpret */ + uint32_t format; + + /* Surface dimension */ + uint32_t width; + uint32_t height; + + /* Buffer data. */ + void *data; +}; + +/* + Interface for capturing buffer data (render targets, etc) from the engine. +*/ +struct StreamCaptureApi +{ + /* Enables stream capture of the named buffers. */ + void (*enable_capture)(void *window, uint32_t n_buffers, uint32_t *buffer_names); + + /* Disables stream capture for the named buffers. */ + void (*disable_capture)(void *window, uint32_t n_buffers, uint32_t *buffer_names); + + /* Extracts data from the named capture modifier into the output buffer. Returns true if + successful. + + The captured data is allocated with the specified allocator. It is the responsibility of + the caller to deallocate the data pointer in the SC_Buffer. */ + uint8_t (*capture_buffer)(void *window, uint32_t name, struct AllocatorObject *allocator, + struct SC_Buffer *output); + + /* Returns the name of a stream capture modifier */ + const char* (*capture_target_name)(CApiCaptureBufferPtr buffer); + + /* Returns an opaque pointer to a stream capture modifier */ + CApiCaptureBufferPtr (*capture_target)(unsigned index); + + /* Returns the length of currently available stream capture modifiers */ + unsigned (*num_available_capture_targets)(); + + /* Returns the amount of used capture buffers to buffer capture data */ + unsigned (*num_used_buffers)(); + + /* Reserved for expansion of the API. */ + void *reserved[31]; +}; + +/* ---------------------------------------------------------------------- + FlowApi +---------------------------------------------------------------------- */ + +/* Opaque struct representing the context in which flow events are triggered. */ +struct FlowTriggerContext; + +/* Opaque struct representing a set of output events for a flow node. */ +struct FlowOutputEvents; + +/* Identifier for the special query event, which is sent to query nodes to get them to update + their data. */ +#define PLUGIN_QUERY_EVENT 0xffff + +typedef uint32_t FlowNodeType; + +/* Data for a flow trigger event. */ +struct FlowData +{ + /* An integer identifying the type of the flow node. */ + FlowNodeType node_type; + + /* Identifier for the node. */ + unsigned short node; + + /* Index of the in event that was triggered on the flow node. */ + unsigned short event_index; + + /* Opaque struct that represents the out events of the flow node. Can be used to trigger out + events. */ + const struct FlowOutputEvents* out_events; +}; + +/* Maximum number of parameters to a flow node. */ +#define PLUGIN_FLOW_NODES_MAX_PARAMS 63 + +/* Maximum length of flow string variables. */ +#define PLUGIN_FLOW_STRING_VARIABLE_LENGTH 128 + +/* Represents the parameters of a flow node. */ +struct FlowParameters { + const void* parameters[PLUGIN_FLOW_NODES_MAX_PARAMS + 1]; +}; + +struct FlowString +{ + unsigned int is_id64; // Always set to zero + char plain[PLUGIN_FLOW_STRING_VARIABLE_LENGTH]; +}; + +struct FlowId +{ + unsigned int is_id64; // May be 0 or 1 for input, always 1 for output + unsigned int padding; + uint64_t id; +}; + +/* Callback function for performing an action when a flow node is triggered. */ +typedef void (*FlowFunction)(struct FlowTriggerContext* tc, const struct FlowData *fd, const struct FlowParameters *fp); + +/* Callback function for setting variables on the flow node. */ +typedef void (*SetVariableFunction)(struct FlowTriggerContext* tc, const struct FlowParameters *fp, unsigned key, void *data); + +/* Callback function for triggering an out event. */ +typedef void (*EventCallbackFunction)(struct FlowTriggerContext* tc, const struct FlowData *fd, const struct FlowParameters *fp); + +/* + Type Input field (can be null) Output field (not null) + "unit" const CApiUnitRef* CApiUnitRef* + "actor" const CApiActor* CApiActor* + "mover" const CApiMover* CApiMover* + "vector3" const CApiVector3* CApiVector3* + "float" const float* float* + "bool" const unsigned* unsigned* + "string" const FlowString* FlowString* + "id" const FlowId* FlowId* + "quaternion" const CApiQuaternion* CApiQuaternion* + "unsigned" const unsigned* unsigned* + "camera" const CApiCamera* CApiCamera* + "light" const CApiLight* CApiLight* + "mesh" const CApiMesh* CApiMesh* + "material" const CApiMaterial* CApiMaterial* + "resource" const FlowString* + "enum" int +*/ + +/* + Interface for implementing custom flow nodes. +*/ +struct FlowNodesApi +{ + /* Registers a flow trigger function for a flow node with the specified name. */ + void (*setup_trigger_function)(unsigned name_id32, FlowFunction trigger_function); + + /* Registers an event callback for a flow node with the specified name. */ + void (*setup_event_callback)(unsigned name_id32, EventCallbackFunction event_callback_function); + + /* Registers a set_variable callback for a flow node with the specified name. */ + void (*setup_set_variable_callback)(unsigned name_id32, SetVariableFunction variable_callback_function); + + /* Unregisters the flow node with the specified name. */ + void (*unregister_flow_node)(unsigned name_id32); + + /* Used in the flow trigger implementation to trigger one of the flow node's out events. */ + void (*trigger_out_event)(struct FlowTriggerContext *tc, const struct FlowData* fd, int event_index); + + /* Used in the flow trigger implementation to trigger an external level event. */ + void (*trigger_external_level_event)(CApiLevel *level, unsigned id_string_32); + + /* Used in the flow trigger implementation to trigger an external unit event. */ + void (*trigger_external_unit_event)(CApiUnit *unit, unsigned id_string_32); + + /* Reserved for expansion of the API. */ + void *reserved[32]; +}; + +/* ---------------------------------------------------------------------- + CameraApi +---------------------------------------------------------------------- */ + +/* Camera mode. */ +typedef enum +{ + C_MONO, + C_STEREO +} C_Mode; + +/* Camera projection. */ +typedef enum +{ + C_ORTHOGRAPHIC, + C_PERSPECTIVE +} C_ProjectionType; + +/* + Interface for manipulating cameras. +*/ +struct CameraApi +{ + /* Returns the scene graph that owns the camera. */ + struct SceneGraph * (*scene_graph)(CApiCamera *camera); + + /* Returns the near range of the camera. */ + float (*near_range)(CApiCamera *camera); + + /* Sets the near range of the camera. */ + void (*set_near_range)(CApiCamera *, float near_range); + + /* Returns the far range of the camera. */ + float (*far_range)(CApiCamera *camera); + + /* Sets the far range of the camera. */ + void (*set_far_range)(CApiCamera *camera, float far_range); + + /* Returns the projection type of the camera. */ + uint8_t (*projection_type)(CApiCamera *camera); + + /* Sets the projection type of the camera. */ + void (*set_projection_type)(CApiCamera *camera, uint8_t projection_type); + + /* Returns the vertical FOV of the camera. */ + float (*vertical_fov)(CApiCamera *camera, unsigned i); + + /* Sets the vertical FOV of the camera. */ + void (*set_vertical_fov)(CApiCamera *camera, float fov, unsigned i); + + /* Sets the dimensions of the specified camera frustum. */ + void (*set_frustum)(CApiCamera *camera, float left, float right, float bottom, float top, + unsigned i); + void (*set_frustum_shear)(CApiCamera *camera, float shear_x, float shear_y, unsigned i); + + /* Sets the half angles of the specifies camera frustum. */ + void (*set_frustum_half_angles)(CApiCamera *camera, float left_tan, float right_tan, + float bottom_tan, float top_tan, unsigned i); + + /* Returns the camera mode. */ + uint8_t (*mode)(CApiCamera *camera); + + /* Sets the camera mode. */ + void (*set_mode)(CApiCamera *camera, uint8_t mode); + + /* Sets the local position of the camera. */ + void (*set_local)(CApiCamera *camera, ConstMatrix4x4Ptr offset, unsigned i); + + /* Reserved for expansion of the API. */ + void *reserved[32]; +}; + +/* ---------------------------------------------------------------------- + PhysicsRuntimeCookingApi +---------------------------------------------------------------------- */ + +/* + API for doing runtime physics compilation of meshes into physics actors. Currently only supported on UWP. +*/ + +/* Description of the triangle mesh to cook */ +typedef struct MeshDescription +{ + unsigned num_vertices; + unsigned vertice_stride; + void *vertices; + unsigned num_triangles; + unsigned triangle_stride; + void *triangles; +} MeshDescription; + +struct PhysicsRuntimeCookingApi +{ + /* Setup and initialize the physics cooking */ + void (*setup)(); + + /* Shutdown the physics cooking */ + void (*shutdown)(); + + /* Cooks a mesh and returns a pointer to the cooked mesh data allocated in the supplied allocator*/ + void *(*cook_mesh)(const MeshDescription *mesh_description, struct AllocatorObject *allocator); + + /* Creates a physics mesh from cooked data */ + void *(*create_physics_mesh)(const void *cooked_mesh); + + /* Releases physics mesh */ + void (*release_physics_mesh)(void *physics_mesh); + + /* Reserved for expansion of the API. */ + void *reserved[32]; +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/plugin_api_types.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/plugin_api_types.h new file mode 100644 index 0000000..653c9eb --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/plugin_api_types.h @@ -0,0 +1,136 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/* Opaque struct representing a memory allocator. */ +struct AllocatorObject; + +typedef struct CApiUnit CApiUnit; +typedef struct CApiWindow CApiWindow; +typedef struct CApiWorld CApiWorld; +typedef struct CApiLevel CApiLevel; +typedef struct CApiActor CApiActor; +typedef struct CApiMover CApiMover; +typedef struct CApiCamera CApiCamera; +typedef struct CApiViewport CApiViewport; +typedef struct CApiLight CApiLight; +typedef struct CApiMaterial CApiMaterial; +typedef struct CApiMesh CApiMesh; +typedef struct CApiShadingEnvironment CApiShadingEnvironment; +typedef struct CApiNavigationMesh CApiNavigationMesh; +typedef struct CApiPhysicsWorld CApiPhysicsWorld; +typedef struct CApiLineObject CApiLineObject; +typedef struct CApiGui CApiGui; +typedef struct CApiStoryTeller CApiStoryTeller; +typedef struct CApiVideoPlayer CApiVideoPlayer; +typedef struct CApiReplay CApiReplay; +typedef struct CApiVectorField CApiVectorField; +typedef struct CApiScatterSystem CApiScatterSystem; +typedef struct CApiMaterialData CApiMaterialData; +typedef struct CApiStreamSource CApiStreamSource; +typedef struct CApiTimpaniWorldInterface CApiTimpaniWorldInterface; +typedef struct CApiGuiThumbnail CApiGuiThumbnail; +typedef struct CApiCaptureBuffer CApiCaptureBuffer; +typedef struct CApiInputController CApiInputController; +typedef struct CApiUnitSynchronizer CApiUnitSynchronizer; + +typedef struct CApiTransformComponent CApiTransformComponent; +typedef struct CApiMeshComponent CApiMeshComponent; +typedef struct CApiActorComponent CApiActorComponent; +typedef struct CApiSceneGraphComponent CApiSceneGraphComponent; +typedef struct CApiAnimationBlenderComponent CApiAnimationBlenderComponent; +typedef struct CApiAnimationStateMachineComponent CApiAnimationStateMachineComponent; +typedef struct CApiDebugNameComponent CApiDebugNameComponent; +typedef struct CApiDataComponentPtr CApiDataComponentPtr; +typedef struct CApiRenderDataComponent CApiRenderDataComponent; +typedef struct CApiTagComponent CApiTagComponent; +typedef struct CApiComponent CApiComponent; +typedef struct CApiFlowComponent CApiFlowComponent; +typedef struct CApiUnitComponent CApiUnitComponent; + +typedef unsigned CApiUnitRef; +typedef unsigned CApiInstance; +typedef unsigned CApiInstanceId; + +typedef struct CApiInstanceWithId +{ + CApiInstance instance; + CApiInstanceId id; +} CApiInstanceWithId; + +typedef struct CApiVector2 +{ + union { float x; float u; }; + union { float y; float v; }; +} CApiVector2; + +typedef struct CApiVector3 +{ + float x, y, z; +} CApiVector3; + +typedef struct CApiVector4 +{ + float x, y, z, w; +} CApiVector4; + +typedef struct CApiQuaternion +{ + float x,y,z,w; +} CApiQuaternion; + +typedef struct CApiMatrix3x3 +{ + CApiVector3 x, y, z; +} CApiMatrix3x3; + +typedef struct CApiMatrix4x4 +{ + float v[16]; +} CApiMatrix4x4; + +typedef struct CApiTransform +{ + CApiQuaternion q; + CApiVector3 p; +} CApiTransform; + +typedef struct CApiLocalTransform +{ + CApiMatrix3x3 rot; + CApiVector3 pos; + CApiVector3 scale; + float dummy; // Force 16 byte alignment +} CApiLocalTransform; + +typedef struct CApiPhysicsWorldSettings +{ + char apex_cloth; + float apex_lod_resource_budget; + + int step_frequency; + int max_substeps; + char async_timestep; + char swept_integration; +} CApiPhysicsWorldSettings; + +typedef struct CApiWorldConfig { + char disable_physics; + char disable_sound; + char disable_rendering; + char enable_replay; + CApiPhysicsWorldSettings physics_world_settings; + unsigned long long decals; +} CApiWorldConfig; + +typedef void (*CApiCallbackFunction)(const void*); + +typedef struct CApiCallbackData32 { + char _data[32]; +} CApiCallbackData32; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/plugin_c_api.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/plugin_c_api.h new file mode 100644 index 0000000..7d73976 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/plugin_c_api.h @@ -0,0 +1,73 @@ +#pragma once + +#include "c_api/c_api_input.h" +#include "c_api/c_api_world.h" +#include "c_api/c_api_application.h" +#include "c_api/c_api_unit.h" +#include "c_api/c_api_camera.h" +#include "c_api/c_api_material.h" +#include "c_api/c_api_lan.h" +#include "c_api/c_api_network.h" +#include "c_api/c_api_game_session.h" +#include "c_api/c_api_unit_synchronizer.h" +#include "c_api/c_api_level.h" +#include "c_api/c_api_utilities.h" +#include "c_api/c_api_psn.h" +#include "c_api/c_api_dynamic_script_data.h" +#include "c_api/c_api_entity.h" +#include "c_api/c_api_line_object.h" +#include "c_api/c_api_gui.h" +#include "c_api/c_api_physics_world.h" +#include "c_api/c_api_actor.h" +#include "c_api/c_api_mover.h" +#include "c_api/c_api_save_system.h" +#include "c_api/c_api_viewport.h" +#include "c_api/c_api_mesh.h" +#include "c_api/c_api_ps4.h" +#include "c_api/c_api_ps4_ime_dialog.h" +#include "c_api/c_api_ps4_msg_dialog.h" +#include "c_api/c_api_ps4_error_dialog.h" +#include "c_api/c_api_ps4_np_commerce_dialog.h" +#include "c_api/c_api_window.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +struct ScriptApi +{ + struct InputCApi *Input; + struct WorldCApi* World; + struct ApplicationCApi* Application; + struct UnitCApi* Unit; + struct CameraCApi* Camera; + struct MaterialCApi* Material; + struct LanCApi* Lan; + struct NetworkCApi* Network; + struct GameSessionCApi* GameSession; + struct UnitSynchronizerCApi* UnitSynchronizer; + struct LevelCApi* Level; + struct UtilitiesCApi* Utilities; + struct PsnCApi* Psn; + struct DynamicScriptDataCApi* DynamicScriptData; + struct EntityCApi* Entity; + struct LineObjectCApi* LineObject; + struct GuiCApi* Gui; + struct PhysicsWorldCApi* PhysicsWorld; + struct ActorCApi* Actor; + struct MoverCApi* Mover; + struct SaveSystemCApi* SaveSystem; + struct ViewportCApi* Viewport; + struct MeshCApi* Mesh; + struct Ps4CApi* Ps4; + struct Ps4ImeDialogCApi* Ps4ImeDialog; + struct Ps4MsgDialogCApi* Ps4MsgDialog; + struct Ps4ErrorDialogCApi* Ps4ErrorDialog; + struct Ps4NpCommerceDialogCApi* Ps4NpCommerceDialog; + struct WindowCApi* Window; +}; + +#ifdef __cplusplus +} +#endif diff --git a/lib/dt_p2p/stingray_sdk/engine_plugin_api/plugin_scene_database_api.h b/lib/dt_p2p/stingray_sdk/engine_plugin_api/plugin_scene_database_api.h new file mode 100644 index 0000000..cef0145 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/engine_plugin_api/plugin_scene_database_api.h @@ -0,0 +1,347 @@ +#pragma once + +#ifdef CAN_COMPILE + +#include +#include +#include + +enum SDB_ChannelType { + SDCT_FLOAT1 = 0, + SDCT_FLOAT2, + SDCT_FLOAT3, + SDCT_FLOAT4, + SDCT_MATRIX4x4, + SDCT_QUATERNION, + SDCT_FLOAT3_CMP_11_11_10, + SDCT_HALF1, + SDCT_HALF2, + SDCT_HALF3, + SDCT_HALF4, + SDCT_UBYTE4, + SDCT_SHORT1, + SDCT_SHORT2, + SDCT_SHORT3, + SDCT_SHORT4, + SDCT_COUNT +}; + +/* Direct Access, No extra memory copy */ +struct SD_Scene; +struct SD_Indices; +struct SD_Geometry; +struct SD_GeometryMaterial; +struct SD_Animation; +struct SD_AnimationTake; +struct SD_Stream; +struct SD_Channel; +struct SD_BlendShapeTarget; +struct SD_Streams; + +/* Indirect Access, Copy memory */ +struct SDB_StringList { + uint32_t size; + const char **data; +}; + +struct SDB_Channel { + const char *name; + uint32_t index; + SDB_ChannelType type; +}; + +struct SDB_Stream { + uint32_t n_channels; + SDB_Channel *channels; + uint32_t size; + uint32_t stride; + uint32_t n_data; + uint8_t *data; +}; + +struct SDB_Node { + const char *name; + const char *parent; + SDB_StringList children; + float local[16]; + SDB_StringList geometries; + uint8_t viewport_visible; + uint8_t has_local_mirroring; +}; + +struct SDB_IndicesStream { + uint32_t n_indices; + uint32_t *indices; +}; + +struct SDB_Indices { + + uint32_t n_indices; + uint32_t n_streams; + SDB_IndicesStream *streams; +}; + +struct SDB_Joint { + const char *name; + float inv_bind_matrix[16]; +}; + +struct SDB_Skin { + const char *name; + uint32_t max_affecting_bones; + uint32_t n_joints; + SDB_Joint *joints; +}; + +struct SDB_GeometryInstance { + const char *name; + const char *geometry; + SDB_StringList materials; +}; + +struct SDB_GeometryMaterial { + const char *name; + uint32_t n_primitives; + uint32_t *primitives; +}; + +struct SDB_GeometryBlendShapeTarget { + const char *name; + uint32_t n_streams; + SDB_Stream *streams; +}; + +struct SDB_Geometry { + const char *name; + uint32_t n_streams; + SDB_Stream *streams; + SDB_Indices indices; + const char *skin; + uint32_t n_materials; + SDB_GeometryMaterial *materials; + uint32_t n_primitive_smoothing; + uint32_t *primitive_smoothing; + uint32_t n_blend_shape_targets; + SDB_GeometryBlendShapeTarget *blend_shape_targets; + uint8_t shadow_caster; + uint32_t n_vertex_position_remapping; + uint32_t *vertex_position_remapping; + uint32_t n_vertex_normal_remapping; + uint32_t *vertex_normal_remapping; +}; + +enum SDB_LightDefinitionType { + OMNI = 0, + SPOT = 1, + BOX = 2, + DIRECTIONAL = 3 +}; +struct SDB_Light { + const char *name; + SDB_LightDefinitionType type; + float color[4]; + float falloff_start; + float falloff_end; + float spot_angle_start; + float spot_angle_end; + uint8_t cast_shadow; +}; + +enum SDB_CameraDefinitionType { + ORTHOGRAPHIC, + PERSPECTIVE +}; +struct SDB_Camera { + const char *name; + SDB_CameraDefinitionType type; + float near_plane; + float far_plane; + float vertical_fov; +}; + +struct SDB_Animation { + const char *node; + const char *parameter; + uint32_t n_times; + float *times; + SDB_Stream data; +}; + +struct SDB_AnimationTake { + const char *name; + float start_time; + float end_time; + uint32_t nb_samples; + uint32_t n_animations; + SDB_Animation *animations; +}; + +struct SDB_SurfaceMaterialProperty { + const char *name; + uint32_t n_integers; + int integer; + uint32_t n_floats; + float floats[4]; + const char *value_string; + SDB_StringList textures; +}; + +struct SDB_SurfaceMaterialProperties { + uint32_t size; + SDB_SurfaceMaterialProperty *data; +}; + +enum SDB_SurfaceMaterialDefinitionType { + LAMBERT = 0, + PHONG = 1, + SHADER = 2 +}; +struct SDB_SurfaceMaterial { + const char *name; + SDB_SurfaceMaterialDefinitionType type; + SDB_SurfaceMaterialProperties properties; + uint32_t nb_influences; +}; + +struct SDB_Texture { + const char *name; + const char *file_path; + const char *relative_path; + uint8_t embedded; + float uv_offset[2]; + float uv_scale[2]; + float uv_rotation; +}; + +struct SDB_LevelOfDetailStep { + SDB_StringList nodes; + float min_pct; + float max_pct; +}; + +struct SDB_LevelOfDetail { + const char *name; + const char *orientation_node; + const char *bounding_volume; + uint8_t requires_predefined_pct; + uint32_t n_steps; + SDB_LevelOfDetailStep *steps; +}; + +enum SDB_SceneImportTangents { + TANGENTS_IMPORT, + TANGENTS_MIKKTSPACE +}; +struct SDB_SceneImportOptions { + uint8_t combine_meshes; + uint8_t combine_meshes_by_material; + uint8_t reverse_forward_axis; + uint8_t skip_create_extra_root; + uint8_t skip_textures; + uint8_t skip_lights; + uint8_t skip_cameras; + uint8_t create_missing_uvs; + SDB_SceneImportTangents tangents; +}; + +struct SDB_Property { + const char *first; + const char *second; +}; + +struct SDB_Nodes { + uint32_t size; + SDB_Node *data; +}; + +struct SDB_GeometryInstances { + uint32_t size; + SDB_GeometryInstance *data; +}; + +struct SDB_Geometries { + uint32_t size; + SDB_Geometry *data; +}; + +struct SDB_Lights { + uint32_t size; + SDB_Light *data; +}; + +struct SDB_Cameras { + uint32_t size; + SDB_Camera *data; +}; + +struct SDB_Skins { + typedef SDB_Skin value_type; + uint32_t size; + SDB_Skin *data; +}; + +struct SDB_SurfaceMaterials { + uint32_t size; + SDB_SurfaceMaterial *data; +}; + +struct SDB_Textures { + uint32_t size; + SDB_Texture *data; +}; + +struct SDB_LevelOfDetails { + uint32_t size; + SDB_LevelOfDetail *data; +}; + +struct SDB_AnimationTakes { + uint32_t size; + SDB_AnimationTake *data; +}; + +struct SDB_Properties { + uint32_t size; + SDB_Property *data; +}; + +struct SDB_SceneDatabase { + SDB_Nodes nodes; + SDB_StringList roots; + SDB_GeometryInstances geometry_instances; + SDB_Geometries geometries; + SDB_Lights lights; + SDB_Cameras cameras; + SDB_Skins skins; + SDB_SurfaceMaterials materials; + SDB_Textures textures; + SDB_LevelOfDetails lods; + SDB_AnimationTakes anim_takes; + const char *source_path; + SDB_SceneImportOptions import_options; + SDB_Properties properties; +}; + +struct SceneDatabaseApi +{ + void (*scene)(SD_Scene *scene, SDB_SceneDatabase *dest, struct AllocatorObject *allocator); + void (*set_scene)(SD_Scene *scene, const SDB_SceneDatabase *source); + + void (*geometries)(SD_Scene *scene, SDB_Geometries *dest, struct AllocatorObject *allocator); + + const char * (*source_path)(const SD_Scene *scene); + void (*set_source_path)(SD_Scene *scene, const char *text); + + SDB_SceneImportOptions (*import_options)(SD_Scene *scene); + void (*set_import_options)(SD_Scene *scene, const SDB_SceneImportOptions *source); + + /* Utilities */ + SD_Scene * (*create)(struct DataCompileParameters *params, const char *resource_name); + void (*destroy)(SD_Scene *scene); + + uint32_t (*channel_size)(SDB_ChannelType channel_type); + + void (*apply_modifiers)(SD_Scene *scene, const char *platform_name, const char *resource_name, bool modify_tangents); +}; + +#endif /* CAN_COMPILE */ diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/allocator.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/allocator.h new file mode 100644 index 0000000..16c710d --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/allocator.h @@ -0,0 +1,106 @@ +#pragma once + +#include "../engine_plugin_api/plugin_api.h" + +#define _XKEYCHECK_H +#define alignof(x) __alignof(x) + +namespace stingray_plugin_foundation { + +// Abstract base class for allocators. +// +// Allocators can be thread-safe or not, see the separate documentation for each +// alloactor. +class Allocator +{ + Allocator(const Allocator &); + Allocator & operator=(const Allocator &); + +public: + static const int DEFAULT_ALIGN = 4; + + Allocator() {} + virtual ~Allocator() {} + + // Convenience method for allocating when you don't care about allocated size. + virtual void *allocate(size_t size, unsigned align = DEFAULT_ALIGN) = 0; + + // Frees the memory pointed to by p, the memory must have been allocated by the allocate() + // function. Returns the size of the allocated memomry. + virtual size_t deallocate(void *p) = 0; +}; + +// Allocator class that wraps the AllocatorApi exposed by the engine's plugin interface. +class ApiAllocator : public Allocator +{ + AllocatorObject *_object; + AllocatorApi *_api; + +public: + ApiAllocator(AllocatorApi *api, AllocatorObject *object) : _object(object), _api(api) {} + ApiAllocator(const ApiAllocator &a) : _object(a._object), _api(a._api) {} + ApiAllocator & operator=(const ApiAllocator &a) { _object = a._object; _api = a._api; return *this; } + + virtual void *allocate(size_t size, unsigned align = DEFAULT_ALIGN) override {return _api->allocate(_object, size, align);} + virtual size_t deallocate(void *p) override {return _api->deallocate(_object, p);} + + AllocatorObject *object() { return _object; } + AllocatorApi *api() { return _api; } +}; + +template void make_delete(Allocator &a, T *p) { + if (p) { + p->~T(); + a.deallocate(p); + } +} + +// Allocator that allocates from a static buffer. +class StaticAllocator : public Allocator +{ + char *_start; + char *_p; + char *_end; + +public: + StaticAllocator(char *p, char *end) : _start(p), _p(p), _end(end) {} + + virtual void *allocate(size_t size, unsigned align = DEFAULT_ALIGN) override + { + if (size == 0) + return nullptr; + + unsigned rem = (_p - (const char *)0) % align; + if (rem) + _p += (align - rem); + char *ret = _p + size > _end ? nullptr : _p; + _p += size; + return ret; + } + + size_t deallocate(void *p) override { return 0; } + + char *start() {return _start;} + bool out_of_memory() {return _p > _end;} + size_t wanted_memory() {return (size_t)(_p - _start);} +}; + +// Allocations released only by destructor +class TempAllocator : public ApiAllocator +{ +public: + TempAllocator(AllocatorApi *api) : ApiAllocator(api, api->make_temp_allocator()) {} + virtual ~TempAllocator() { api()->destroy_temp_allocator(object()); } +}; + +// Add this in the public section of classes to specify that they want to be initialized with an +// allocator. +#define ALLOCATOR_AWARE typedef int allocator_aware + +// Macro versions of make_new and make_delete to avoid template combinatorial explosion and +// make sure errors are reported in the file where the macro is called. +#define MAKE_NEW(a, T, ...) (new ((a).allocate(sizeof(T), alignof(T))) T(__VA_ARGS__)) +#define MAKE_DELETE(a, p) (make_delete(a,p)) +#define MAKE_DELETE_TYPE(a, T, p) do {if (p) {(p)->~T(); (a).deallocate(p);}} while (0) + +} // namespace stingray_plugin_foundation diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/array.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/array.h new file mode 100644 index 0000000..2b972a2 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/array.h @@ -0,0 +1,149 @@ +#pragma once + +#include "allocator.h" +#include + +namespace stingray_plugin_foundation { + +struct NoAllocator; + +// An Array<> is a simplified Vector<> for POD types that does not call +// constructors or destructors for its elements (it doesn't even zero the +// memory). It also assumes that the members can be moved and copied with +// a memmove operation and compared with memcmp. +template +class Array +{ +public: + // Type definitions + + typedef Array this_type; + typedef T value_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef T& reference; + typedef const T& const_reference; + typedef pointer iterator; + typedef const_pointer const_iterator; + + // Constructors + + // Creates an array that uses the specified allocator to allocate memory. + Array(Allocator &allocator); + + // Creates an array and presizes it to the specified size. + Array(unsigned size, Allocator &allocator); + + // Creates an array without an allocator, one must be provided later with + // set_allocator() before the array is resized. + Array(const NoAllocator &); + + // Sets the allocator of the array. You can only call this before any + // allocations have been made by the array. + void set_allocator(Allocator &allocator); + + Array( const Array &o ); + ~Array() {reset();} + + // Asignment operator -- note that we do not support chained assignments. + void operator=(const Array &o); + + // std::vector interface + + iterator begin() {return _data;} + const_iterator begin() const {return _data;} + iterator end() {return _data + _size;} + const_iterator end() const {return _data + _size;} + + unsigned size() const {return _size;} + unsigned capacity() const {return _capacity;} + bool any() const {return _size != 0;} + bool empty() const {return _size == 0;} + + reference operator[](unsigned i); + const_reference operator[](unsigned i) const; + + void reserve(unsigned capacity); + + reference front() {return _data[0];} + const_reference front() const {return _data[0];} + reference back() {return _data[_size-1];} + const_reference back() const {return _data[_size-1];} + + template void push_back(const ASSIGNABLE &item); + void pop_back(); + + void swap(Array &o); + + template iterator insert(iterator pos, const ASSIGNABLE & x); + iterator insert(iterator pos); + void insert(iterator pos, const_iterator from, const_iterator to); + iterator erase(iterator pos); + iterator erase(iterator first, iterator last); + + void clear() {resize(0);} + void resize(unsigned size); + + // Serializes the array to the stream. + template void serialize(STREAM &stream); + + bool operator==(const Array &o) const; + bool operator<(const Array &o) const; + + // Array extensions + + // Resets the array to initial state (no memory allocated). + void reset() {set_capacity(0);} + + // Extends the array with the specified number of elements and returns a pointer to the first new element. + pointer extend(unsigned elements) { resize(size() + elements); return _data + _size - elements; } + + // Extends the array with one elements and returns a reference to the newly created element. + reference extend() { resize(size() + 1); return back(); } + + // Returns the allocator of the array. + Allocator &allocator() const {return *_allocator;} + + // Sets the capacity of the array to exactly the specified ammount. + // This operation always reallocates the memory of the array, no + // swap trick is necessary to enforce reallocation. + void set_capacity(unsigned capacity); + + // Trims the array so that the capacity corresponds to its current size. + void trim() {set_capacity(size());} + + // Finds the first occurrence of x in the array and returns it. + template iterator find(const EQUATABLE &x) {return std::find(begin(), end(), x);} + + // Finds the first occurrence of x in the array and returns it. + template const_iterator find(const EQUATABLE &x) const {return std::find(begin(), end(), x);} + + // Returns the index of x in the array (or size() if it is not in the array). + template unsigned index_of(const EQUATABLE &x) const {return (unsigned)(find(x) - begin());} + + // Returns if x is in the array + template bool has(const EQUATABLE &x) const {return (find(x) != end());} + + // Erases the first occurrence of x in the array. + template void erase(const EQUATABLE &item); + + // "Steals" the data buffer from the array. The array will be empty after this operation. The "stealer" is + // responsible for deallocating the stolen buffer. + pointer steal(); + +private: + void move(pointer to, pointer from, unsigned n); + void copy(pointer to, const_pointer from, unsigned n); + + void grow(unsigned min_capacity = 0); + +private: + unsigned _size; + unsigned _capacity; + pointer _data; + Allocator * _allocator; +}; + +} // namespace stingray_plugin_foundation + +#include "array.inl" diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/array.inl b/lib/dt_p2p/stingray_sdk/plugin_foundation/array.inl new file mode 100644 index 0000000..ea8aee8 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/array.inl @@ -0,0 +1,276 @@ +#include "assert.h" + +namespace stingray_plugin_foundation { + +template Array::Array(Allocator &allocator) : _size(0), _capacity(0), _data(0), _allocator(&allocator) +{ +} + +template Array::Array(unsigned size, Allocator &allocator) : _size(0), _capacity(0), _data(0), _allocator(&allocator) +{ + resize(size); +} + +template Array::Array(const NoAllocator &) : _size(0), _capacity(0), _data(0), _allocator(0) +{ +} + +template void Array::set_allocator(Allocator &allocator) +{ + _allocator = &allocator; +} + +template Array::Array( const Array &o ) : _size(0), _capacity(0), _data(0), _allocator(o._allocator) +{ + set_capacity(o.size()); + copy(_data, o._data, o.size()); + _size = o.size(); +} + +template void Array::operator=(const Array &o) +{ + resize(o.size()); + copy(_data, o._data, o.size()); +} + +template typename Array::reference Array::operator[](unsigned i) { + XENSURE(i < _size); + return _data[i]; +} +template typename Array::const_reference Array::operator[](unsigned i) const { + XENSURE(i < _size); + return _data[i]; +} + +template void Array::reserve(unsigned capacity) +{ + if (capacity > _capacity) + grow(capacity); +} + +template template +void Array::push_back(const ASSIGNABLE &item) +{ + if (_size + 1 > _capacity) + grow(); + _data[_size++] = item; +} + +template void Array::pop_back() +{ + _size--; +} + +template void Array::swap(Array &o) +{ + XENSURE(_allocator == o._allocator); + std::swap(_size, o._size); + std::swap(_capacity, o._capacity); + std::swap(_data, o._data); + std::swap(_allocator, o._allocator); +} + +template template +typename Array::iterator Array::insert(iterator pos, const ASSIGNABLE& x) +{ + if (_size + 1 > _capacity) { + unsigned i = (unsigned)(pos - _data); + grow(); + pos = _data + i; + } + move(pos + 1, pos, (unsigned)((_data + _size) - pos)); + *pos = x; + ++_size; + return pos; +} + +template typename Array::iterator Array::insert(iterator pos) +{ + if (_size + 1 > _capacity) { + unsigned i = pos - _data; + grow(); + pos = _data + i; + } + move(pos + 1, pos, (_data + _size) - pos); + ++_size; + return pos; +} + +template void Array::insert(iterator pos, const_iterator from, const_iterator to) +{ + unsigned add = (unsigned)(to - from); + if (_size + add > _capacity) { + size_t i = pos - _data; + grow(_size + add); + pos = _data + i; + } + move(pos + add, pos, (unsigned)((_data + _size) - pos)); + copy(pos, from, add); + _size += add; +} + +template typename Array::iterator Array::erase(iterator pos) +{ + XASSERT(pos >= begin() && pos < end(), "Trying to remove outside array."); + move(pos, pos + 1, (unsigned)((_data + _size) - pos - 1)); + --_size; + return pos; +} + +template typename Array::iterator Array::erase(iterator first, iterator last) +{ + move(first, last, (unsigned)((_data + _size) - last)); + _size -= (unsigned)(last - first); + return first; +} + +template template void Array::erase(const EQUATABLE &item) +{ + iterator it = find(item); + XENSURE(it != end()); + erase(it); +} + +template void Array::resize(unsigned size) +{ + if (size > _capacity) + grow(size); + + _size = size; +} + +template void Array::set_capacity(unsigned capacity) +{ + if (capacity == _capacity) + return; + + if (capacity < _size) + resize(capacity); + + pointer new_data = 0; + + if (capacity > 0) { + unsigned align = alignof(value_type) > 4 ? alignof(value_type) : 4; + new_data = (pointer)_allocator->allocate(sizeof(value_type)*capacity, align); + copy(new_data, _data, _size); + } + _allocator->deallocate(_data); + + _data = new_data; + _capacity = capacity; +} + +template void Array::move(pointer to, pointer from, unsigned n) +{ + memmove((void *)to, (void *)from, sizeof(T) * n); +} + +template void Array::copy(pointer to, const_pointer from, unsigned n) +{ + memcpy((void *)to, (void *)from, sizeof(T) * n); +} + +template +template void Array::serialize(STREAM &stream) +{ + unsigned sz = size(); + stream & sz; + resize(sz); + for (unsigned i=0; i +void raw_array_serialize(STREAM &s, Array &data) +{ + unsigned n = data.size(); + s & n; + data.resize(n); + + if (n > 0) { + if (s.is_output()) + s.write(data.begin(), n * sizeof(T)); + else + s.read(data.begin(), n * sizeof(T)); + } +} + +template <> +template void Array::serialize(STREAM &stream) { + raw_array_serialize(stream, *this); +} + +template <> +template void Array::serialize(STREAM &stream) { + raw_array_serialize(stream, *this); +} + +template <> +template void Array::serialize(STREAM &stream) { + raw_array_serialize(stream, *this); +} + +template <> +template void Array::serialize(STREAM &stream) { + raw_array_serialize(stream, *this); +} + +template <> +template void Array::serialize(STREAM &stream) { + raw_array_serialize(stream, *this); +} + +template <> +template void Array::serialize(STREAM &stream) { + raw_array_serialize(stream, *this); +} + +template <> +template void Array::serialize(STREAM &stream) { + raw_array_serialize(stream, *this); +} + +template <> +template void Array::serialize(STREAM &stream) { + raw_array_serialize(stream, *this); +} + +template <> +template void Array::serialize(STREAM &stream) { + raw_array_serialize(stream, *this); +} + +template bool Array::operator==(const Array &o) const +{ + if (size() != o.size()) + return false; + return memcmp(_data, o._data, sizeof(T)*size()) == 0; +} + +template bool Array::operator<(const Array &o) const +{ + if (size() != o.size()) + return size() < o.size(); + return memcmp(_data, o._data, sizeof(T)*size()) < 0; +} + +template void Array::grow(unsigned min_capacity) +{ + uint64_t new_capacity = (uint64_t)_capacity*2 + 10; + if (new_capacity < min_capacity) + new_capacity = min_capacity; + else if (new_capacity > UINT32_MAX) + new_capacity = UINT32_MAX; + set_capacity((unsigned)new_capacity); +} + +template typename Array::pointer Array::steal() +{ + pointer return_value = _data; + _data = 0; + _capacity = 0; + _size = 0; + return return_value; +} + +} // namespace stingray_plugin_foundation diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/assert.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/assert.h new file mode 100644 index 0000000..fc5c1ed --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/assert.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include "../engine_plugin_api/plugin_api.h" + +#if defined(DEVELOPMENT) + namespace stingray_plugin_foundation { + inline struct ErrorApi *&error_api() + { + static struct ErrorApi *api = nullptr; + return api; + } + inline void set_error_api(struct ErrorApi *api) + { + error_api() = api; + } + } + + #define XASSERT_BASE(test, test_msg, msg, ...) \ + do {if (!(test)) { \ + struct ErrorApi *api = stingray_plugin_foundation::error_api(); \ + if (api && api->report_assert_failure) \ + api->report_assert_failure(__LINE__, __FILE__, test_msg, api->eprintf(msg, ## __VA_ARGS__)); \ + else \ + assert(test); \ + }} while (0) + #define XASSERT(test, msg, ...) do {XASSERT_BASE(test, #test, msg, ## __VA_ARGS__);} while(0) + #define XENSURE(test) do {XASSERT_BASE(test, #test, "Assertion failed");} while(0) + #define XERROR(msg, ...) do {XASSERT_BASE(false, nullptr, msg, ## __VA_ARGS__);} while(0) +#else + #define XASSERT(test, msg, ...) ((void)0) + #define XENSURE(test) ((void)0) + #define XERROR(msg, ...) ((void)0) + + namespace stingray_plugin_foundation { + inline void set_error_api(struct ErrorApi *api) {} + } +#endif diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/bucket_iterator.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/bucket_iterator.h new file mode 100644 index 0000000..7cf8d42 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/bucket_iterator.h @@ -0,0 +1,97 @@ +#pragma once + +namespace stingray_plugin_foundation { + +template +class ConstBucketIterator; + +// A helper class that makes an iterator for a bucket based data structure. +// Such a data structure has a number of random access buckets which may be +// "valid" or not. The iterator iterates over the valid buckets only. +template +class BucketIterator { +public: + typedef BucketIterator iterator; + friend class ConstBucketIterator; + + typedef ITEM value_type; + typedef ITEM* pointer; + typedef ITEM& reference; + typedef ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + inline BucketIterator() : _i(0) { } + inline BucketIterator(CONTAINER &container, unsigned i); + inline BucketIterator(const BucketIterator &other); + + inline bool operator==(const iterator &rhs) const { return cmp(rhs) == 0; } + inline bool operator!=(const iterator &rhs) const { return cmp(rhs) != 0; } + inline bool operator<(const iterator &rhs) const { return cmp(rhs) < 0; } + inline bool operator<=(const iterator &rhs) const { return cmp(rhs) <= 0; } + inline bool operator>(const iterator &rhs) const { return cmp(rhs) > 0; } + inline bool operator>=(const iterator &rhs) const { return cmp(rhs) >= 0; } + + inline iterator operator++(); + inline iterator operator++(int); + + inline ITEM &operator*() { return _container->bucket_value(_i); } + inline ITEM *operator->() { return &_container->bucket_value(_i); } + +private: + inline int cmp(const iterator &rhs) const { + if(_container < rhs._container) return -1; + else if(_container > rhs._container) return 1; + else if(_i < rhs._i) return -1; + else if(_i > rhs._i) return 1; + else return 0; + } + + void advance_to_valid_bucket(); + + CONTAINER *_container; + unsigned _i; +}; + +// A helper class that makes an iterator for a bucket based data structure. +// Such a data structure has a number of random access buckets which may be +// "valid" or not. The iterator iterates over the valid buckets only. +template +class ConstBucketIterator { +public: + typedef ConstBucketIterator iterator; + + typedef ITEM value_type; + typedef ITEM* pointer; + typedef ITEM& reference; + typedef ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + inline ConstBucketIterator() : _i(0) {} + inline ConstBucketIterator(const CONTAINER &container, unsigned i); + inline ConstBucketIterator(const ConstBucketIterator &rhs); + inline ConstBucketIterator(const BucketIterator &rhs); + + inline bool operator==(const iterator &rhs) const { return cmp(rhs) == 0; } + inline bool operator!=(const iterator &rhs) const { return cmp(rhs) != 0; } + inline bool operator<(const iterator &rhs) const { return cmp(rhs) < 0; } + inline bool operator<=(const iterator &rhs) const { return cmp(rhs) <= 0; } + inline bool operator>(const iterator &rhs) const { return cmp(rhs) > 0; } + inline bool operator>=(const iterator &rhs) const { return cmp(rhs) >= 0; } + + inline iterator operator++(); + inline iterator operator++(int); + + inline const ITEM &operator*() { return _container->bucket_value(_i); } + inline const ITEM *operator->() { return &_container->bucket_value(_i); } + +private: + inline int cmp(const iterator &rhs) const {if (_container != rhs._container) return (int)(_container - rhs._container); return (int)(_i - rhs._i);} + void advance_to_valid_bucket(); + + const CONTAINER *_container; + unsigned _i; +}; + +} // namespace stingray_plugin_foundation + +#include "bucket_iterator.inl" diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/bucket_iterator.inl b/lib/dt_p2p/stingray_sdk/plugin_foundation/bucket_iterator.inl new file mode 100644 index 0000000..a4d5a71 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/bucket_iterator.inl @@ -0,0 +1,89 @@ +namespace stingray_plugin_foundation { + +// ---------------------------------------------------------------------- +// BucketIterator +// ---------------------------------------------------------------------- + +template +BucketIterator::BucketIterator(CONTAINER &container, unsigned int i) : _container(&container), _i(i) +{ + advance_to_valid_bucket(); +} + +template +BucketIterator::BucketIterator(const iterator &other) : _container(other._container), _i(other._i) +{} + +template +BucketIterator BucketIterator::operator++() +{ + //XASSERT(_i < _container->num_buckets(), "iterating past end of container"); + XENSURE(_i < _container->num_buckets()); + ++_i; + advance_to_valid_bucket(); + return *this; +} + +template +BucketIterator BucketIterator::operator++(int) +{ + iterator result = *this; + ++(*this); + return result; +} + +template +void BucketIterator::advance_to_valid_bucket() +{ + unsigned int size = _container->num_buckets(); + for (; _i < size; ++_i) + if (_container->bucket_valid(_i)) + break; +} + +// ---------------------------------------------------------------------- +// ConstBucketIterator +// ---------------------------------------------------------------------- + + +template +ConstBucketIterator::ConstBucketIterator(const CONTAINER &container, unsigned int i) : _container(&container), _i(i) +{ + advance_to_valid_bucket(); +} + +template +ConstBucketIterator::ConstBucketIterator(const iterator &other) : _container(other._container), _i(other._i) +{} + +template +ConstBucketIterator::ConstBucketIterator(const BucketIterator &other) : _container(other._container), _i(other._i) +{} + +template +ConstBucketIterator ConstBucketIterator::operator++() +{ + XASSERT(_i < _container->num_buckets(), "iterating past end of container"); + ++_i; + advance_to_valid_bucket(); + return *this; +} + +template +ConstBucketIterator ConstBucketIterator::operator++(int) +{ + iterator result = *this; + ++(*this); + return result; +} + +template +void ConstBucketIterator::advance_to_valid_bucket() +{ + unsigned int size = _container->num_buckets(); + for (; _i < size; ++_i) + if (_container->bucket_valid(_i)) + break; +} + +} // namespace stingray_plugin_foundation diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/buffer.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/buffer.h new file mode 100644 index 0000000..ed39d63 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/buffer.h @@ -0,0 +1,73 @@ +#pragma once + +#include "stream.h" +//#include "array.h" +#include "allocator.h" + +// sourced from engine's data_compiler.h + +namespace stingray_plugin_foundation { + +namespace buffer +{ + //Buffer buffer(const Array &resource, Allocator &allocator) { + // Buffer result; + // result.len = resource.size(); + // result.p = (char *)allocator.allocate(result.len); + // memmove(result.p, resource.begin(), result.len); + // return result; + //} + + //Buffer buffer(const Array &header, const Array &data, Allocator &allocator) { + // Buffer result; + // result.len = header.size() + data.size(); + // XENSURE(result.len > 0); + // result.p = (char *)allocator.allocate(result.len); + // memcpy(result.p, header.begin(), header.size()); + // memcpy(result.p + header.size(), data.begin(), data.size()); + // return result; + //} + + //Buffer buffer(const StringStream &os, Allocator &allocator) { + // Buffer result; + // result.p = (char *)allocator.allocate(os.size()); + // result.len = os.size(); + // memcpy(result.p, os.c_str(), os.size()); + // return result; + //} + + //Buffer buffer(MemoryOutputBuffer &ob, Allocator &allocator) { + // Buffer result; + // result.len = (unsigned)ob.position(); + // result.p = (char *)allocator.allocate(result.len); + // ob.read(result.p); + // return result; + //} + + //Buffer copy(Buffer b, Allocator &allocator) + //{ + // Buffer result; + // result.len = b.len; + // result.p = (char *)allocator.allocate(result.len); + // memcpy(result.p, b.p, result.len); + // return result; + //} + + //template Buffer serialize(T &t, Allocator &allocator) { + // MemoryOutputBuffer mob(allocator); + // OutputArchive oa = SharedPtr(mob); + // oa & t; + // return buffer(mob, allocator); + //} + + template Buffer pack(T &t, Allocator &allocator) { + Buffer result; + result.len = sizeof(T); + result.p = (char *)allocator.allocate(result.len); + char *p = result.p; + stream::pack(p, t); + return result; + } +} // namespace buffer + +} // namespace stingray_plugin_foundation diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/collection_tools.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/collection_tools.h new file mode 100644 index 0000000..0fcd8d7 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/collection_tools.h @@ -0,0 +1,16 @@ +#pragma once + +#include "pair.h" +#include "vector" + +namespace stingray_plugin_foundation { + +template +inline void swap_erase(T &v, typename T::iterator it); + +template +inline void swap_erase(T &v, int i); + +} // namespace stingray_plugin_foundation + +#include "collection_tools.inl" diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/collection_tools.inl b/lib/dt_p2p/stingray_sdk/plugin_foundation/collection_tools.inl new file mode 100644 index 0000000..4d56a4a --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/collection_tools.inl @@ -0,0 +1,16 @@ +namespace stingray_plugin_foundation { + +template +inline void swap_erase(T &v, typename T::iterator it) +{ + std::swap(*it, v.back()); + v.pop_back(); +} + +template +inline void swap_erase(T &v, int i) +{ + swap_erase(v, v.begin() + i); +} + +} // namespace stingray_plugin_foundation diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/color.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/color.h new file mode 100644 index 0000000..e863d1e --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/color.h @@ -0,0 +1,23 @@ +#pragma once + +#include "platform.h" + +namespace stingray_plugin_foundation { + +typedef unsigned int Color8; + +__forceinline Color8 color8(unsigned char a, unsigned char r, unsigned char g, unsigned char b) +{ + return (a << 24) | (r << 16) | (g << 8) | b; +} + +__forceinline unsigned char alpha(Color8 c) {return (c >> 24) & 0xff;} +__forceinline unsigned char red(Color8 c) {return (c >> 16) & 0xff;} +__forceinline unsigned char green(Color8 c) {return (c >> 8) & 0xff;} +__forceinline unsigned char blue(Color8 c) {return (c >> 0) & 0xff;} + +struct Color32 { + float r, g, b, a; +}; + +} // namespace stingray_plugin_foundation diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/com_ptr.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/com_ptr.h new file mode 100644 index 0000000..a947313 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/com_ptr.h @@ -0,0 +1,31 @@ +#pragma once + +#if defined(WINDOWSPC) || defined(XBOXONE) + +namespace stingray_plugin_foundation { + +template +class ComPtr { +public: + explicit ComPtr(T* ptr = 0); + ComPtr(const ComPtr& rhs); + ~ComPtr(); + + ComPtr& operator=(const ComPtr& rhs); + T& operator*() const; + T* operator->() const; + T* get() const; + + T* abandon() const; + T** init_ptr(); +private: + T* _ptr; + mutable bool _owned; +}; + +#endif + +} + +#include "com_ptr.inl" + diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/com_ptr.inl b/lib/dt_p2p/stingray_sdk/plugin_foundation/com_ptr.inl new file mode 100644 index 0000000..3914958 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/com_ptr.inl @@ -0,0 +1,66 @@ +namespace stingray_plugin_foundation { + +#if defined(WINDOWSPC) || defined(XBOXONE) + +template +ComPtr::ComPtr(T* ptr = 0) : _owned(true), _ptr(ptr) { + +} + +template +ComPtr::ComPtr(const ComPtr& rhs) : _owned(rhs._owned), _ptr(rhs.abandon()) { + +} + +template +ComPtr::~ComPtr() { + if(_owned && _ptr) { + _ptr->Release(); + } + +} + +template +ComPtr& ComPtr::operator=(const ComPtr& rhs) { + if( this != &rhs ) { + if( _ptr != rhs.get() && _owned && _ptr) + _ptr->Release(); + _owned = rhs._owned; + _ptr = rhs.abandon(); + } + return *this; +} + +template +T& ComPtr::operator*() const { + return *get(); +} + +template +T* ComPtr::operator->() const { + return get(); +} + +template +T* ComPtr::get() const { + return _ptr; +} + +template +T* ComPtr::abandon() const { + _owned=false; + return _ptr; +} + +template +T** ComPtr::init_ptr() { + if(_owned && _ptr) + _ptr->Release(); + _ptr=0; + _owned=true; + return &_ptr; +} + +#endif + +} diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/const_config.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/const_config.h new file mode 100644 index 0000000..034d886 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/const_config.h @@ -0,0 +1,168 @@ +#pragma once + +#include +#include "assert.h" +#include "platform.h" + +// This file is the runtime representation of a config data structure. A config data structure +// is a JSON-like object for representing generic data. This format is suitable when the +// development cost of creating a custom binary format is big and the benefits are small. +// (I.e. for any data that is not massive bulk data -- such as small configuration files.) +// +// The runtime format is essential (type, data) where type is a four-byte type identifier +// and data is four bytes of data. We use four bytes for the type identifier for alignment +// purposes. Note that the runtime format represent an entire config object as a single +// memory block. Local pointers inside the memory block are used to build structure. +// +// Note that it is possible to optimize this format further to squeeze out a few more bytes. + +namespace stingray_plugin_foundation { + +struct ConstConfigArray; +struct ConstConfigObject; + +namespace const_config +{ + // Type used for offset parameters + typedef unsigned offset_t; + + // The supported value types + enum ValueType {NIL, BOOL, INTEGER, FLOAT, STRING, ARRAY, OBJECT}; + + // Generic representation of a value of one of the types. + union Value { + int b; + int i; + float f; + offset_t s; // Offset to char * + offset_t a; // Offset to ConstConfigArray * + offset_t o; // Offset toConstConfigObject * + }; +} + +// Represents the root object (the first item in the memory block). +struct ConstConfigRoot +{ + int type; // ValueType + const_config::Value value; +}; + +// Represents an array. Note that the type is only stored once, all objects in an array +// must have the same type. In the memory layout, the ConstConfigArray block is followed +// by *size* data items (which are bool, int, float, etc) depending on type. +struct ConstConfigArray +{ + int type; // ValueType + int size; + const_config::Value first_item; // size data items follows in memory +}; + +// Represents an entry in a ConstConfigObject. Stores the key (always a string), the +// type of the entry and the value. +struct ConstConfigObjectEntry +{ + const_config::offset_t name; // Offset to name + int type; // ValueType + const_config::Value value; +}; + +// Represents an object. In the memory layout, ConstConfigObject is followed by +// *size* ConstConfigObjectEntry structures that contain the actual objects. +struct ConstConfigObject +{ + int size; + ConstConfigObjectEntry first_entry; +}; + +// Convenience class used to access config data. +class ConstConfigItem +{ +public: + // Creates a nil config item. + ConstConfigItem() : _base(nullptr), _type(const_config::NIL) {} + + // Creates a config item from the specified root. + ConstConfigItem(const ConstConfigRoot &root) : _base((const char *)&root), _type(root.type), _value(root.value) {} + + // Creates a config item with the specified base, type and data. + ConstConfigItem(const char *base, const_config::ValueType t, const_config::Value v) : _base(base), _type(t), _value(v) {} + + bool is_nil() const {return _type == const_config::NIL;} + bool is_bool() const {return _type == const_config::BOOL;} + bool is_false() const {return _type == const_config::BOOL && !_value.b;} + bool is_true() const {return _type == const_config::BOOL && _value.b;} + bool is_integer() const {return _type == const_config::INTEGER;} + bool is_float() const {return _type == const_config::FLOAT;} + bool is_number() const {return is_integer() || is_float();} + bool is_string() const {return _type == const_config::STRING;} + bool is_resource() const { return is_string() || is_object() && (*this)["$resource_name"].is_string(); } + bool is_resource(const char *type) const { return is_resource() && (is_string() || (*this)["$resource_type"].is_string() && strcmp((*this)["$resource_type"].to_string(),type)==0); } + bool is_array() const { return _type == const_config::ARRAY; } + bool is_object() const {return _type == const_config::OBJECT;} + + bool to_bool() const {XENSURE(is_bool()); return _value.b != 0;} + int to_integer() const {XENSURE(is_integer()); return _value.i;} + float to_float() const {return is_float() ? _value.f : float(to_integer());} + const char *to_string() const {XENSURE(is_string()); return raw_s();} + const char *to_resource(const char *type) const { + XENSURE(is_resource(type)); + if (is_string()) { + return to_string(); + } + return (*this)["$resource_name"].to_string(); + } + + bool operator||(bool b) const {return is_bool() ? to_bool() : b;} + int operator||(int i) const {return is_integer() ? _value.i : i;} + unsigned operator||(unsigned i) const {return is_integer() ? unsigned(_value.i) : i;} + float operator||(float f) const {return is_float() ? _value.f : (is_integer() ? _value.i : f);} + const char *operator||(const char *s) const {return is_string() ? raw_s() : s;} + ConstConfigItem operator||(ConstConfigItem o) {return is_nil() ? o : *this;} + + int size() const {return is_array() ? raw_a()->size : 0;} + int n_items() const {return is_object() ? raw_o()->size : 0;} + + ConstConfigItem operator[](int i) const { + if (!is_array()) + return ConstConfigItem(); + if (i<0 || i>=raw_a()->size) + return ConstConfigItem(); + const ConstConfigArray &arr = *raw_a(); + return ConstConfigItem(_base, (const_config::ValueType)arr.type, *(&arr.first_item + i)); + } + + ConstConfigItem operator[](const char *s) const { + if (!is_object()) + return ConstConfigItem(); + const ConstConfigObject &obj = *raw_o(); + for (int i=0; i=obj.size) + return ConstConfigItem(); + + const ConstConfigObjectEntry &e = *(&obj.first_entry + i); + if(s) *s = _base + e.name; + return ConstConfigItem(_base, (const_config::ValueType)e.type, e.value); + } + +private: + const char *raw_s() const {return _base + _value.s;} + const ConstConfigArray *raw_a() const {return (ConstConfigArray *)(_base + _value.a);} + const ConstConfigObject *raw_o() const {return (ConstConfigObject *)(_base + _value.o);} + + const char *_base; // Base for offsets + int _type; // ValueType + const_config::Value _value; +}; + +} // namespace stingray_plugin_foundation diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/encoding.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/encoding.h new file mode 100644 index 0000000..8eba482 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/encoding.h @@ -0,0 +1,84 @@ +#pragma once + +namespace stingray_plugin_foundation { + +template class Array; +class Allocator; + +// Functions for string encoding. +namespace encoding +{ + +// Encodes the unicode character `c` in UTF-8 at the position pointed +// to by `buffer`. `buffer` must have room for at least 5 bytes. +// Returns a pointer to the first character in buffer after the end of +// the encoding. +char *utf8_encode(int codepoint, char *utf8); + +// Decodes the UTF-8 character at the start of `buffer` into a unicode +// code point and returns it in `res`. Returns a pointer to the first +// character in the buffer after the UTF-8 character that was just +// consumed. +const char *utf8_decode(const char *utf8, int &codepoint); + +// Returns the number of bytes used by the UTF-8 codepoint pointed to by +// buffer. Advance by this amount to get to the next code point. +unsigned utf8_codepoint_bytes(const char *utf8); + +// Decodes an UTF-8 string to a vector of codepoints. +void utf8_decode(const char *utf8, Array &codepoints); + +// Encode a vector of codepoints to an array of UTF-8 characters. +void utf8_encode(const Array &codepoints, Array &utf8); +// Encode an array of codepoints to an array of UTF-8 characters. +void utf8_encode(const unsigned *codepoints, unsigned size, Array &utf8); + +// Determines the begin and end position of the utf8 codepoint at +// `utf8`[index]. `end` is an index pointing to the byte after the +// utf-8 codepoint. +void utf8_location(const char *utf8, unsigned index, unsigned &begin, unsigned &end); + +// Returns a pointer to the next character if the character at utf8 is valid, otherwise +// returns nullptr. +const char *utf8_valid_first(const char *utf8); + +// Returns true if the string utf8 contains only valid UTF-8 code points and +// false otherwise. +bool utf8_valid_all(const char *utf8); + +// Returns the number of of bytes needed to store the UCS-2 encoded wchar_t * +// as an UTF-8 value, including the zero byte at the end of the UTF-8 string. +unsigned wstr_to_utf8_bytes(const wchar_t *ucs2); + +// Converts an UCS-2 encoded w_char * to an UTF-8 encoded char *. +// `size` specifies the size of the buffer. If the conversion requires +// more than `size` bytes, an assert is thrown. +void wstr_to_utf8(const wchar_t *ucs2, char *utf8, unsigned size); + +// Converts an UCS-2 encoded w_char * to an UTF-8 encoded char *, +// allocating memory as necessary. +void wstr_to_utf8(const wchar_t *ucs2, Array &utf8); + +// Returns the number of of tokens needed to store the UTF-8 encoded char * +// as an UCS-2 value, including the zero token at the end of the UCS-2 string. +unsigned utf8_to_wstr_tokens(const char *utf8); + +// Converts an UTF-8 encoded char * to an UCS-2 encoded wchar_t *. +// `tokens` specifies the number of tokens in the buffer. If the +// converted string contains more tokens, an assert is thrown. +void utf8_to_wstr(const char *utf8, wchar_t *ucs2, unsigned tokens); + +// Converts an UTF-8 encoded char * to an UCS-2 encoded wchar_t *, +// allocating memory as necessary. +void utf8_to_wstr(const char *utf8, Array &ucs2); + +// Converts an UTF-8 encoded char * to an UCS-2 encoded wchar_t *, +// allocated using the specified allocator. +wchar_t *utf8_to_wstr(const char *utf8, Allocator &a); + + +} // namespace encoding + +} // namespace stingray_plugin_foundation + +#include "encoding.inl" diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/encoding.inl b/lib/dt_p2p/stingray_sdk/plugin_foundation/encoding.inl new file mode 100644 index 0000000..19610c8 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/encoding.inl @@ -0,0 +1,211 @@ +#include "assert.h" +#include "array.h" +#include +#include + +namespace stingray_plugin_foundation { + +inline char *encoding::utf8_encode(int c, char *utf8) +{ + if (c<0x80) { + *utf8 = c; + return utf8 + 1; + } else if (c<0x800) { + utf8[0] = (c>>6)|0xC0; + utf8[1] = (c&0x3F)|0x80; + return utf8 + 2; + } else if (c<0x10000) { + utf8[0] = (c>>12)|0xE0; + utf8[1] = ((c>>6)&0x3F)|0x80; + utf8[2] = (c&0x3F)|0x80; + return utf8 + 3; + } else if (c<0x110000) { + utf8[0] = (c>>18)|0xf0; + utf8[1] = ((c>>12)&0x3F)|0x80; + utf8[2] = ((c>>6)&0x3F)|0x80; + utf8[3] = (c&0x3F)|0x80; + return utf8 + 4; + } else { + XERROR("Cannot encode character"); + } + return utf8; +} + +inline const char *encoding::utf8_decode(const char *utf8, int &codepoint) +{ + char c = *utf8; + if ((c&0x80)==0x0) { + codepoint = c; + return utf8 + 1; + } else if ((c&0xE0)==0xC0) { + unsigned char d = utf8[1]; + XASSERT((d&0xC0)==0x80, "Archive not utf-8 encoded %s", utf8); + codepoint = (static_cast(c&0x1F)<<6) | static_cast(d&0x3F); + return utf8 + 2; + } else if ((c&0xF0)==0xE0) { + const char *d = utf8 + 1; + XASSERT(((d[0]&0xC0)==0x80) && ((d[1]&0xC0)==0x80), "Archive not utf-8 encoded %s", utf8); + codepoint = (static_cast(c&0x0f)<<12) | (static_cast(d[0]&0x3f)<<6) | + static_cast(d[1]&0x3f); + return utf8 + 3; + } else if ((c&0xf8)==0xf0) { + const char *d = utf8 + 1; + XASSERT(((d[0]&0xc0)==0x80) && ((d[1]&0xc0)==0x80) && + ((d[2]&0xc0)==0x80), "Archive not utf-8 encoded %s", utf8); + codepoint = (static_cast(c&0x07)<<18) | (static_cast(d[0]&0x3f)<<12) | + (static_cast(d[1]&0x3f)<<6) | static_cast(d[2]&0x3f); + return utf8 + 4; + } else { + XERROR("Archive not utf-8 encoded %s", utf8); + return utf8; + } +} + +inline unsigned encoding::utf8_codepoint_bytes(const char *buffer) +{ + char c = *buffer; + if ((c&0x80)==0x0) + return 1; + else if ((c&0xE0)==0xC0) + return 2; + else if ((c&0xF0)==0xE0) + return 3; + else if ((c&0xf8)==0xf0) + return 4; + else { + XERROR("Length on part of utf-8 character"); + return 1; + } +} + +inline void encoding::utf8_decode(const char *utf8, Array &codepoints) +{ + while (*utf8) { + int c; + utf8 = utf8_decode(utf8, c); + codepoints.push_back((unsigned)c); + } +} + +inline void encoding::utf8_encode(const Array &codepoints, Array &utf8) +{ + utf8_encode(codepoints.begin(), codepoints.size(), utf8); +} + +inline void encoding::utf8_encode(const unsigned *codepoints, unsigned size, Array &utf8) +{ + const unsigned *it(codepoints), *end(codepoints + size); + for(; it != end; ++it) { + utf8.reserve(utf8.size() + 4); + const char *new_ptr = utf8_encode(*it, utf8.end()); + utf8.resize((unsigned)(new_ptr - utf8.begin())); + } +} + +inline void encoding::utf8_location(const char *utf8, unsigned index, unsigned &begin, unsigned &end) +{ + XASSERT(index < strlen(utf8), "Index out of string"); + // walk backwards to find beginning of utf8 character + begin = index; + while(true) { + if (begin == 0) + break; + if ((utf8[begin] & 0xc0) != 0x80) + break; + --begin; + } + end = begin + utf8_codepoint_bytes(utf8 + begin); +} + +inline const char * encoding::utf8_valid_first(const char *utf8) +{ + char c = *utf8; + const char *d = utf8 + 1; + + if ((c&0x80)==0x0) return utf8 + 1; + else if ((c&0xE0)==0xC0) return (d[0]&0xC0)==0x80 ? utf8+2 : nullptr; + else if ((c&0xF0)==0xE0) return (d[0]&0xC0)==0x80 && (d[1]&0xC0)==0x80 ? utf8+3 : nullptr; + else if ((c&0xf8)==0xf0) return (d[0]&0xc0)==0x80 && (d[1]&0xc0)==0x80 && (d[2]&0xc0)==0x80 ? utf8+4 : nullptr; + else return nullptr; +} + +inline bool encoding::utf8_valid_all(const char *utf8) +{ + while (*utf8) { + utf8 = utf8_valid_first(utf8); + if (!utf8) + return false; + } + return true; +} + +inline unsigned encoding::wstr_to_utf8_bytes(const wchar_t *ucs2) +{ + char buffer[5]; + unsigned size = 0; + while (*ucs2) { + size += (unsigned)(utf8_encode(*ucs2, &buffer[0]) - &buffer[0]); + ++ucs2; + } + ++size; + return size; +} + +inline void encoding::wstr_to_utf8(const wchar_t *ucs2, char *utf8, unsigned size) +{ + char *b = utf8; + while (*ucs2) { + b = utf8_encode(*ucs2, b); + ++ucs2; + } + XENSURE(unsigned(b - utf8) < size); + *b = 0; +} + +inline void encoding::wstr_to_utf8(const wchar_t *ucs2, Array &utf8) +{ + unsigned n = wstr_to_utf8_bytes(ucs2); + utf8.resize(n); + wstr_to_utf8(ucs2, utf8.begin(), n); +} + +inline unsigned encoding::utf8_to_wstr_tokens(const char *utf8) +{ + unsigned tokens = 0; + while (*utf8) { + ++tokens; + utf8 += utf8_codepoint_bytes(utf8); + } + ++tokens; + return tokens; +} + +inline void encoding::utf8_to_wstr(const char *utf8, wchar_t *ucs2, unsigned tokens) +{ + wchar_t *b = ucs2; + while (*utf8) { + int c; + utf8 = utf8_decode(utf8, c); + *b = c; + ++b; + } + XENSURE(unsigned(b - ucs2) < tokens); + *b = 0; +} + +inline void encoding::utf8_to_wstr(const char *utf8, Array &ucs2) +{ + unsigned n = utf8_to_wstr_tokens(utf8); + ucs2.resize(n); + utf8_to_wstr(utf8, ucs2.begin(), n); +} + +inline wchar_t *encoding::utf8_to_wstr(const char *utf8, Allocator &a) +{ + unsigned n = utf8_to_wstr_tokens(utf8); + wchar_t *res = (wchar_t *)a.allocate(sizeof(wchar_t)*n); + utf8_to_wstr(utf8, res, n); + return res; +} + +} // namespace stingray_plugin_foundation diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/exception_handling.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/exception_handling.h new file mode 100644 index 0000000..07d3db9 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/exception_handling.h @@ -0,0 +1,33 @@ +#pragma once + +#if (defined(WINDOWSPC) || defined(XBOXONE)) && defined(DEVELOPMENT) + + #include + + namespace stingray_plugin_foundation { + + // Disable FPU exceptions in scope and restore on exit. + struct FpuUnsafeScope { + unsigned _initial_control_word; + + FpuUnsafeScope() { + _initial_control_word = _controlfp(0,0); + _controlfp(~0U, _MCW_EM); + } + + ~FpuUnsafeScope() { + _clearfp(); + _controlfp(_initial_control_word, _MCW_EM); + } + }; + } +#else + namespace stingray_plugin_foundation { + + struct FpuUnsafeScope { + FpuUnsafeScope() {} + ~FpuUnsafeScope() {} + }; + + } +#endif diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/flow.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/flow.h new file mode 100644 index 0000000..6fa5d74 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/flow.h @@ -0,0 +1,51 @@ +#pragma once + +#include "../engine_plugin_api/plugin_api.h" +#include "id_string.h" + +namespace stingray_plugin_foundation { + + inline const char *get_c_string(const FlowString& flow_string) + { + XENSURE(flow_string.is_id64 == 0); + return flow_string.plain; + } + + inline void set_c_string(FlowString& flow_string, const char *string) + { + flow_string.is_id64 = 0; + if (string == nullptr) + flow_string.plain[0] = 0; + strncpy(flow_string.plain, string, PLUGIN_FLOW_STRING_VARIABLE_LENGTH); + } + + inline IdString64 get_id64(const FlowId* flow_id) + { + if (flow_id == nullptr) + return IdString64(); + + if (flow_id->is_id64 == 0) + return IdString64(((const FlowString*)flow_id)->plain); + + return IdString64(flow_id->id); + } + + inline const char *get_c_string(const FlowId* flow_id) + { + if (flow_id == nullptr) + return nullptr; + + if (flow_id->is_id64 == 0) + return ((const FlowString*)flow_id)->plain; + + return IdString64(flow_id->id).to_string(); + } + + inline void set_id64(FlowId& flow_id, IdString64 id) + { + flow_id.is_id64 = 1; + flow_id.id = id.id(); + } + + +} // namespace stingray_plugin_foundation diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/functional.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/functional.h new file mode 100644 index 0000000..cd081ed --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/functional.h @@ -0,0 +1,17 @@ +#pragma once + +namespace stingray_plugin_foundation { + +struct less +{ + template bool operator()(const A& a, const B& b) const {return (a < b);} + void swap(less &other) {} +}; + +struct equal_to +{ + template bool operator()(const A& a, const B& b) const {return (a == b);} + void swap(less &other) {} +}; + +} // namespace stingray_plugin_foundation diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/hash_function.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/hash_function.h new file mode 100644 index 0000000..b1318b1 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/hash_function.h @@ -0,0 +1,192 @@ +#pragma once + +#include +#include + +namespace stingray_plugin_foundation { + +// Implementation of the 64 bit murmur hash function +// http://murmurhash.googlepages.com/ +inline uint64_t murmur_hash_64(const void * key, int len, uint64_t seed) +{ + const uint64_t m = 0xc6a4a7935bd1e995ULL; + const int r = 47; + + uint64_t h = seed ^ (len * m); + + const uint64_t * data = (const uint64_t *)key; + const uint64_t * end = data + (len/8); + + while(data != end) + { + #if defined(ANDROID) || defined(IOS) || defined(WEB) // Unaligned 64bit reads not supported! + uint64_t k; + char *p = (char *)&k, *d = (char *)data; + p[0] = d[0]; p[1] = d[1]; p[2] = d[2]; p[3] = d[3]; + p[4] = d[4]; p[5] = d[5]; p[6] = d[6]; p[7] = d[7]; + data++; + #elif defined(WINDOWSPC) || defined(UWP) || defined(XBOXONE) || defined(__ORBIS__) || defined(MACOSX) || defined(LINUXPC) + uint64_t k = *data++; + #else + #error Unaligned 64bit reads undefined! + #endif + + k *= m; + k ^= k >> r; + k *= m; + + h ^= k; + h *= m; + } + + const unsigned char * data2 = (const unsigned char*)data; + + switch(len & 7) + { + case 7: h ^= uint64_t(data2[6]) << 48; + case 6: h ^= uint64_t(data2[5]) << 40; + case 5: h ^= uint64_t(data2[4]) << 32; + case 4: h ^= uint64_t(data2[3]) << 24; + case 3: h ^= uint64_t(data2[2]) << 16; + case 2: h ^= uint64_t(data2[1]) << 8; + case 1: h ^= uint64_t(data2[0]); + h *= m; + }; + + h ^= h >> r; + h *= m; + h ^= h >> r; + + return h; +} + +inline uint64_t hash64(const char *s) +{ + return murmur_hash_64(s, int(strlen(s)), 0); +} + +inline unsigned hash32(const char *s) +{ + uint64_t id64 = murmur_hash_64(s, int(strlen(s)), 0); + return unsigned(id64 >> 32); +} + +inline unsigned hash32(const void * key, int len) +{ + uint64_t id64 = murmur_hash_64(key, len, 0); + return unsigned(id64 >> 32); +} + +// A quick hash for four byte sized values based on a single +// iteration of the murmur hash function. +// +// Another option would be to convert the bit pattern directly to +// an int. That would be faster, but might lead to clustering if +// the input values do not distribute evenly. +inline unsigned int four_byte_hash(const void * key) +{ + const unsigned int m = 0x5bd1e995; + const int r = 24; + unsigned int k = *(unsigned int *)key; + + k *= m; + k ^= k >> r; + k *= m; + return k; +} + +inline uint64_t eight_byte_hash_64(const void * key) +{ + const uint64_t m = 0xc6a4a7935bd1e995ULL; + const int r = 47; + uint64_t k = *(const uint64_t *)key; + + k *= m; + k ^= k >> r; + k *= m; + return k; +} + +// Default hashing for builtin-types. +template struct default_hash +{ + static constexpr bool value = false; + unsigned operator()(T t) const { static_assert(value, "default_hash not implemented for this type!"); return 0; } +}; + +template struct default_hash +{ + unsigned operator()(T *t) const + { + #ifdef PLATFORM_64BIT + return (unsigned)eight_byte_hash_64(&t); + #else + return four_byte_hash(&t); + #endif + } +}; + +template struct default_hash +{ + unsigned operator()(const T *t) const + { + #ifdef PLATFORM_64BIT + return (unsigned)eight_byte_hash_64(&t); + #else + return four_byte_hash(&t); + #endif + } +}; + +template <> struct default_hash +{ + unsigned operator()(unsigned t) const { return four_byte_hash(&t); } +}; + +template <> struct default_hash +{ + unsigned operator()(int t) const { return four_byte_hash(&t); } +}; + +template <> struct default_hash +{ + unsigned operator()(uint64_t t) const { return hash32(&t, sizeof(t)); } +}; + +template <> struct default_hash +{ + unsigned operator()(int64_t t) const { return hash32(&t, sizeof(t)); } +}; + +// Utility functions +inline uint64_t mix(uint64_t h, uint64_t k) +{ + const uint64_t m = 0xc6a4a7935bd1e995ULL; + const int r = 47; + + k *= m; + k ^= k >> r; + k *= m; + + h ^= k; + h *= m; + + return h; +} + +inline unsigned mix(unsigned h, unsigned k) +{ + const unsigned int m = 0x5bd1e995; + const int r = 24; + + k *= m; + k ^= k >> r; + k *= m; + + h *= m; + h ^= k; + + return h; +} + +} // namespace stingray_plugin_foundation diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/hash_function_string.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/hash_function_string.h new file mode 100644 index 0000000..fc707b1 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/hash_function_string.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include +#include "string.h" +#include "hash_function.h" + +namespace stingray_plugin_foundation { + +struct string_hash +{ + unsigned operator()(const char *t) const {return hash32(t);} + unsigned operator()(const ConstString &t) const {return hash32(t.c_str(), t.size());} + unsigned operator()(const DynamicString &t) const {return hash32(t.c_str(), t.size());} +}; + +struct string_hash64 +{ + uint64_t operator()(const char *t) const {return murmur_hash_64(t, strlen32(t),0);} + uint64_t operator()(const ConstString &t) const {return murmur_hash_64(t.c_str(), t.size(),0);} + uint64_t operator()(const DynamicString &t) const {return murmur_hash_64(t.c_str(), t.size(),0);} +}; + +} // namespace stingray_plugin_foundation diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/hash_map.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/hash_map.h new file mode 100644 index 0000000..cf4fb71 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/hash_map.h @@ -0,0 +1,145 @@ +#pragma once + +#include "hash_function.h" +#include "pair.h" +#include "bucket_iterator.h" +#include "vector.h" +#include "functional.h" + +namespace stingray_plugin_foundation { + +// Implements an unordered map using a hash table. +// +// The hash table allocates its memory in a single block to be as cache +// friendly as possible. Hash collisions are resolved by chaining into +// a separate region of that memory block. This avoids clustering while +// also avoiding the cache inefficiency of linked lists. +// +// A lookup in the spillover area will likely lead to a cache miss, so +// from a cache perspective linear probing might be more efficient. +// OTOH linear probing has a tendency to cause clustering which can +// heavily degrade performance. It also complicates hash table deletes. +// +// For a randomly distributed hash function, a lookup in this hash table +// on average has too look at 1.3 nodes. The expected memory use is +// +// $ 1.37 n (K_s D_s + 4) $, +// +// where `n` is the number of elements and `K_s` is the size of +// the key elements and `D_s` is the size of the data elements. The +// spillover region is set to 37 % of the hash region size. Experimentally +// this has been found to be a good trade off value. +// +// HashMap is a good choice when you need to insert and lookup continuously +// (so you can't use SortMap) and you don't need to do an ordered traversal +// of the items. +// \tparam K the key type +// \tparam D the data type +// \tparam HASH hash functor, defaults to default_hash> +// \tparam EQUAL equality functor, defaults to std::equal_to +template , class EQUAL = equal_to > +class HashMap +{ +public: + ALLOCATOR_AWARE; + + typedef K key_type; + typedef D data_type; + typedef HASH key_hash; + typedef EQUAL key_equal; + typedef HashMap this_type; + typedef Pair value_type; + + // Special values for marker + enum {END_OF_LIST = 0x7fffffff, UNUSED = 0xfffffffe, END_OF_FREELIST = 0xffffffff}; + + typedef BucketIterator iterator; + typedef ConstBucketIterator const_iterator; + + HashMap(Allocator &a); + // Creates an unordered map presized to the specified number of buckets and + // spill-over buckets. It is recommended that spill = 0.37 * buckets. + HashMap(unsigned buckets, unsigned spill, Allocator &a); + HashMap(const HashMap &o); + ~HashMap(); + + void operator=(const HashMap &o); + void swap(HashMap &o); + + iterator begin(); + iterator end(); + const_iterator begin() const; + const_iterator end() const; + + template const_iterator find(const KEY_EQ &k) const; + template iterator find(const KEY_EQ &k); + + Allocator & allocator() const; + + void reserve(unsigned size); + unsigned size() const; + bool empty() const; + + // Returns true if the key is in the hash + template bool has(const KEY_EQ &k) const; + template data_type &operator[](const KEY_EQ &k); + template value_type &get_pair(const KEY_EQ &k); + template const data_type &operator[](const KEY_EQ &k) const; + // Returns the value for `k` if it exists and `def` otherwise. + template data_type &get(const KEY_EQ &k, data_type &def); + template const data_type &get(const KEY_EQ &k, const data_type &def) const; + void clear(); + // Inserts the data point (`k`, `v`) in the map. + template void insert(const KEY_EQ &k, const DATA_EQ &v); + template void erase(const KEY_EQ &k); + + // Rehashes the data to the specified number of buckets (and a spill + // region of 0.37 * buckets). + // You can use this to reserve memory in the hash before inserting a lot + // of elements to avoid rehashing during insertion. You can also use it + // to shrink a hash, but you cannot shrink a hash beyond its current size. + void rehash(unsigned new_buckets); + + // Used by iterator + unsigned num_buckets() const; + bool bucket_valid(unsigned i) const; + value_type &bucket_value(unsigned i); + const value_type &bucket_value(unsigned i) const; + + // Serializes the hash map to the stream. + template void serialize(STREAM &stream); + +private: + template unsigned find_or_fail(const KEY_EQ &k) const; + template unsigned find_or_make(const KEY_EQ &k); + template void find_and_erase(const KEY_EQ &k); + bool full() const; + void grow(); + template unsigned hash(const KEY_EQ &k) const; + unsigned allocate_spill(); + void free_spill(unsigned i); + void clear_freelist(); + void allocate_data(unsigned count); + void construct(value_type &p) { new (&p) value_type(_allocator); } + void destruct(value_type &p) { p.~value_type(); } + + struct Data { + Data() : size(), marker(), value() {} + unsigned size; + unsigned *marker; + value_type *value; + }; + + key_hash _hash; + key_equal _equal; + Data _data; + unsigned _used; + unsigned _buckets; + unsigned _spill_unused; + unsigned _spill_freelist; + Allocator &_allocator; +}; + +} // namespace stingray_plugin_foundation + +#include "hash_map.inl" diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/hash_map.inl b/lib/dt_p2p/stingray_sdk/plugin_foundation/hash_map.inl new file mode 100644 index 0000000..7b703bd --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/hash_map.inl @@ -0,0 +1,518 @@ +namespace stingray_plugin_foundation { + + +template +HashMap::HashMap(Allocator &a) : _data(), _used(0), _buckets(0), + _spill_unused(0), _spill_freelist(END_OF_FREELIST), _allocator(a) +{ +} + +template +HashMap::HashMap(unsigned buckets, unsigned spill, Allocator &a) : + _data(), _used(0), _buckets(buckets), _spill_unused(spill), _spill_freelist(END_OF_FREELIST) + , _allocator(a) +{ + allocate_data(buckets + spill); + for (unsigned i=0; i<_data.size; ++i) + _data.marker[i] = UNUSED; +} + +template +HashMap::HashMap(const HashMap &o) : + _hash(o._hash), _equal(o._equal), + _data(), _used(o._used), _buckets(o._buckets), + _spill_unused(o._spill_unused), _spill_freelist(o._spill_freelist), + _allocator(o._allocator) +{ + allocate_data(o._data.size); + for (unsigned i = 0; i < _data.size; ++i) { + if (o._data.marker[i] != UNUSED && (o._data.marker[i] & 0x80000000) == 0) { + construct(_data.value[i]); + _data.value[i] = o._data.value[i]; + } + _data.marker[i] = o._data.marker[i]; + } +} + +template +void HashMap::operator=(const HashMap &o) +{ + if (this == &o) + return; + clear(); + _hash = o._hash; + _equal = o._equal; + _allocator.deallocate(_data.marker); + _data.marker = nullptr; + allocate_data(o._data.size); + for (unsigned i = 0; i < _data.size; ++i) { + if (o._data.marker[i] != UNUSED && (o._data.marker[i] & 0x80000000) == 0) { + construct(_data.value[i]); + _data.value[i] = o._data.value[i]; + } + _data.marker[i] = o._data.marker[i]; + } + _used = o._used; + _buckets = o._buckets; + _spill_unused = o._spill_unused; + _spill_freelist = o._spill_freelist; +} + +template +HashMap::~HashMap() +{ + clear(); + _allocator.deallocate(_data.marker); +} + +template +void HashMap::swap(HashMap &o) +{ + XENSURE(&_allocator == &o._allocator); + std::swap(_hash, o._hash); + std::swap(_equal, o._equal); + std::swap(_data.size, o._data.size); + std::swap(_data.marker, o._data.marker); + std::swap(_data.value, o._data.value); + std::swap(_used, o._used); + std::swap(_buckets, o._buckets); + std::swap(_spill_unused, o._spill_unused); + std::swap(_spill_freelist, o._spill_freelist); +} + +template +typename HashMap::iterator HashMap::begin() +{ + return iterator(*this, 0); +} + +template +typename HashMap::iterator HashMap::end() +{ + return iterator(*this, num_buckets()); +} + +template +typename HashMap::const_iterator HashMap::begin() const +{ + return const_iterator(*this, 0); +} + +template +typename HashMap::const_iterator HashMap::end() const +{ + return const_iterator(*this, num_buckets()); +} + +template template +typename HashMap::const_iterator HashMap::find(const KEY_EQ &k) const{ + auto i = find_or_fail(k); + return (i == END_OF_LIST) ? end() : const_iterator(*this, i); +} + +template template +typename HashMap::iterator HashMap::find(const KEY_EQ &k){ + auto i = find_or_fail(k); + return (i == END_OF_LIST) ? end() : iterator(*this, i); +} + +template +Allocator & HashMap::allocator() const +{ + return _allocator; +} + +template +unsigned HashMap::size() const +{ + return _used; +} + +template +bool HashMap::empty() const +{ + return _used == 0; +} + +template template +bool HashMap::has(const KEY_EQ &k) const +{ + return find_or_fail(k) != END_OF_LIST; +} + +template template +typename HashMap::data_type &HashMap::operator[](const KEY_EQ &k) +{ + if (full()) { + unsigned i = find_or_fail(k); + if (i != END_OF_LIST) + return _data.value[i].second; + grow(); + } + return _data.value[find_or_make(k)].second; +} + +template template +typename HashMap::value_type &HashMap::get_pair(const KEY_EQ &k) +{ + if (full()) { + unsigned i = find_or_fail(k); + if (i != END_OF_LIST) + return _data.value[i]; + grow(); + } + return _data.value[find_or_make(k)]; +} + +template template +const typename HashMap::data_type &HashMap::operator[](const KEY_EQ &k) const +{ + unsigned i = find_or_fail(k); + XASSERT(i != END_OF_LIST, "key not in map"); + return _data.value[i].second; +} + +template template +typename HashMap::data_type &HashMap::get(const KEY_EQ &k, data_type &def) +{ + unsigned i = find_or_fail(k); + if (i == END_OF_LIST) + return def; + else + return _data.value[i].second; +} + +template template +const typename HashMap::data_type &HashMap::get(const KEY_EQ &k, const data_type &def) const +{ + unsigned i = find_or_fail(k); + if (i == END_OF_LIST) + return def; + else + return _data.value[i].second; +} + +template +void HashMap::clear() +{ + _used = 0; + _spill_freelist = END_OF_FREELIST; + _spill_unused = _data.size - _buckets; + for (unsigned i=0; i<_data.size; ++i) { + if (bucket_valid(i)) + destruct(_data.value[i]); + _data.marker[i] = UNUSED; + } +} + +template template +void HashMap::insert(const KEY_EQ &k, const DATA_EQ &v) +{ + (*this)[k] = v; +} + +template template +void HashMap::erase(const KEY_EQ &k) +{ + find_and_erase(k); +} + +template +void HashMap::rehash(unsigned new_buckets) +{ + XENSURE(new_buckets >= _used); + clear_freelist(); + unsigned spill = int(new_buckets * 0.37f + 1); + unsigned old_size = _data.size; + if (_data.size == 0) { + allocate_data(new_buckets + spill); + _buckets = new_buckets; + _spill_unused = spill; + for (unsigned i = 0; i<_data.size; ++i) + _data.marker[i] = UNUSED; + return; + } + this_type new_hash(new_buckets, spill, _allocator); + for (unsigned o=0; o +void HashMap::reserve(unsigned items) +{ + unsigned buckets = int(items * 1.37f); + if (buckets < 26) + buckets = 26; + rehash(buckets); +} + +template +unsigned HashMap::num_buckets() const +{ + return _data.size; +} + +template +bool HashMap::bucket_valid(unsigned i) const +{ + return (_data.marker[i] & 0x80000000) == 0; +} + +template +typename HashMap::value_type &HashMap::bucket_value(unsigned i) +{ + return _data.value[i]; +} + +template +const typename HashMap::value_type &HashMap::bucket_value(unsigned i) const +{ + return _data.value[i]; +} + +// Searches for `k` in the map. Returns the index of the entry if found and +// END_OF_LIST if not found. +template template +unsigned HashMap::find_or_fail(const KEY_EQ &k) const +{ + // Is hash empty? + if (empty()) + return END_OF_LIST; + + unsigned i = hash(k); + + // Is primary slot unused? + if (_data.marker[i] == UNUSED) + return END_OF_LIST; + + // Walk the hash chain until key matches or end is reached. + while (true) { + if (i == END_OF_LIST || _equal(k, _data.value[i].first)) + return i; + i = _data.marker[i]; + } +} + +// Searches for `k` in the map. Returns the index if it is found. If it is +// not found a new hash slot is create for `k` and its index is returned. +template template +unsigned HashMap::find_or_make(const KEY_EQ &k) +{ + unsigned i = hash(k); + + // Is primary slot unused? + if (_data.marker[i] == UNUSED) { + ++_used; + construct(_data.value[i]); + _data.value[i].first = k; + _data.marker[i] = END_OF_LIST; + return i; + } + + while (true) { + // Walk the hash chain until found + if (_equal(k, _data.value[i].first) ) + return i; + + // Or until end of hash chain, in which case we add a new entry + // to the end. + if (_data.marker[i] == END_OF_LIST) { + unsigned j = allocate_spill(); + _data.marker[i] = j; + i = j; + construct(_data.value[i]); + _data.value[i].first = k; + _data.marker[i] = END_OF_LIST; + return i; + } + + i = _data.marker[i]; + } +} + +// Searches for `k` in the map. If it is found, it is erased. +template template +void HashMap::find_and_erase(const KEY_EQ &k) +{ + // early out to avoid division by zero in hash method if the map is empty. + if (_buckets == 0) + return; + + unsigned i = hash(k); + + // Is primary slot unused? + if (_data.marker[i] == UNUSED) + return; + + // Did the primary slot match? + if (_equal(k, _data.value[i].first)) { + // If there is no chain, just return the primary value + if (_data.marker[i] == END_OF_LIST) { + _data.marker[i] = UNUSED; + destruct(_data.value[i]); + --_used; + // If there is a chain, bring in the first value from the + // chain and mark it as free in the spillover region. + } else { + unsigned del = _data.marker[i]; + _data.marker[i] = _data.marker[del]; + _data.value[i] = _data.value[del]; + destruct(_data.value[del]); + free_spill(del); + } + return; + } + + // If not, search the hash chain for a match + unsigned prev = i; + while (true) { + // If there is a match remove that value from the chain and + // mark it as free in the spillover region. + if (_equal(k, _data.value[i].first) ) { + _data.marker[prev] = _data.marker[i]; + destruct(_data.value[i]); + free_spill(i); + return; + } + + // If end of chain was reached without finding the key just return + if (_data.marker[i] == END_OF_LIST) + return; + + prev = i; + i = _data.marker[i]; + } +} + +template +bool HashMap::full() const +{ + // Hash map is full when spillover region is full + return _spill_unused == 0 && _spill_freelist == END_OF_FREELIST; +} + +template +void HashMap::grow() +{ + do { + unsigned new_buckets = _buckets * 2 + 1; + if (new_buckets < 19) + new_buckets = 19; + rehash(new_buckets); + } while (full()); +} + +template template +unsigned HashMap::hash(const KEY_EQ &k) const +{ + XENSURE(_buckets > 0); + + return _hash(k) % _buckets; +} + +// Allocate a slot in the spillover region and return it. +template +unsigned HashMap::allocate_spill() +{ + ++_used; + + // If there spillover free list is non-empty, use its + // first item. + if (_spill_freelist != END_OF_FREELIST) { + unsigned i = _spill_freelist & 0x7fffffff; + _spill_freelist = _data.marker[i]; + return i; + } + + // Return the first unused item from the spillover region. + XENSURE(_spill_unused > 0); + unsigned i = _data.size - _spill_unused; + --_spill_unused; + _data.marker[i] = UNUSED; + return i; +} + +template +void HashMap::free_spill(unsigned i) +{ + // Free a spillover item by inserting it in the freelist. + --_used; + _data.marker[i] = _spill_freelist; + _spill_freelist = i | 0x80000000; +} + +// Clears the spillover freelist (marks all items as unused). +template +void HashMap::clear_freelist() +{ + while (_spill_freelist != END_OF_FREELIST) { + unsigned i = _spill_freelist & 0x7fffffff; + _spill_freelist = _data.marker[i]; + _data.marker[i] = UNUSED; + } +} + +template +void HashMap::allocate_data(unsigned count) +{ + XASSERT(_data.marker == nullptr, "Data must be deallocated/cleared before allocating new data"); + if (count == 0) { + _data = Data(); + return; + } + + auto marker_size = (((sizeof(unsigned) * count) + sizeof(void*) - 1) / sizeof(void*)) * sizeof(void*); + auto value_size = sizeof(value_type) * count; + auto data_size = marker_size + value_size; + _data.marker = (unsigned*)_allocator.allocate(data_size); + _data.value = (value_type*)&(((char*)_data.marker)[marker_size]); + _data.size = count; +} + +template +template void HashMap::serialize(STREAM &stream) +{ + unsigned n = size(); + stream & n; + if (stream.is_output()) { + iterator it(this->begin()); + iterator end(this->end()); + for (; it != end; ++it) + stream & (*it); + } else { + reserve(n); + for (unsigned i=0; i, class EQUAL = equal_to > +class HashSet +{ +public: + ALLOCATOR_AWARE; + + typedef K key_type; + typedef HASH key_hash; + typedef EQUAL key_equal; + typedef HashSet this_type; + + typedef ConstBucketIterator const_iterator; + typedef BucketIterator iterator; + + enum {END_OF_LIST = 0x7fffffff, UNUSED = 0xfffffffe, END_OF_FREELIST = 0xffffffff}; + + HashSet(Allocator &a); + HashSet(unsigned buckets, unsigned spill, Allocator &a); + HashSet(const HashSet &o); + ~HashSet(); + void operator=(const HashSet &o); + + void reserve(unsigned size); + + void swap(HashSet &o); + Allocator & allocator() const; + unsigned size() const; + bool empty() const; + + template bool has(const KEY_EQ &k) const; + void clear(); + template void insert(const KEY_EQ &k); + template void erase(const KEY_EQ &k); + void rehash(unsigned new_buckets); + + const_iterator begin() const; + const_iterator end() const; + + unsigned num_buckets() const; + bool bucket_valid(unsigned i) const; + const key_type &bucket_value(unsigned i) const; + key_type &bucket_value(unsigned i); + + template void serialize(STREAM &stream); + +private: + template unsigned find_or_fail(const KEY_EQ &k) const; + template unsigned find_or_make(const KEY_EQ &k); + template void find_and_erase(const KEY_EQ &k); + bool full() const; + void grow(); + template unsigned hash(const KEY_EQ &k) const; + unsigned allocate_spill(); + void free_spill(unsigned i); + void clear_freelist(); + void allocate_data(unsigned count); + void construct(key_type &p, const Int2Type &) { new (&p) key_type(_allocator); } + void construct(key_type &p, const Int2Type &) { new (&p) key_type(); } + void destruct(key_type &p) { p.~key_type(); } + + struct Data { + Data() : size(), marker(), key() {} + unsigned size; + unsigned *marker; + key_type *key; + }; + + key_hash _hash; + key_equal _equal; + Data _data; + unsigned _used; + unsigned _buckets; + unsigned _spill_unused; + unsigned _spill_freelist; + Allocator &_allocator; +}; + +} // namespace stingray_plugin_foundation + +#include "hash_set.inl" diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/hash_set.inl b/lib/dt_p2p/stingray_sdk/plugin_foundation/hash_set.inl new file mode 100644 index 0000000..a1b7c31 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/hash_set.inl @@ -0,0 +1,404 @@ +#include "assert.h" + +namespace stingray_plugin_foundation { + +template +HashSet::HashSet(Allocator &a) : _data(), _used(0), _buckets(0), + _spill_unused(0), _spill_freelist(END_OF_FREELIST), _allocator(a) +{} + +template +HashSet::HashSet(unsigned buckets, unsigned spill, Allocator &a) : _data(), + _used(0), _buckets(buckets), _spill_unused(spill), _spill_freelist(END_OF_FREELIST) + , _allocator(a) +{ + allocate_data(buckets + spill); + for (unsigned i=0; i<_data.size; ++i) + _data.marker[i] = UNUSED; +} + +template +HashSet::HashSet(const HashSet &o) : + _hash(o._hash), _equal(o._equal), + _data(), _used(o._used), _buckets(o._buckets), + _spill_unused(o._spill_unused), _spill_freelist(o._spill_freelist), + _allocator(o._allocator) +{ + allocate_data(o._data.size); + for (unsigned i = 0; i < _data.size; ++i) { + if (o._data.marker[i] != UNUSED && (o._data.marker[i] & 0x80000000) == 0) { + construct(_data.key[i], IS_ALLOCATOR_AWARE_TYPE(K)()); + _data.key[i] = o._data.key[i]; + } + _data.marker[i] = o._data.marker[i]; + } +} + +template +void HashSet::operator=(const HashSet &o) +{ + if (this == &o) + return; + clear(); + _hash = o._hash; + _equal = o._equal; + _allocator.deallocate(_data.marker); + _data.marker = nullptr; + allocate_data(o._data.size); + for (unsigned i = 0; i < _data.size; ++i) { + if (o._data.marker[i] != UNUSED && (o._data.marker[i] & 0x80000000) == 0) { + construct(_data.key[i], IS_ALLOCATOR_AWARE_TYPE(K)()); + _data.key[i] = o._data.key[i]; + } + _data.marker[i] = o._data.marker[i]; + } + _used = o._used; + _buckets = o._buckets; + _spill_unused = o._spill_unused; + _spill_freelist = o._spill_freelist; +} + +template +HashSet::~HashSet() +{ + clear(); + _allocator.deallocate(_data.marker); +} + +template +void HashSet::reserve(unsigned items) +{ + unsigned buckets = int(items * 1.37f); + if (buckets < int(19*1.37f)) + buckets = int(19*1.37f); + rehash(buckets); +} + +template +void HashSet::swap(HashSet &o) +{ + XENSURE(&_allocator == &o._allocator); + std::swap(_hash, o._hash); + std::swap(_equal, o._equal); + std::swap(_data.size, o._data.size); + std::swap(_data.marker, o._data.marker); + std::swap(_data.key, o._data.key); + std::swap(_used, o._used); + std::swap(_buckets, o._buckets); + std::swap(_spill_unused, o._spill_unused); + std::swap(_spill_freelist, o._spill_freelist); +} + +template +Allocator & HashSet::allocator() const +{ + return _allocator; +} + +template +unsigned HashSet::size() const +{ + return _used; +} + +template +bool HashSet::empty() const +{ + return _used == 0; +} + +template template +unsigned HashSet::find_or_fail(const KEY_EQ &k) const +{ + if (empty()) + return END_OF_LIST; + + unsigned i = hash(k); + if (_data.marker[i] == UNUSED) + return END_OF_LIST; + while (true) { + if (i == END_OF_LIST || _equal(k, _data.key[i])) + return i; + i = _data.marker[i]; + } +} + +template template +unsigned HashSet::find_or_make(const KEY_EQ &k) +{ + unsigned i = hash(k); + if (_data.marker[i] == UNUSED) { + ++_used; + construct(_data.key[i], IS_ALLOCATOR_AWARE_TYPE(K)()); + _data.key[i] = k; + _data.marker[i] = END_OF_LIST; + return i; + } + while (true) { + if (_equal(k, _data.key[i]) ) + return i; + + if (_data.marker[i] == END_OF_LIST) { + unsigned j = allocate_spill(); + _data.marker[i] = j; + i = j; + construct(_data.key[i], IS_ALLOCATOR_AWARE_TYPE(K)()); + _data.key[i] = k; + _data.marker[i] = END_OF_LIST; + return j; + } else + i = _data.marker[i]; + } +} + +template template +void HashSet::find_and_erase(const KEY_EQ &k) +{ + unsigned i = hash(k); + if (_data.marker[i] == UNUSED) + return; + + if (_equal(k, _data.key[i])) { + if (_data.marker[i] == END_OF_LIST) { + _data.marker[i] = UNUSED; + destruct(_data.key[i]); + --_used; + } else { + unsigned del = _data.marker[i]; + _data.marker[i] = _data.marker[del]; + _data.key[i] = _data.key[del]; + destruct(_data.key[del]); + free_spill(del); + } + return; + } + + unsigned prev = i; + while (true) { + if (_equal(k, _data.key[i]) ) { + _data.marker[prev] = _data.marker[i]; + destruct(_data.key[i]); + free_spill(i); + return; + } + + if (_data.marker[i] == END_OF_LIST) + return; + + prev = i; + i = _data.marker[i]; + } +} + +template template +bool HashSet::has(const KEY_EQ &k) const +{ + return find_or_fail(k) != END_OF_LIST; +} + +template +void HashSet::clear() +{ + _used = 0; + _spill_freelist = END_OF_FREELIST; + _spill_unused = _data.size - _buckets; + for (unsigned i = 0; i<_data.size; ++i) { + if (bucket_valid(i)) + destruct(_data.key[i]); + _data.marker[i] = UNUSED; + } +} + +template template +void HashSet::insert(const KEY_EQ &k) +{ + if (full()) { + unsigned i = find_or_fail(k); + if (i != END_OF_LIST) + return; + grow(); + } + find_or_make(k); +} + +template template +void HashSet::erase(const KEY_EQ &k) +{ + find_and_erase(k); +} + +template +void HashSet::rehash(unsigned new_buckets) +{ + XENSURE(new_buckets >= _used); + clear_freelist(); + unsigned spill = int(new_buckets * 0.37f + 1); + unsigned old_size = _data.size; + if (_data.size == 0) { + allocate_data(new_buckets + spill); + _buckets = new_buckets; + _spill_unused = spill; + for (unsigned i = 0; i<_data.size; ++i) + _data.marker[i] = UNUSED; + return; + } + this_type new_set(new_buckets, spill, _allocator); + for (unsigned o = 0; o +typename HashSet::const_iterator HashSet::begin() const +{ + return const_iterator(*this, 0); +} + +template +typename HashSet::const_iterator HashSet::end() const +{ + return const_iterator(*this, num_buckets()); +} + +template +unsigned HashSet::num_buckets() const +{ + return _data.size; +} + +template +bool HashSet::bucket_valid(unsigned i) const +{ + return (_data.marker[i] & 0x80000000) == 0; +} + +template +const typename HashSet::key_type &HashSet::bucket_value(unsigned i) const +{ + return _data.key[i]; +} + +template +typename HashSet::key_type &HashSet::bucket_value(unsigned i) +{ + return _data.key[i]; +} + +template +bool HashSet::full() const +{ + return _spill_unused == 0 && _spill_freelist == END_OF_FREELIST; +} + +template +void HashSet::grow() +{ + do { + unsigned new_buckets = _buckets * 2 + 1; + if (new_buckets < 19) + new_buckets = 19; + rehash(new_buckets); + } while (full()); +} + +template template +unsigned HashSet::hash(const KEY_EQ &k) const +{ + return _hash(k) % _buckets; +} + +template +unsigned HashSet::allocate_spill() +{ + ++_used; + unsigned i = 0; + if (_spill_freelist != END_OF_FREELIST) { + i = _spill_freelist & 0x7fffffff; + _spill_freelist = _data.marker[i]; + return i; + } else { + XENSURE(_spill_unused > 0); + i = _data.size - _spill_unused; + --_spill_unused; + } + _data.marker[i] = UNUSED; + return i; +} + +template +void HashSet::free_spill(unsigned i) +{ + --_used; + _data.marker[i] = _spill_freelist; + _spill_freelist = i | 0x80000000; +} + +template +void HashSet::clear_freelist() +{ + while (_spill_freelist != END_OF_FREELIST) { + unsigned i = _spill_freelist & 0x7fffffff; + _spill_freelist = _data.marker[i]; + _data.marker[i] = UNUSED; + } +} + +template +void HashSet::allocate_data(unsigned count) +{ + XASSERT(_data.marker == nullptr, "Data must be deallocated/cleared before allocating new data"); + if (count == 0) { + _data = Data(); + return; + } + + auto marker_size = (((sizeof(unsigned) * count) + sizeof(void*) - 1) / sizeof(void*)) * sizeof(void*); + auto key_size = sizeof(key_type) * count; + auto data_size = marker_size + key_size; + _data.marker = (unsigned*)_allocator.allocate(data_size); + _data.key = (key_type*)&(((char*)_data.marker)[marker_size]); + _data.size = count; +} + +template +template void HashSet::serialize(STREAM &stream) +{ + unsigned n = _used; + stream & n; + if (stream.is_output()) { + iterator it(*this, 0); + iterator end(*this, num_buckets()); + for (; it != end; ++it) + stream & *it; + } else { + for (unsigned i=0; i +#include + +#include "platform.h" + +namespace stingray_plugin_foundation { + +#define ID32_FORMAT "#ID[%08x]" +#define ID64_FORMAT "#ID[%016llx]" + +// An IdString64 is a 64-bit hash of a string value. It can be used +// instead of strings to save memory and processing time. +// +// If you know that the keyspace is small and want to save memory +// you can use an IdString32 instead of an IdString64. IdString32 +// uses the same hash function as IdString64, but just keeps the +// first 32 bits of the hash so you can do a reverse lookup using +// the same tables. +class IdString64 +{ +public: + IdString64(); + explicit IdString64(uint64_t id); + explicit IdString64(const char *s); + IdString64(const char *s, uint64_t id); + IdString64(unsigned len, const char *s); + + // Returns the stored hash value. + uint64_t id() const {return _id;} + + // True if this is the empty string. + bool empty() const {return _id == 0;} + + // True if this is not the empty string. + bool nonempty() const {return _id != 0;} + + bool operator==(const IdString64 &o) const {return _id == o._id;} + bool operator!=(const IdString64 &o) const {return _id != o._id;} + bool operator<(const IdString64 &o) const {return _id < o._id;} + + // Converts the id to a string on the format #ID[xxxxxxxxxxxxxxxx]. + // Returns a pointer to a static copy of the result. This will be + // overwritten by next call. + const char *to_string() const {return to_id_hex();} + + // Converts the id to a string on the format #ID[xxxxxxxxxxxxxxxx]. + // Returns a pointer to a static copy of the result. This will be + // overwritten by next call. + const char *to_id_hex() const; + + static const int HEX_BUFFER_SIZE = 17; + + // Writes a hexadecimal null terminated string to the memory pointed + // to by `s`. There must be 17 bytes of allocated memory where `s` + // is pointing. + void to_hex(char *s) const {sprintf(s, "%016llx", (unsigned long long)_id);} + +private: + uint64_t _id; +}; + +// A 32 bit hashed string value. If your keyspace is too big and you +// get collisions with this hash, you should switch to an IdString64 +// instead. +class IdString32 +{ +public: + IdString32(); + explicit IdString32(unsigned id); + explicit IdString32(uint64_t id64); + explicit IdString32(const char *s); + IdString32(const char *s, unsigned id); + IdString32(unsigned len, const char *s); + + template void serialize(STREAM &s) { + s & _id; + } + + // Returns the stored hash value. + unsigned id() const {return _id;} + + // True if this is the empty string. + bool empty() const {return _id == 0;} + + // True if this is not the empty string. + bool nonempty() const {return _id != 0;} + + bool operator==(const IdString32 &o) const {return _id == o._id;} + bool operator!=(const IdString32 &o) const {return _id != o._id;} + bool operator<(const IdString32 &o) const {return _id < o._id;} + + const char *to_string() const {return to_id_hex();} + const char *to_id_hex() const; + static const int HEX_BUFFER_SIZE = 9; + char *to_hex(char *s) const {sprintf(s, "%08x", _id); return s;} + +private: + unsigned _id; +}; + +struct idstring_hash { + unsigned operator()(const IdString64 &t) const {return (t.id() >> 32);} + unsigned operator()(const IdString32 &t) const {return t.id();} +}; + +} + +#include "id_string.inl" diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/id_string.inl b/lib/dt_p2p/stingray_sdk/plugin_foundation/id_string.inl new file mode 100644 index 0000000..b3b332d --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/id_string.inl @@ -0,0 +1,88 @@ +#include +#include "hash_function.h" +#include "array.h" + +namespace stingray_plugin_foundation { + +inline IdString64::IdString64() : _id(0) +{ +} + +inline IdString64::IdString64(uint64_t id) : _id(id) +{ +} + +inline IdString64::IdString64(const char *s) +{ + _id = murmur_hash_64(s, (unsigned)strlen(s), 0); +} + +inline IdString64::IdString64(unsigned len, const char *s) +{ + _id = murmur_hash_64(s, len, 0); +} + +inline IdString64::IdString64(const char *s, uint64_t id) +{ + _id = id; + #if defined(_DEBUG) && defined(XASSERT) + XASSERT(_id == murmur_hash_64(s, (unsigned)strlen(s), 0), "Bad static idstring `%s`", s); + #endif +} + +inline const char *IdString64::to_id_hex() const +{ + static char buffer[200]; + static char *p = &buffer[0]; + + if (p + HEX_BUFFER_SIZE + 10 > &buffer[200]) + p = &buffer[0]; + char hex[HEX_BUFFER_SIZE]; + to_hex(hex); + sprintf(p, "#ID[%s]", hex); + char *s = p; + p += strlen(p) + 1; + return s; +} + +inline IdString32::IdString32() : _id(0) {} +inline IdString32::IdString32(unsigned id) : _id(id) {} + +inline IdString32::IdString32(const char *s) +{ + uint64_t id64 = murmur_hash_64(s, (unsigned)strlen(s), 0); + _id = (id64 >> 32); +} + +inline IdString32::IdString32(unsigned len, const char *s) +{ + uint64_t id64 = murmur_hash_64(s, len, 0); + _id = (id64 >> 32); +} + +inline const char *IdString32::to_id_hex() const +{ + static char buffer[200]; + static char *p = &buffer[0]; + + if (p + HEX_BUFFER_SIZE + 10 > &buffer[200]) + p = &buffer[0]; + char hex[HEX_BUFFER_SIZE]; + to_hex(hex); + sprintf(p, "#ID[%s]", hex); + char *s = p; + p += strlen(p) + 1; + return s; +} + +template <> +template void Array::serialize(STREAM &stream) { + raw_array_serialize(stream, *this); +} + +template <> +template void Array::serialize(STREAM &stream) { + raw_array_serialize(stream, *this); +} + +} diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/line_shapes.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/line_shapes.h new file mode 100644 index 0000000..8d7d6db --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/line_shapes.h @@ -0,0 +1,25 @@ +#pragma once + +#include "vector.h" +#include "types.h" +#include "color.h" + +namespace stingray_plugin_foundation +{ + +namespace line_shapes +{ + typedef Vector PointList; + typedef Vector ColorList; + + void line(const Vector3 &p1, const Vector3 &p2, Color8 color, PointList & out_starts, PointList & out_ends, ColorList & out_colors); + void xyz_cross(const Vector3 &pos, float radius, Color8 color, PointList & out_starts, PointList & out_ends, ColorList & out_colors); + void circle(const Vector3 &pos, float radius, const Vector3 &normal, Color8 color, PointList & out_starts, PointList & out_ends, ColorList & out_colors, int segments=20); + void cone(const Vector3 &p1, const Vector3 &p2, float radius, Color8 color, PointList & out_starts, PointList & out_ends, ColorList & out_colors, int segments = 20, int bars = 10); + void arrow(const Vector3 &from, const Vector3 &to, float head_height, float head_radius, Color8 color, PointList & out_starts, PointList & out_ends, ColorList & out_colors); + void sphere(const Vector3 &pos, float radius, Color8 color, PointList & out_starts, PointList & out_ends, ColorList & out_colors, int segments = 20, int parts = 2); +} // namespace line_shapes + +} // namespace stingray_plugin_foundation + +#include "line_shapes.inl" diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/line_shapes.inl b/lib/dt_p2p/stingray_sdk/plugin_foundation/line_shapes.inl new file mode 100644 index 0000000..bb4b1c7 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/line_shapes.inl @@ -0,0 +1,80 @@ +#include "vector3.h" + +namespace stingray_plugin_foundation +{ + +inline void line_shapes::line(const Vector3 &p1, const Vector3 &p2, Color8 color, PointList & out_starts, PointList & out_ends, ColorList & out_colors) +{ + out_starts.push_back(p1); + out_ends.push_back(p2); + out_colors.push_back(color); +} + +inline void line_shapes::xyz_cross(const Vector3 &pos, float radius, Color8 color, PointList & out_starts, PointList & out_ends, ColorList & out_colors) +{ + line(pos - vector3(radius,0,0), pos + vector3(radius,0,0), color, out_starts, out_ends, out_colors); + line(pos - vector3(0,radius,0), pos + vector3(0,radius,0), color, out_starts, out_ends, out_colors); + line(pos - vector3(0,0,radius), pos + vector3(0,0,radius), color, out_starts, out_ends, out_colors); +} + +inline void line_shapes::circle(const Vector3 &pos, float radius, const Vector3 &normal, Color8 color, PointList & out_starts, PointList & out_ends, ColorList & out_colors, int segments) +{ + Vector3 x, y; + make_axes(normal, x, y); + x *= radius; + y *= radius; + + Vector3 prev; + for( int i = 0; i <= segments; ++i ) { + float t = ((math::pi*2.0f) / ((float)segments)) * (float)i; + Vector3 point = pos + x * cosf(t) + y * sinf(t); + if (i != 0) + line(prev, point, color, out_starts, out_ends, out_colors); + prev = point; + } +} + +inline void line_shapes::cone(const Vector3 &p1, const Vector3 &p2, float radius, Color8 color, PointList & out_starts, PointList & out_ends, ColorList & out_colors, int segments, int bars) +{ + Vector3 n = normalize(p1 - p2); + Vector3 x, y; + make_axes(n, x, y); + + circle(p2, radius, n, color, out_starts, out_ends, out_colors, segments); + for (int i=0; i +#include +#include + +namespace stingray_plugin_foundation { + +// Common math functions. +namespace math { + const float pi = 3.141592654f; + + __forceinline bool is_pow2(unsigned); + __forceinline float square_root(float); + __forceinline float degrees_to_radians(float); + __forceinline float radians_to_degrees(float f); + + #undef max + template __forceinline T max(T a, T b); + template __forceinline T max3(T a, T b, T c); + + #undef min + template __forceinline T min(T a, T b); + template __forceinline T min3(T a, T b, T c); + + template __forceinline T clamp(T x, T min, T max); + + template __forceinline T abs(T x); + template __forceinline T sign(T x); + + unsigned branchless_max(unsigned a, unsigned b); + unsigned branchless_min(unsigned a, unsigned b); + + unsigned div_ceil(unsigned a, unsigned b); + unsigned div_round(unsigned a, unsigned b); + + __forceinline unsigned round_down_to_align(unsigned x, unsigned align) {return x - x%align;} + __forceinline unsigned round_up_to_align(unsigned x, unsigned align) {return round_down_to_align(x+align-1, align);} + + __forceinline bool valid(const float *fa, unsigned n) + { + for (unsigned i=0; i= FLT_MAX || f <= -FLT_MAX) + return false; + } + return true; + } + + __forceinline unsigned log2(unsigned a) + { + unsigned log2 = 0; + while(a >>= 1) log2++; + return log2; + } +} + +__forceinline float lerp(float a, float b, float t); + +// Finds the maximum value and its source from a number of tested +// values. +template +class FindMaximum +{ +public: + // Initiates the search for the maximum value. + // * `start` The start value of the search. + FindMaximum(float start = -std::numeric_limits::max()) : _value(start) {} + + // Tests if value is the biggest value encountered so far. + // If it is, the value and the source are recorded and the + // function returns true, otherwise it returns false. + bool test(float value, const SOURCE &source) { + if (value > _value) { + _value = value; + _source = source; + return true; + } else + return false; + } + + // Returns true if any value bigger than the start value was + // found. + bool found(float start = -std::numeric_limits::max()) {return _value > start;} + + // Returns the maximum value found. + const float &value() {return _value;} + + // Returns the source of the maximum value found + const SOURCE &source() {return _source;} + +private: + float _value; + SOURCE _source; +}; + +// Finds the minimum value and its source from a number of tested +// values. +template +class FindMinimum +{ +public: + // Initiates the search for the minimum avlue. + // * `start` The start value of the search + FindMinimum(float start = std::numeric_limits::max()) : _value(start) {} + + // Tests if value is the smallest value encountered so far. + // If it is, the value and the source are recorded and the + // function returns true, otherwise it returns false. + bool test(const float &value, const SOURCE &source) { + if (value < _value) { + _value = value; + _source = source; + return true; + } else + return false; + } + + // Returns true if any value smaller than the start value was + // found. + bool found(float start = std::numeric_limits::max()) {return _value < start;} + + // Returns the maximum value found. + const float &value() {return _value;} + + // Returns the source of the maximum value found + const SOURCE &source() {return _source;} + +private: + float _value; + SOURCE _source; +}; + +// Class that represents a cross fade. +// A cross fade is a mix between an in fade and an out fade. +class Crossfade +{ +public: + // Creates a new crossfade that is fully faded in. + Crossfade() : _fade_in(1), _fade_in_t(FLT_MAX), _fade_out(0), _fade_out_t(FLT_MAX) {} + + // Creates a new crossfade that fades in over time `bt`. + Crossfade(float bt) : _fade_in(0), _fade_in_t(bt), _fade_out(0), _fade_out_t(FLT_MAX) {} + + // Fades out the current crossfade over time bt. + void fade_out(float bt) { + if (bt < _fade_out_t) + _fade_out_t = bt; + if (_fade_in_t != FLT_MAX && bt < _fade_in_t) + _fade_in_t = bt; + } + + // Updates this crossfade + void update(float dt); + + // Returns true if the crossfade is done + bool is_done() {return _fade_out == 1;} + + // Returns the current blend value for the crossfade + float blend() {return _fade_in - _fade_out;} + +private: + float _fade_in, _fade_in_t; + float _fade_out, _fade_out_t; +}; + +} + +#include "math.inl" diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/math.inl b/lib/dt_p2p/stingray_sdk/plugin_foundation/math.inl new file mode 100644 index 0000000..79f913c --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/math.inl @@ -0,0 +1,120 @@ +#include "assert.h" + +namespace stingray_plugin_foundation { + +__forceinline bool math::is_pow2(unsigned x) +{ + return (x & (x - 1)) == 0; +} + +__forceinline float math::square_root(float f) +{ + return sqrtf(f); +} + +__forceinline float math::degrees_to_radians(float f) +{ + return f / 180.0f * pi; +} + +__forceinline float math::radians_to_degrees(float f) +{ + return 180.0f * f / pi; +} + +template __forceinline T math::max(T a, T b) +{ + return a > b ? a : b; +} + +template __forceinline T math::max3(T a, T b, T c) +{ + return max(a, max(b,c)); +} + +template __forceinline T math::min(T a, T b) +{ + return a < b ? a : b; +} + +template __forceinline T math::min3(T a, T b, T c) +{ + return min(a, min(b,c)); +} + + +template __forceinline T math::clamp(T x, T min, T max) +{ + if(x>max) + return max; + else if(x __forceinline T math::abs(T x) +{ + if (x > 0) + return x; + else + return -x; +} + +template __forceinline T math::sign(T x) +{ + if (x > 0) + return T(1); + else if (x == 0) + return T(0); + else + return T(-1); +} + +__forceinline unsigned math::branchless_max(unsigned a, unsigned b) +{ + return a - ((a-b) & (a-b)>>31); +} + +__forceinline unsigned math::branchless_min(unsigned a, unsigned b) +{ + return b + ((a-b) & (a-b)>>31); +} + +__forceinline unsigned math::div_ceil(unsigned a, unsigned b) { + return (a+b-1)/b; +} + +__forceinline unsigned math::div_round(unsigned a, unsigned b) { + return (a+b/2)/b; +} + +__forceinline float lerp(float a, float b, float p) +{ + return a * (1-p) + b * p; +} + +inline void Crossfade::update(float dt) +{ + if (_fade_in_t < FLT_MAX) { + _fade_in += (1 - _fade_in) * dt / _fade_in_t; + _fade_in_t -= dt; + if (_fade_in_t <= 0) { + _fade_in_t = FLT_MAX; + _fade_in = 1; + } + } + + if (_fade_out_t < FLT_MAX) { + _fade_out += (1 - _fade_out) * dt / _fade_out_t; + _fade_out_t -= dt; + if (_fade_out_t <= 0) { + _fade_out_t = FLT_MAX; + _fade_out = 1; + } + } + + XENSURE(blend() >= 0.0f); +} + +} diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/matrix4x4.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/matrix4x4.h new file mode 100644 index 0000000..0335927 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/matrix4x4.h @@ -0,0 +1,78 @@ +#pragma once + +#include "types.h" +#include "platform.h" + +namespace stingray_plugin_foundation { + +// Operators +__forceinline Matrix4x4 operator *(const Matrix4x4& lhs, const Matrix4x4 &rhs); +__forceinline Matrix4x4 operator +(const Matrix4x4& lhs, const Matrix4x4 &rhs); +__forceinline Matrix4x4 operator -(const Matrix4x4& lhs, const Matrix4x4 &rhs); + +__forceinline void operator *=(Matrix4x4& lhs, const Matrix4x4 &rhs); +__forceinline void operator +=(Matrix4x4& lhs, const Matrix4x4 &rhs); +__forceinline void operator -=(Matrix4x4& lhs, const Matrix4x4 &rhs); + +__forceinline bool operator==(const Matrix4x4 &lhs, const Matrix4x4 &rhs); +__forceinline bool operator!=(const Matrix4x4 &lhs, const Matrix4x4 &rhs); + +__forceinline Matrix4x4 operator *(const Matrix4x4& lhs, float rhs); +__forceinline Matrix4x4 operator *(float lhs, const Matrix4x4 &rhs); + +// Methods +__forceinline void set_to_zero_matrix(Matrix4x4 &m); +__forceinline void set_to_identity_matrix(Matrix4x4 &m); +__forceinline void set_to_scale_matrix(Matrix4x4 &m, const Vector3 &s); +__forceinline void set_to_translation_matrix(Matrix4x4 &m, const Vector3 &t); +__forceinline const Matrix4x4 &matrix4x4_zero(); +__forceinline const Matrix4x4 &matrix4x4_identity(); +__forceinline void normalize(Matrix4x4 &m); +__forceinline float determinant(const Matrix4x4 &m); +__forceinline bool has_mirroring(const Matrix4x4 &m); + +Matrix4x4 inverse(const Matrix4x4 &m); + +__forceinline float & element(Matrix4x4 &m, int i, int j); +__forceinline const float & element(const Matrix4x4 &m, int i, int j); + +__forceinline void transpose(Matrix4x4 &m); + +__forceinline Matrix4x4 rotation(const Matrix4x4 &m); +__forceinline void set_rotation(Matrix4x4 &m, const Matrix4x4 &rot); + +__forceinline Vector3 scale(const Matrix4x4 &m); +__forceinline void set_scale(Matrix4x4 &m, const Vector3 &scale); + +// Vector3 helper access +__forceinline Vector3 &translation(Matrix4x4 &m); +__forceinline Vector3 &x_axis(Matrix4x4 &m); +__forceinline Vector3 &y_axis(Matrix4x4 &m); +__forceinline Vector3 &z_axis(Matrix4x4 &m); +__forceinline const Vector3 &translation(const Matrix4x4 &m); +__forceinline const Vector3 &x_axis(const Matrix4x4 &m); +__forceinline const Vector3 &y_axis(const Matrix4x4 &m); +__forceinline const Vector3 &z_axis(const Matrix4x4 &m); + +__forceinline void set_translation(Matrix4x4 &m, const Vector3 &t); + +__forceinline Vector3 &forward_axis(Matrix4x4 &m); +__forceinline Vector3 &up_axis(Matrix4x4 &m); +__forceinline Vector3 &right_axis(Matrix4x4 &m); +__forceinline const Vector3 &forward_axis(const Matrix4x4 &m); +__forceinline const Vector3 &up_axis(const Matrix4x4 &m); +__forceinline const Vector3 &right_axis(const Matrix4x4 &m); + +__forceinline Vector3 &axis(Matrix4x4 &m, int i); +__forceinline const Vector3 &axis(const Matrix4x4 &m, int i); +__forceinline Vector4 &row(Matrix4x4 &m, int i); +__forceinline const Vector4 &row(const Matrix4x4 &m, int i); + +// Transforms the point p with the matrix m. +__forceinline Vector3 transform(const Matrix4x4 &m, const Vector3 &p); +__forceinline Vector3 transform_without_translation(const Matrix4x4 &m, const Vector3 &p); +__forceinline Vector4 transform(const Matrix4x4 &m, const Vector4 &p); + +} + +#include "matrix4x4.inl" diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/matrix4x4.inl b/lib/dt_p2p/stingray_sdk/plugin_foundation/matrix4x4.inl new file mode 100644 index 0000000..6538704 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/matrix4x4.inl @@ -0,0 +1,385 @@ +#include "vector3.h" + +namespace stingray_plugin_foundation { + +enum Elements { + xx, xy, xz, xw, + yx, yy, yz, yw, + zx, zy, zz, zw, + tx, ty, tz, tw +}; + +// Operators + +__forceinline Matrix4x4 operator *(const Matrix4x4& lhs, const Matrix4x4 &rhs) { + Matrix4x4 m = {{ + lhs.v[xx]*rhs.v[xx] + lhs.v[xy]*rhs.v[yx] + lhs.v[xz]*rhs.v[zx] + lhs.v[xw]*rhs.v[tx], + lhs.v[xx]*rhs.v[xy] + lhs.v[xy]*rhs.v[yy] + lhs.v[xz]*rhs.v[zy] + lhs.v[xw]*rhs.v[ty], + lhs.v[xx]*rhs.v[xz] + lhs.v[xy]*rhs.v[yz] + lhs.v[xz]*rhs.v[zz] + lhs.v[xw]*rhs.v[tz], + lhs.v[xx]*rhs.v[xw] + lhs.v[xy]*rhs.v[yw] + lhs.v[xz]*rhs.v[zw] + lhs.v[xw]*rhs.v[tw], + lhs.v[yx]*rhs.v[xx] + lhs.v[yy]*rhs.v[yx] + lhs.v[yz]*rhs.v[zx] + lhs.v[yw]*rhs.v[tx], + lhs.v[yx]*rhs.v[xy] + lhs.v[yy]*rhs.v[yy] + lhs.v[yz]*rhs.v[zy] + lhs.v[yw]*rhs.v[ty], + lhs.v[yx]*rhs.v[xz] + lhs.v[yy]*rhs.v[yz] + lhs.v[yz]*rhs.v[zz] + lhs.v[yw]*rhs.v[tz], + lhs.v[yx]*rhs.v[xw] + lhs.v[yy]*rhs.v[yw] + lhs.v[yz]*rhs.v[zw] + lhs.v[yw]*rhs.v[tw], + lhs.v[zx]*rhs.v[xx] + lhs.v[zy]*rhs.v[yx] + lhs.v[zz]*rhs.v[zx] + lhs.v[zw]*rhs.v[tx], + lhs.v[zx]*rhs.v[xy] + lhs.v[zy]*rhs.v[yy] + lhs.v[zz]*rhs.v[zy] + lhs.v[zw]*rhs.v[ty], + lhs.v[zx]*rhs.v[xz] + lhs.v[zy]*rhs.v[yz] + lhs.v[zz]*rhs.v[zz] + lhs.v[zw]*rhs.v[tz], + lhs.v[zx]*rhs.v[xw] + lhs.v[zy]*rhs.v[yw] + lhs.v[zz]*rhs.v[zw] + lhs.v[zw]*rhs.v[tw], + lhs.v[tx]*rhs.v[xx] + lhs.v[ty]*rhs.v[yx] + lhs.v[tz]*rhs.v[zx] + lhs.v[tw]*rhs.v[tx], + lhs.v[tx]*rhs.v[xy] + lhs.v[ty]*rhs.v[yy] + lhs.v[tz]*rhs.v[zy] + lhs.v[tw]*rhs.v[ty], + lhs.v[tx]*rhs.v[xz] + lhs.v[ty]*rhs.v[yz] + lhs.v[tz]*rhs.v[zz] + lhs.v[tw]*rhs.v[tz], + lhs.v[tx]*rhs.v[xw] + lhs.v[ty]*rhs.v[yw] + lhs.v[tz]*rhs.v[zw] + lhs.v[tw]*rhs.v[tw] + }}; + + return m; +} + +__forceinline Matrix4x4 operator +(const Matrix4x4& lhs, const Matrix4x4 &rhs) { + Matrix4x4 m = {{ + lhs.v[xx] + rhs.v[xx], lhs.v[xy] + rhs.v[xy], lhs.v[xz] + rhs.v[xz], lhs.v[xw] + rhs.v[xw], + lhs.v[yx] + rhs.v[yx], lhs.v[yy] + rhs.v[yy], lhs.v[yz] + rhs.v[yz], lhs.v[yw] + rhs.v[yw], + lhs.v[zx] + rhs.v[zx], lhs.v[zy] + rhs.v[zy], lhs.v[zz] + rhs.v[zz], lhs.v[zw] + rhs.v[zw], + lhs.v[tx] + rhs.v[tx], lhs.v[ty] + rhs.v[ty], lhs.v[tz] + rhs.v[tz], lhs.v[tw] + rhs.v[tw] + }}; + return m; +} + +__forceinline Matrix4x4 operator -(const Matrix4x4& lhs, const Matrix4x4 &rhs) { + Matrix4x4 m = {{ + lhs.v[xx] - rhs.v[xx], lhs.v[xy] - rhs.v[xy], lhs.v[xz] - rhs.v[xz], lhs.v[xw] - rhs.v[xw], + lhs.v[yx] - rhs.v[yx], lhs.v[yy] - rhs.v[yy], lhs.v[yz] - rhs.v[yz], lhs.v[yw] - rhs.v[yw], + lhs.v[zx] - rhs.v[zx], lhs.v[zy] - rhs.v[zy], lhs.v[zz] - rhs.v[zz], lhs.v[zw] - rhs.v[zw], + lhs.v[tx] - rhs.v[tx], lhs.v[ty] - rhs.v[ty], lhs.v[tz] - rhs.v[tz], lhs.v[tw] - rhs.v[tw] + }}; + return m; +} + +__forceinline void operator *=(Matrix4x4& lhs, const Matrix4x4 &rhs) { + Matrix4x4 tmp = lhs * rhs; + lhs = tmp; +} + +__forceinline void operator +=(Matrix4x4& lhs, const Matrix4x4 &rhs) { + lhs.v[xx] += rhs.v[xx]; lhs.v[xy] += rhs.v[xy]; lhs.v[xz] += rhs.v[xz]; lhs.v[xw] += rhs.v[xw]; + lhs.v[yx] += rhs.v[yx]; lhs.v[yy] += rhs.v[yy]; lhs.v[yz] += rhs.v[yz]; lhs.v[yw] += rhs.v[yw]; + lhs.v[zx] += rhs.v[zx]; lhs.v[zy] += rhs.v[zy]; lhs.v[zz] += rhs.v[zz]; lhs.v[zw] += rhs.v[zw]; + lhs.v[tx] += rhs.v[tx]; lhs.v[ty] += rhs.v[ty]; lhs.v[tz] += rhs.v[tz]; lhs.v[tw] += rhs.v[tw]; +} + +__forceinline void operator -=(Matrix4x4& lhs, const Matrix4x4 &rhs) { + lhs.v[xx] -= rhs.v[xx]; lhs.v[xy] -= rhs.v[xy]; lhs.v[xz] -= rhs.v[xz]; lhs.v[xw] -= rhs.v[xw]; + lhs.v[yx] -= rhs.v[yx]; lhs.v[yy] += rhs.v[yy]; lhs.v[yz] -= rhs.v[yz]; lhs.v[yw] -= rhs.v[yw]; + lhs.v[zx] -= rhs.v[zx]; lhs.v[zy] += rhs.v[zy]; lhs.v[zz] -= rhs.v[zz]; lhs.v[zw] -= rhs.v[zw]; + lhs.v[tx] -= rhs.v[tx]; lhs.v[ty] -= rhs.v[ty]; lhs.v[tz] -= rhs.v[tz]; lhs.v[tw] -= rhs.v[tw]; +} + +__forceinline Matrix4x4 operator *(const Matrix4x4& lhs, float rhs) { + Matrix4x4 m = {{ + lhs.v[xx] * rhs, lhs.v[xy] * rhs, lhs.v[xz] * rhs, lhs.v[xw] * rhs, + lhs.v[yx] * rhs, lhs.v[yy] * rhs, lhs.v[yz] * rhs, lhs.v[yw] * rhs, + lhs.v[zx] * rhs, lhs.v[zy] * rhs, lhs.v[zz] * rhs, lhs.v[zw] * rhs, + lhs.v[tx] * rhs, lhs.v[ty] * rhs, lhs.v[tz] * rhs, lhs.v[tw] * rhs + }}; + return m; +} + +__forceinline Matrix4x4 operator *(float lhs, const Matrix4x4 &rhs) { + return rhs * lhs; +} + +__forceinline bool operator==(const Matrix4x4 &lhs, const Matrix4x4 &rhs) +{ + for (int i=0; i<16; ++i) + if (lhs.v[i] != rhs.v[i]) + return false; + return true; +} + +__forceinline bool operator!=(const Matrix4x4 &lhs, const Matrix4x4 &rhs) +{ + return !(lhs == rhs); +} + +// Methods + +__forceinline void set_to_zero_matrix(Matrix4x4 &m) +{ + m.v[xx]=m.v[xy]=m.v[xz]=m.v[xw]=0.f; + m.v[yx]=m.v[yy]=m.v[yz]=m.v[yw]=0.f; + m.v[zx]=m.v[zy]=m.v[zz]=m.v[zw]=0.f; + m.v[tx]=m.v[ty]=m.v[tz]=m.v[tw]=0.f; +} + +__forceinline void set_to_identity_matrix(Matrix4x4 &m) +{ + m = matrix4x4_identity(); +} + +__forceinline const Matrix4x4 &matrix4x4_zero() +{ + static Matrix4x4 zero = {{ + 0.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 0.f, + 0.f, 0.f, 0.f, 0.f + }}; + return zero; +} + +__forceinline const Matrix4x4 &matrix4x4_identity() +{ + static Matrix4x4 id = {{ + 1.f, 0.f, 0.f, 0.f, + 0.f, 1.f, 0.f, 0.f, + 0.f, 0.f, 1.f, 0.f, + 0.f, 0.f, 0.f, 1.f + }}; + return id; +} + +__forceinline void set_to_scale_matrix(Matrix4x4 &m, const Vector3 &s) +{ + set_to_identity_matrix(m); + m.v[xx] = s.x; + m.v[yy] = s.y; + m.v[zz] = s.z; +} + +__forceinline void set_to_translation_matrix(Matrix4x4 &m, const Vector3 &t) +{ + set_to_identity_matrix(m); + m.v[tx] = t.x; + m.v[ty] = t.y; + m.v[tz] = t.z; +} + +__forceinline void normalize(Matrix4x4 &m) { + Vector3 &x = x_axis(m); + Vector3 &y = y_axis(m); + Vector3 &z = z_axis(m); + + x = normalize(x); + y -= x*dot(x, y); + y = normalize(y); + z = cross(x,y); +} + +__forceinline float determinant(const Matrix4x4 &m) { +// return m.v[xx]*m.v[yy]*m.v[zz] + m.v[xy]*m.v[yz]*m.v[zx] + m.v[xz]*m.v[yx]*m.v[zy] - +// m.v[xz]*m.v[yy]*m.v[zx] - m.v[xy]*m.v[yx]*m.v[zz] - m.v[xx]*m.v[yz]*m.v[zy]; + + return + m.v[3] * m.v[6] * m.v[ 9] * m.v[12] - m.v[2] * m.v[7] * m.v[ 9] * m.v[12] - m.v[3] * m.v[5] * m.v[10] * m.v[12] + m.v[1] * m.v[7] * m.v[10] * m.v[12] + + m.v[2] * m.v[5] * m.v[11] * m.v[12] - m.v[1] * m.v[6] * m.v[11] * m.v[12] - m.v[3] * m.v[6] * m.v[ 8] * m.v[13] + m.v[2] * m.v[7] * m.v[ 8] * m.v[13] + + m.v[3] * m.v[4] * m.v[10] * m.v[13] - m.v[0] * m.v[7] * m.v[10] * m.v[13] - m.v[2] * m.v[4] * m.v[11] * m.v[13] + m.v[0] * m.v[6] * m.v[11] * m.v[13] + + m.v[3] * m.v[5] * m.v[ 8] * m.v[14] - m.v[1] * m.v[7] * m.v[ 8] * m.v[14] - m.v[3] * m.v[4] * m.v[ 9] * m.v[14] + m.v[0] * m.v[7] * m.v[ 9] * m.v[14] + + m.v[1] * m.v[4] * m.v[11] * m.v[14] - m.v[0] * m.v[5] * m.v[11] * m.v[14] - m.v[2] * m.v[5] * m.v[ 8] * m.v[15] + m.v[1] * m.v[6] * m.v[ 8] * m.v[15] + + m.v[2] * m.v[4] * m.v[ 9] * m.v[15] - m.v[0] * m.v[6] * m.v[ 9] * m.v[15] - m.v[1] * m.v[4] * m.v[10] * m.v[15] + m.v[0] * m.v[5] * m.v[10] * m.v[15]; + +} + +__forceinline bool has_mirroring(const Matrix4x4 &m) { + return (determinant(m) < 0.0f); +} + +__forceinline float & element(Matrix4x4 &m, int i, int j) +{ + return m.v[i*4 + j]; +} + +__forceinline const float & element(const Matrix4x4 &m, int i, int j) +{ + return m.v[i*4 + j]; +} + +__forceinline void transpose(Matrix4x4 &m) +{ + #define SWAP(a,b) {float temp = a; a = b; b = temp;} + + SWAP(m.v[1], m.v[4]); + SWAP(m.v[2], m.v[8]); + SWAP(m.v[3], m.v[12]); + SWAP(m.v[6], m.v[9]); + SWAP(m.v[7], m.v[13]); + SWAP(m.v[11], m.v[14]); + + #undef SWAP +} + +// Vector3 helper access +__forceinline Vector3 &translation(Matrix4x4 &m) { + return *reinterpret_cast(&m.v[tx]); +} +__forceinline Vector3 &x_axis(Matrix4x4 &m) { + return *reinterpret_cast(&m.v[xx]); +} +__forceinline Vector3 &y_axis(Matrix4x4 &m) { + return *reinterpret_cast(&m.v[yx]); +} +__forceinline Vector3 &z_axis(Matrix4x4 &m) { + return *reinterpret_cast(&m.v[zx]); +} + +__forceinline const Vector3 &translation(const Matrix4x4 &m) { + return *reinterpret_cast(&m.v[tx]); +} +__forceinline const Vector3 &x_axis(const Matrix4x4 &m){ + return *reinterpret_cast(&m.v[xx]); +} +__forceinline const Vector3 &y_axis(const Matrix4x4 &m){ + return *reinterpret_cast(&m.v[yx]); +} +__forceinline const Vector3 &z_axis(const Matrix4x4 &m){ + return *reinterpret_cast(&m.v[zx]); +} + +__forceinline Vector3 &forward_axis(Matrix4x4 &m) { + return y_axis(m); +} +__forceinline Vector3 &up_axis(Matrix4x4 &m) { + return z_axis(m); +} +__forceinline Vector3 &right_axis(Matrix4x4 &m) { + return x_axis(m); +} + +__forceinline const Vector3 &forward_axis(const Matrix4x4 &m){ + return y_axis(m); +} +__forceinline const Vector3 &up_axis(const Matrix4x4 &m){ + return z_axis(m); +} +__forceinline const Vector3 &right_axis(const Matrix4x4 &m){ + return x_axis(m); +} + +__forceinline Vector3 &axis(Matrix4x4 &m, int i) +{ + return *reinterpret_cast(&m.v[xx] + i*4); +} + +__forceinline const Vector3 &axis(const Matrix4x4 &m, int i) +{ + return *reinterpret_cast(&m.v[xx] + i*4); +} + +__forceinline Vector4 &row(Matrix4x4 &m, int i) +{ + return *reinterpret_cast(&m.v[xx] + i*4); +} + +__forceinline const Vector4 &row(const Matrix4x4 &m, int i) +{ + return *reinterpret_cast(&m.v[xx] + i*4); +} + +__forceinline void set_translation(Matrix4x4 &m, const Vector3 &t) +{ + translation(m) = t; +} + +__forceinline Vector3 transform(const Matrix4x4 &m, const Vector3 &p) +{ + Vector3 pt; + pt.x = m.v[xx] * p.x + m.v[yx] * p.y + m.v[zx] * p.z + m.v[tx]; + pt.y = m.v[xy] * p.x + m.v[yy] * p.y + m.v[zy] * p.z + m.v[ty]; + pt.z = m.v[xz] * p.x + m.v[yz] * p.y + m.v[zz] * p.z + m.v[tz]; + return pt; +} + +__forceinline Vector3 transform_without_translation(const Matrix4x4 &m, const Vector3 &p) +{ + Vector3 pt; + pt.x = m.v[xx] * p.x + m.v[yx] * p.y + m.v[zx] * p.z; + pt.y = m.v[xy] * p.x + m.v[yy] * p.y + m.v[zy] * p.z; + pt.z = m.v[xz] * p.x + m.v[yz] * p.y + m.v[zz] * p.z; + return pt; +} + +__forceinline Vector4 transform(const Matrix4x4 &m, const Vector4 &p) +{ + Vector4 pt; + pt.x = m.v[xx] * p.x + m.v[yx] * p.y + m.v[zx] * p.z + p.w * m.v[tx]; + pt.y = m.v[xy] * p.x + m.v[yy] * p.y + m.v[zy] * p.z + p.w * m.v[ty]; + pt.z = m.v[xz] * p.x + m.v[yz] * p.y + m.v[zz] * p.z + p.w * m.v[tz]; + pt.w = m.v[xw] * p.x + m.v[yw] * p.y + m.v[zw] * p.z + p.w * m.v[tw]; + return pt; +} + +__forceinline Matrix4x4 rotation(const Matrix4x4 &m) +{ + Matrix4x4 out = m; + out.v[xw] = out.v[yw] = out.v[zw] = out.v[tx] = out.v[ty] = out.v[tz] = 0; + out.v[tw] = 1; + return out; +} + +__forceinline void set_rotation(Matrix4x4 &m, const Matrix4x4 &rot) +{ + x_axis(m) = x_axis(rot); + y_axis(m) = y_axis(rot); + z_axis(m) = z_axis(rot); +} + +__forceinline Vector3 scale(const Matrix4x4 &m) +{ + Vector3 s; + s.x = length(x_axis(m)); + s.y = length(y_axis(m)); + s.z = length(z_axis(m)); + return s; +} + +__forceinline void set_scale(Matrix4x4 &m, const Vector3 &s) +{ + Vector3 p = scale(m); + x_axis(m) *= s.x / p.x; + y_axis(m) *= s.y / p.y; + z_axis(m) *= s.z / p.z; +} + +inline Matrix4x4 inverse(const Matrix4x4 &m) +{ + Matrix4x4 inv = matrix4x4_identity(); + Matrix4x4 temp = m; + int i, j, k, swap; + float *v = (float *)&temp.v[xx]; + float *v2 = (float *)&inv.v[xx]; + for(i=0; i!=4; ++i) { + swap=i; + for(j=i+1; j!=4; ++j) { + if(fabs(v[(j<<2)+i]) > fabs(v[(swap<<2)+i])) + swap = j; + } + if (swap != i) { + for(k=0; k!=4; ++k) { + const float t = v[(i<<2)+k]; + v[(i<<2)+k] = v[(swap<<2)+k]; + v[(swap<<2)+k] = t; + + const float t2 = v2[(i<<2)+k]; + v2[(i<<2)+k] = v2[(swap<<2)+k]; + v2[(swap<<2)+k] = t2; + } + } + if (v[(i<<2)+i] == 0) + return inv; + const float t = v[(i<<2)+i]; + for (k=0; k!=4; ++k) { + v[(i<<2)+k] /= t; + v2[(i<<2)+k] /= t; + } + for (j=0; j!=4; ++j) { + if(j!=i) { + const float t = v[(j<<2)+i]; + for(k=0; k<4; k++) { + v[(j<<2)+k] -= v[(i<<2)+k]*t; + v2[(j<<2)+k] -= v2[(i<<2)+k]*t; + } + } + } + } + return inv; +} + +} diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/memory_utilities.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/memory_utilities.h new file mode 100644 index 0000000..2376516 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/memory_utilities.h @@ -0,0 +1,94 @@ +#pragma once + +namespace stingray_plugin_foundation { + +namespace memory_utilities { + +// Rounds size up to the specified alignment +template +inline T round_up_to(T size, unsigned align) +{ + return ((size + align - 1) / align) * align; +} + +// Returns true if p is aligned to the specified alignment +inline bool is_aligned(const void *p, unsigned align) +{ + uintptr_t pi = (uintptr_t)p; + return pi % align == 0; +} + +// Returns the result of advancing p by the specified number of bytes +inline void *pointer_add(void *p, size_t bytes) +{ + return (void*)((char *)p + bytes); +} +inline const void *pointer_add(const void *p, size_t bytes) +{ + return (const void*)((const char *)p + bytes); +} + + +// Returns the result of moving p back by the specified number of bytes +inline void *pointer_sub(void *p, size_t bytes) +{ + return (void*)((char *)p - bytes); +} +inline const void *pointer_sub(const void *p, size_t bytes) +{ + return (const void*)((const char *)p - bytes); +} +inline size_t pointer_sub(const void *p1, const void *p2) +{ + return (const char *)p1 - (const char *)p2; +} + +// The number of bytes p must be moved forward to align +inline unsigned bytes_to_aligned_address(const void *p, unsigned align) +{ + uintptr_t pi = (uintptr_t)p; + return (unsigned)(((pi + align - 1)/align)*align - pi); +} + +// The number of bytes p must be moved backward to align +inline unsigned bytes_from_aligned_address(const void *p, unsigned align) +{ + uintptr_t pi = (uintptr_t)p; + return pi % align; +} + +// Moves p forward to align +inline void *round_up_to_aligned_address(void *p, unsigned align) +{ + return pointer_add(p, bytes_to_aligned_address(p, align)); +} +inline const void *round_up_to_aligned_address(const void *p, unsigned align) +{ + return pointer_add(p, bytes_to_aligned_address(p, align)); +} + +// Moves p backward to align +inline void *round_down_to_aligned_address(void *p, unsigned align) +{ + return pointer_sub(p, bytes_from_aligned_address(p, align)); +} +inline const void *round_down_to_aligned_address(const void *p, unsigned align) +{ + return pointer_sub(p, bytes_from_aligned_address(p, align)); +} + +// Interprets data at address p as an object of type T. +template +inline T& object_at_address(void *p) +{ + return *(T *)p; +} +template +inline const T& object_at_address(const void *p) +{ + return *(T *)p; +} + +} + +} diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/option.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/option.h new file mode 100644 index 0000000..7de29f9 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/option.h @@ -0,0 +1,40 @@ +#pragma once + +namespace stingray_plugin_foundation { + + // A class that can optionally hold a value. + template + class Option + { + bool _has_value; + T _value; + + Option(bool has_value, const T &value) : _has_value(has_value), _value(value) {} + + public: + // Initializes the object to hold no value. + Option() : _has_value(false), _value() {} + + // Initializes the object to hold the specified value. + Option(const T &value) : _has_value(true), _value(value) {} + + // Static constructor that returns an Option object with no value. + static Option none() {return Option();} + + // Static constructor that returns an Option object with the specified value. + static Option some(const T &value) {return Option(true, value);} + + // True if the object has a value. + bool is_some() const {return _has_value;} + + // True if the object doesn't have a value. + bool is_none() const {return !_has_value;} + + // Returns the object's value. + const T &value() const { + XASSERT(is_some(), "Cannot obtain value from a none Option."); + return _value; + } + }; + +} diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/pair.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/pair.h new file mode 100644 index 0000000..a71805d --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/pair.h @@ -0,0 +1,179 @@ +#pragma once + +#include +#include "allocator.h" +#include "template_tools.h" + +namespace stingray_plugin_foundation { + +// A replacement for std::pair that is allocator aware, so that any +// of the pair members that need to be constructed with an allocator is. +// +// The default template implementation is used when none of the types +// are allocator aware. +template +struct Pair { + typedef Pair this_type; + typedef FIRST first_type; + typedef SECOND second_type; + + Pair() : first(first_type()), second(second_type()) {} + Pair(Allocator &) : first(first_type()), second(second_type()) {} + Pair(const this_type &t) : first(t.first), second(t.second) {} + Pair(const first_type &f, const second_type &s) : first(f), second(s) {} + + void swap(this_type &right) { + std::swap(first, right.first); + std::swap(second, right.second); + } + + template void serialize(STREAM &s) {s & first & second;} + + first_type first; + second_type second; +}; + +// Template specialization to use when the first type is allocator aware. +template +struct Pair +{ + ALLOCATOR_AWARE; + + typedef Pair this_type; + typedef FIRST first_type; + typedef SECOND second_type; + + Pair(Allocator &a) : first(a), second(second_type()) {} + Pair(const first_type &f, const second_type &s) : first(f), second(s) {} + + void swap(this_type &right) { + std::swap(first, right.first); + std::swap(second, right.second); + } + + template void serialize(STREAM &s) {s & first & second;} + + first_type first; + second_type second; +}; + +// Template specialization to use when the second type is allocator aware. +template +struct Pair +{ + ALLOCATOR_AWARE; + + typedef Pair this_type; + typedef FIRST first_type; + typedef SECOND second_type; + + Pair(Allocator &a) : first(first_type()), second(a) {} + Pair(const first_type &f, const second_type &s) : first(f), second(s) {} + + void swap(this_type &right) { + std::swap(first, right.first); + std::swap(second, right.second); + } + + template void serialize(STREAM &s) {s & first & second;} + + first_type first; + second_type second; +}; + +// Template specialization to use when both types are allocator aware. +template +struct Pair +{ + ALLOCATOR_AWARE; + + typedef Pair this_type; + typedef FIRST first_type; + typedef SECOND second_type; + + Pair(Allocator &a) : first(a), second(a) {} + Pair(const first_type &f, const second_type &s) : first(f), second(s) {} + + void swap(this_type &right) { + std::swap(first, right.first); + std::swap(second, right.second); + } + + template void serialize(STREAM &s) {s & first & second;} + + first_type first; + second_type second; +}; + +// Comparison operators. + +template +bool operator==(const Pair &left, + const Pair &right) { + return left.first == right.first && left.second == right.second; +} + +template +bool operator!=(const Pair &left, + const Pair &right) { + return !(left == right); +} + +template +bool operator<(const Pair &left, + const Pair &right) { + return left.first < right.first || + (!(right.first < left.first) && left.second < right.second); +} + +template +bool operator>(const Pair &left, + const Pair &right) { + return (right < left); +} + +template +bool operator<=(const Pair &left, + const Pair &right) { + return !(right < left); +} + +template +bool operator>=(const Pair &left, + const Pair &right) { + return !(left < right); +} + +// make_pair function that constructs a Pair of the right type +template +Pair make_pair(const FIRST &f, const SECOND &s) +{ + return Pair(f, s); +} + +// swap implementation for Pair +template +void swap(const Pair &left, + const Pair &right) { + left.swap(right); +} + +// Declaration needed for GCC-based compilers +unsigned murmur_hash( const void * key, int len, unsigned seed ); + +// Pair hashing +template +struct pair_hash +{ + template + unsigned operator()(const Pair &pair) const + { + HASH_FIRST hash_first; + HASH_SECOND hash_second; + const unsigned result[2] = { hash_first(pair.first), hash_second(pair.second) }; + const unsigned hash = murmur_hash(&result[0], sizeof(result), 0); + return hash; + } +}; + +} // namespace stingray_plugin_foundation diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/path.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/path.h new file mode 100644 index 0000000..b43de86 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/path.h @@ -0,0 +1,74 @@ +#pragma once + +#include "string.h" +#include "vector.h" + +namespace stingray_plugin_foundation { + +// Convenience tools for manipulating paths. +namespace path +{ + // Strips the extension from path + void strip_extension(DynamicString &path); + + // Strips the extension from `path` returns the result. + DynamicString strip_extension(const char *path, Allocator &a); + + // Returns true if `path` has any extension. + bool has_extension(const char *path); + + // Returns true if `path` has the specified extension. Extension comparison is case-insensitive. + bool has_extension(const char *path, const char *pattern); + + // Joins `dir` to the beginning of all the file names in `files`. + void join(const char *dir, const Vector &files, Vector &res); +} + +} + +namespace stingray_plugin_foundation { + +namespace path { + + inline void strip_extension(DynamicString &path) + { + int n = path.size(); + for (int i = n - 1; i >= 0; --i) { + if (path[i] == '.') { + path.resize(i); + return; + } + } + } + + inline DynamicString strip_extension(const char *path, Allocator &a) + { + DynamicString s(a, path); + strip_extension(s); + return s; + } + + inline bool has_extension(const char *path) + { + int n = strlen32(path); + for (int i = n - 1; i >= 0; --i) { + if (path[i] == '.') + return true; + } + return false; + } + + inline bool has_extension(const char *path, const char *pattern) + { + int n = strlen32(path); + for (int i = n - 1; i >= 0; --i) { + if (path[i] == '.') { + return strequali(pattern, &path[i + 1]); + } + } + return pattern[0] == '\0'; + } + +} // namespace path + +} diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/platform.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/platform.h new file mode 100644 index 0000000..e117c9b --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/platform.h @@ -0,0 +1,43 @@ +#pragma once + +// Platform names +#define PLATFORM_NAME_WIN32 "win32" +#define PLATFORM_NAME_XB1 "xb1" +#define PLATFORM_NAME_ANDROID "android" +#define PLATFORM_NAME_MACOSX "macosx" +#define PLATFORM_NAME_IOS "ios" +#define PLATFORM_NAME_PS4 "ps4" +#define PLATFORM_NAME_WEB "web" +#define PLATFORM_NAME_LINUX "linux" +#define PLATFORM_NAME_UWP "uwp" + +#if defined(XBOXONE) + #include + #include + __forceinline uint64_t rdtsc(void) { return __rdtsc(); } +#endif + +#if defined(IOS) + #include +#endif + +#if defined(WINDOWSPC) || defined(UWP) || defined(XBOXONE) + #define __ALIGN(x) __declspec(align(x)) + #define __THREAD __declspec(thread) +#elif defined(IOS) || defined(ANDROID) || defined(WEB) || defined(LINUXPC) || defined(MACOSX) + #define __forceinline __attribute__((__always_inline__)) inline + #define __ALIGN(x) __attribute__((aligned(x))) + #define __THREAD +#elif defined(PS4) + #define __forceinline __inline__ __attribute__((always_inline)) + #define __ALIGN(x) __attribute__((aligned(x))) + #define __THREAD __thread +#endif + +#if defined(ANDROID) + #define PLUGIN_DLLEXPORT +#elif defined(IOS) + #define PLUGIN_DLLEXPORT __attribute__((visibility("default"))) +#else + #define PLUGIN_DLLEXPORT __declspec(dllexport) +#endif diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/quaternion.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/quaternion.h new file mode 100644 index 0000000..2888c19 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/quaternion.h @@ -0,0 +1,69 @@ +#pragma once + +#include "platform.h" +#include "types.h" + +namespace stingray_plugin_foundation { + +// Operators +__forceinline Quaternion operator +(const Quaternion &q); +__forceinline Quaternion operator -(const Quaternion &q); +__forceinline Quaternion operator +(const Quaternion &lhs, const Quaternion &rhs); +__forceinline Quaternion operator -(const Quaternion &lhs, const Quaternion &rhs); +__forceinline Quaternion operator *(const Quaternion &lhs, const Quaternion &rhs); +__forceinline Quaternion operator *(const Quaternion &lhs, float rhs); +__forceinline Quaternion operator *(float lhs, const Quaternion &rhs); +__forceinline Quaternion operator /(const Quaternion &lhs, float rhs); + +__forceinline void operator +=(Quaternion &lhs, const Quaternion &rhs); +__forceinline void operator -=(Quaternion &lhs, const Quaternion &rhs); +__forceinline void operator *=(Quaternion &lhs, const Quaternion &rhs); +__forceinline void operator *=(Quaternion &lhs, float rhs); + +__forceinline bool operator==(const Quaternion &lhs, const Quaternion &rhs); +__forceinline bool operator!=(const Quaternion &lhs, const Quaternion &rhs); +__forceinline bool operator< (const Quaternion &lhs, const Quaternion &rhs); +__forceinline bool operator<=(const Quaternion &lhs, const Quaternion &rhs); +__forceinline bool operator> (const Quaternion &lhs, const Quaternion &rhs); +__forceinline bool operator>=(const Quaternion &lhs, const Quaternion &rhs); + +// Creation Methods +__forceinline Quaternion quaternion(const float * list); +__forceinline Quaternion quaternion(float x, float y, float z, float w); +__forceinline const Quaternion &quaternion_identity(); +__forceinline Quaternion quaternion(const Vector3 &axis, float theta); +Quaternion quaternion(const Vector3 &forward, const Vector3 &up); +Quaternion quaternion(const Matrix4x4 &m); +Quaternion quaternion(const Matrix3x3 &m); +Quaternion quaternion_orthogonal(const Matrix4x4 &m); + +// Methods +__forceinline Quaternion normalize(const Quaternion &q); +__forceinline Quaternion inverse(const Quaternion &q); +__forceinline Quaternion conjugate(const Quaternion &q); +__forceinline float dot(const Quaternion &q1, const Quaternion &q2); +__forceinline Quaternion slerp(const Quaternion &from, const Quaternion &to, float t); +__forceinline Quaternion nlerp(const Quaternion &from, const Quaternion &to, float t); +__forceinline Quaternion lerp(const Quaternion &from, const Quaternion &to, float t); +__forceinline Quaternion scale_angle(const Quaternion &from, float t); + +__forceinline bool is_zero(const Quaternion &q); +__forceinline float norm(const Quaternion &q); +__forceinline float one_norm(const Quaternion &q); +__forceinline float infinity_norm(const Quaternion &q); + +// Rotate Vector3 with quaternion. +__forceinline Vector3 rotate(const Quaternion &q, const Vector3 &v); + +// Conversion Methods +__forceinline Matrix4x4 matrix4x4(const Quaternion &q); +__forceinline Matrix4x4 matrix4x4(const Quaternion &q, const Vector3 &p); +__forceinline void decompose(const Quaternion &q, Vector3 *axis, float *theta); +__forceinline float angle(const Quaternion &q); + +// Lerps the matrix by lerping Quaternion and Vector3 separately. +__forceinline void lerp(const Matrix4x4 &m1, const Matrix4x4 &m2, float t, Matrix4x4 &m); + +} + +#include "quaternion.inl" diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/quaternion.inl b/lib/dt_p2p/stingray_sdk/plugin_foundation/quaternion.inl new file mode 100644 index 0000000..dcab759 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/quaternion.inl @@ -0,0 +1,511 @@ +#include "vector3.h" +#include "matrix4x4.h" + +namespace stingray_plugin_foundation { + +// Operators +__forceinline Quaternion operator +(const Quaternion &q) { + return q; +} + +__forceinline Quaternion operator -(const Quaternion &q) { + return quaternion(-q.x, -q.y, -q.z, q.w); +} + +__forceinline Quaternion operator +(const Quaternion &lhs, const Quaternion &rhs) { + return quaternion(lhs.x+rhs.x, lhs.y+rhs.y, lhs.z+rhs.z, lhs.w+rhs.w); +} + +__forceinline Quaternion operator -(const Quaternion &lhs, const Quaternion &rhs) { + return quaternion(lhs.x-rhs.x, lhs.y-rhs.y, lhs.z-rhs.z, lhs.w-rhs.w); +} + +__forceinline Quaternion operator *(const Quaternion &lhs, const Quaternion &rhs) { + return quaternion( + lhs.w*rhs.x + lhs.x*rhs.w + lhs.y*rhs.z - lhs.z*rhs.y, + lhs.w*rhs.y + lhs.y*rhs.w + lhs.z*rhs.x - lhs.x*rhs.z, + lhs.w*rhs.z + lhs.z*rhs.w + lhs.x*rhs.y - lhs.y*rhs.x, + lhs.w*rhs.w - lhs.x*rhs.x - lhs.y*rhs.y - lhs.z*rhs.z + ); +} + +__forceinline Quaternion operator *(const Quaternion &lhs, float rhs) { + return quaternion(lhs.x*rhs, lhs.y*rhs, lhs.z*rhs, lhs.w*rhs); +} + +__forceinline Quaternion operator *(float lhs, const Quaternion &rhs) { + return rhs * lhs; +} + +__forceinline Quaternion operator /(const Quaternion &lhs, float rhs) { + return quaternion(lhs.x/rhs, lhs.y/rhs, lhs.z/rhs, lhs.w/rhs); +} + +__forceinline void operator +=(Quaternion &lhs, const Quaternion &rhs) { + lhs.x+=rhs.x; lhs.y+=rhs.y; lhs.z+=rhs.z; lhs.w+=rhs.w; +} + +__forceinline void operator -=(Quaternion &lhs, const Quaternion &rhs) { + lhs.x-=rhs.x; lhs.y-=rhs.y; lhs.z-=rhs.z; lhs.w-=rhs.w; +} + +__forceinline void operator *=(Quaternion &lhs, const Quaternion &rhs) { + lhs.x*=rhs.x; lhs.y*=rhs.y; lhs.z*=rhs.z; lhs.w*=rhs.w; + +} + +__forceinline void operator *=(Quaternion &lhs, float rhs) { + lhs.x*=rhs; lhs.y*=rhs; lhs.z*=rhs; lhs.w*=rhs; +} + +__forceinline bool operator==(const Quaternion &lhs, const Quaternion &rhs) +{ + return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z && lhs.w == rhs.w; +} + +__forceinline bool operator!=(const Quaternion &lhs, const Quaternion &rhs) +{ + return !(lhs == rhs); +} + +__forceinline bool operator< (const Quaternion &lhs, const Quaternion &rhs) +{ + if (lhs.x != rhs.x) return lhs.x < rhs.x; + if (lhs.y != rhs.y) return lhs.y < rhs.y; + if (lhs.z != rhs.z) return lhs.z < rhs.z; + return lhs.w < rhs.w; +} + +__forceinline bool operator<=(const Quaternion &lhs, const Quaternion &rhs) +{ + return (lhs < rhs) || (lhs == rhs); +} + +__forceinline bool operator> (const Quaternion &lhs, const Quaternion &rhs) +{ + return (rhs < lhs); +} + +__forceinline bool operator>=(const Quaternion &lhs, const Quaternion &rhs) +{ + return !(lhs < rhs); +} + +// Creation Methods + +__forceinline Quaternion quaternion(const float * list) { + Quaternion q = { *list, *(list+1), *(list+2), *(list+3) }; + return q; +} + +__forceinline Quaternion quaternion(float x, float y, float z, float w) { + Quaternion q = { x, y, z, w }; + return q; +} + +__forceinline const Quaternion &quaternion_identity() { + static Quaternion q = { 0.f, 0.f, 0.f, 1.f }; + return q; +} + +__forceinline Quaternion quaternion(const Vector3 &axis, float theta) { + Quaternion q; + + float halftheta = theta * 0.5f; + float cos_ht = cosf( halftheta ); + float sin_ht = sinf( halftheta ); + + q.x = axis.x * sin_ht; + q.y = axis.y * sin_ht; + q.z = axis.z * sin_ht; + q.w = cos_ht; + + return q; +} + +// Methods +__forceinline Quaternion normalize(const Quaternion &q) { + float l = math::square_root( dot(q,q) ); + + if(l == 0.0f) + return quaternion(0.f, 0.f, 0.f, 1.f); + else { + float c = 1.0f / l; + return quaternion(q.x*c, q.y*c, q.z*c, q.w*c); + } +} + +__forceinline Quaternion inverse(const Quaternion &q) { + float l = dot(q,q); + if (l == 0.0f) + l = 1.0f; + float norminv = -1.0f / l; + return quaternion(q.x*norminv, q.y*norminv, q.z*norminv, q.w*-norminv); +} + +__forceinline Quaternion conjugate(const Quaternion &q) { + return quaternion(-q.x, -q.y, -q.z, q.w); +} + +__forceinline float dot(const Quaternion &q1, const Quaternion &q2) { + return q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w; +} + +__forceinline Quaternion slerp(const Quaternion &from, const Quaternion &to, float t) { + Quaternion q; + Quaternion q3; + + float d = dot(from, to); + if (d < 0) { + d = -d; + q3 = to * -1.0f; + } else + q3 = to; + + // Use linear interpolation for small angles. + if (d < 0.95f) { + float clamped_dot = math::clamp(d, -1.0f, 1.0f); + float angle = acosf(clamped_dot); + float sina, sinat, sinaomt; + sina = sinf(angle); + sinat = sinf(angle*t); + sinaomt = sinf(angle*(1-t)); + q = (from*sinaomt+q3*sinat)/sina; + } else + q = nlerp(from, q3,t); + + return q; + +} + +__forceinline Quaternion nlerp(const Quaternion &from, const Quaternion &to, float t) { + Quaternion q; + if(dot(from, to) < 0) + q = ((to + from) * t) - from; + else + q = from + ((to - from) * t); + return normalize(q); +} + +// lerp for quaternions defaults to nlerp +__forceinline Quaternion lerp(const Quaternion &from, const Quaternion &to, float t) { + Quaternion q; + if(dot(from, to) < 0) + q = ((to + from) * t) - from; + else + q = from + ((to - from) * t); + return normalize(q); +} + +// Scales the angle in the rotation the quaternion represents by t. +__forceinline Quaternion scale_angle(const Quaternion &from, float t) +{ + Vector3 axis; + float theta; + decompose(from, &axis, &theta); + return quaternion(axis, theta*t); +} + +__forceinline bool is_zero(const Quaternion &q) +{ + return q.x == 0 && q.y == 0 && q.z == 0 && q.w == 0; +} + +__forceinline float norm(const Quaternion &q) +{ + return math::square_root(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w); +} + +__forceinline float one_norm(const Quaternion &q) +{ + return math::abs(q.x) + math::abs(q.y) + math::abs(q.z) + math::abs(q.w); +} + +__forceinline float infinity_norm(const Quaternion &q) +{ + return math::max( + math::max(math::abs(q.x), + math::abs(q.y)), + math::max(math::abs(q.z), + math::abs(q.w)) ); +} + +__forceinline Vector3 rotate(const Quaternion &q, const Vector3 &v) +{ + Quaternion v_quat = quaternion(v.x, v.y, v.z, 0.0f); + Quaternion result(q * v_quat * conjugate(q)); + return vector3(result.x, result.y, result.z); +} + +// Conversion Methods +__forceinline Matrix4x4 matrix4x4(const Quaternion &q) { + const float d = dot(q,q); + float s; + if(d) + s = 2.0f / d; + else + s = 1.0f; + + const float xs = q.x * s; + const float ys = q.y * s; + const float zs = q.z * s; + const float wx = q.w * xs; + const float wy = q.w * ys; + const float wz = q.w * zs; + const float xx = q.x * xs; + const float xy = q.x * ys; + const float xz = q.x * zs; + const float yy = q.y * ys; + const float yz = q.y * zs; + const float zz = q.z * zs; + + Matrix4x4 m = { + (1.0f - yy - zz), (xy + wz), (xz - wy), 0.0f, + (xy - wz), (1.0f - xx - zz), (yz + wx), 0.0f, + (xz + wy), (yz - wx), (1.0f - xx - yy), 0.0f, + 0.f, 0.f, 0.f, 1.f + }; + + return m; +} + +__forceinline Matrix4x4 matrix4x4(const Quaternion &q, const Vector3 &p) +{ + const float d = dot(q,q); + float s; + if(d) + s = 2.0f / d; + else + s = 1.0f; + + const float xs = q.x * s; + const float ys = q.y * s; + const float zs = q.z * s; + const float wx = q.w * xs; + const float wy = q.w * ys; + const float wz = q.w * zs; + const float xx = q.x * xs; + const float xy = q.x * ys; + const float xz = q.x * zs; + const float yy = q.y * ys; + const float yz = q.y * zs; + const float zz = q.z * zs; + + Matrix4x4 m = { + (1.0f - yy - zz), (xy + wz), (xz - wy), 0.0f, + (xy - wz), (1.0f - xx - zz), (yz + wx), 0.0f, + (xz + wy), (yz - wx), (1.0f - xx - yy), 0.0f, + p.x, p.y, p.z, 1.f + }; + + return m; +} + +__forceinline void decompose(const Quaternion &q, Vector3 *axis, float *theta) +{ + Vector3 a = vector3(q.x, q.y, q.z); + float s = length(a); + float c = q.w; + float half_theta = atan2f(s, c); + *theta = half_theta * 2.0f; + *axis = s ? a / s : vector3(1,0,0); +} + +__forceinline float angle(const Quaternion &q) +{ + Vector3 a = vector3(q.x, q.y, q.z); + float s = length(a); + float c = q.w; + float half_theta = atan2f(s, c); + return half_theta * 2.0f; +} + +__forceinline void lerp(const Matrix4x4 &m1, const Matrix4x4 &m2, float t, Matrix4x4 &m) +{ + Vector3 p = lerp(translation(m1), translation(m2), t); + Quaternion q = lerp(quaternion(m1), quaternion(m2), t); + m = matrix4x4(q, p); +} + +inline Quaternion quaternion_orthogonal(const Matrix4x4 &mat) { + static const int kx = 0; + static const int ky = 1; + static const int kz = 2; + static const int kw = 3; + + struct ShadowMatrix { + float m[4][4]; + }; + const ShadowMatrix* m = reinterpret_cast(&mat); + Quaternion r; + float *q = reinterpret_cast(&r); + + // This code can be optimized for m[kw][kw] = 1, which + // should always be true. This optimization is excluded + // here for clarity. + float trace = m->m[kx][kx] + m->m[ky][ky] + m->m[kz][kz] + m->m[kw][kw]; + float four_d; + int i,j,k; + + if (trace >= 1.0) // w >= 0.5 + { + four_d = 2.0f*math::square_root(trace); + q[kw] = -four_d / 4.0f; + const float one_over_coeff = 1.0f / four_d; + q[kx] = (m->m[kz][ky] - m->m[ky][kz])*one_over_coeff; + q[ky] = (m->m[kx][kz] - m->m[kz][kx])*one_over_coeff; + q[kz] = (m->m[ky][kx] - m->m[kx][ky])*one_over_coeff; + } + else + { + // Find the largest component + if (m->m[kx][kx] > m->m[ky][ky]) + i = kx; + else + i = ky; + if (m->m[kz][kz] > m->m[i][i]) + i = kz; + + // Set j and k to next two components + j = (1 << i) & 3; + k = (1 << j) & 3; + + four_d = 2.0f*math::square_root(m->m[i][i] - m->m[j][j] - m->m[k][k] + 1.0f ); + q[i] = four_d/4.0f; + + const float one_over_coeff = 1.0f / four_d; + q[j] = (m->m[j][i] + m->m[i][j])*one_over_coeff; + q[k] = (m->m[k][i] + m->m[i][k])*one_over_coeff; + q[kw] = -(m->m[k][j] - m->m[j][k])*one_over_coeff; + } + + return r; +} + +inline Quaternion quaternion(const Matrix4x4 &mat) +{ + static const int kx = 0; + static const int ky = 1; + static const int kz = 2; + static const int kw = 3; + + const Vector3 scale = stingray_plugin_foundation::scale(mat); + const float *s = reinterpret_cast(&scale); + + // If scale is small return an identity quaternion + const float eps = 1e-5; + if (scale.x > -eps && scale.x < eps || scale.y > -eps && scale.y < eps || scale.z > -eps && scale.z < eps) + return quaternion_identity(); + + struct ShadowMatrix { + float m[4][4]; + }; + const ShadowMatrix* m = reinterpret_cast(&mat); + Quaternion r; + float *q = reinterpret_cast(&r); + + // This code can be optimized for m[kw][kw] = 1, which + // should always be true. This optimization is excluded + // here for clarity. + const float trace = m->m[kx][kx] / s[kx] + m->m[ky][ky] / s[ky] + m->m[kz][kz] / s[kz] + m->m[kw][kw]; + + if (trace >= 1.0) // w >= 0.5 + { + const float four_d = 2.0f*math::square_root(trace); + q[kw] = -four_d / 4.0f; + const float one_over_coeff = 1.0f / four_d; + q[kx] = (m->m[kz][ky] / s[kz] - m->m[ky][kz] / s[ky])*one_over_coeff; + q[ky] = (m->m[kx][kz] / s[kx] - m->m[kz][kx] / s[kz])*one_over_coeff; + q[kz] = (m->m[ky][kx] / s[ky] - m->m[kx][ky] / s[kx])*one_over_coeff; + } + else + { + // Find the largest component + int i; + if (m->m[kx][kx] / s[kx] > m->m[ky][ky] / s[ky]) + i = kx; + else + i = ky; + if (m->m[kz][kz] / s[kz] > m->m[i][i] / s[i]) + i = kz; + + // Set j and k to next two components + const int j = (1 << i) & 3; + const int k = (1 << j) & 3; + + const float four_d = 2.0f*math::square_root(m->m[i][i] / s[i] - m->m[j][j] / s[j] - m->m[k][k] / s[k] + 1.0f ); + q[i] = four_d/4.0f; + + const float one_over_coeff = 1.0f / four_d; + q[j] = (m->m[j][i] / s[j] + m->m[i][j] / s[i])*one_over_coeff; + q[k] = (m->m[k][i] / s[k] + m->m[i][k] / s[i])*one_over_coeff; + q[kw] = -(m->m[k][j] / s[k] - m->m[j][k] / s[j])*one_over_coeff; + } + + return r; +} + +inline Quaternion quaternion(const Matrix3x3 &mat) +{ + static const int kx = 0; + static const int ky = 1; + static const int kz = 2; + static const int kw = 3; + + struct ShadowMatrix { + float m[3][3]; + }; + const ShadowMatrix* m = reinterpret_cast(&mat); + Quaternion r; + float *q = reinterpret_cast(&r); + + float trace = m->m[kx][kx] + m->m[ky][ky] + m->m[kz][kz] + 1; + float four_d; + int i,j,k; + + if (trace >= 1.0) // w >= 0.5 + { + four_d = 2.0f*math::square_root(trace); + q[kw] = -four_d / 4.0f; + const float one_over_coeff = 1.0f / four_d; + q[kx] = (m->m[kz][ky] - m->m[ky][kz])*one_over_coeff; + q[ky] = (m->m[kx][kz] - m->m[kz][kx])*one_over_coeff; + q[kz] = (m->m[ky][kx] - m->m[kx][ky])*one_over_coeff; + } + else + { + // Find the largest component + if (m->m[kx][kx] > m->m[ky][ky]) + i = kx; + else + i = ky; + if (m->m[kz][kz] > m->m[i][i]) + i = kz; + + // Set j and k to next two components + j = (1 << i) & 3; + k = (1 << j) & 3; + + four_d = 2.0f*math::square_root(m->m[i][i] - m->m[j][j] - m->m[k][k] + 1.0f ); + q[i] = four_d/4.0f; + + const float one_over_coeff = 1.0f / four_d; + q[j] = (m->m[j][i] + m->m[i][j])*one_over_coeff; + q[k] = (m->m[k][i] + m->m[i][k])*one_over_coeff; + q[kw] = -(m->m[k][j] - m->m[j][k])*one_over_coeff; + } + + return r; +} + +inline Quaternion quaternion(const Vector3 &y, const Vector3 &z) +{ + Vector3 x = cross(y,z); + Matrix4x4 tm = matrix4x4_identity(); + x_axis(tm) = x; + y_axis(tm) = y; + z_axis(tm) = z; + return quaternion_orthogonal(tm); +} + +} diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/random.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/random.h new file mode 100644 index 0000000..9f5f63b --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/random.h @@ -0,0 +1,83 @@ +#pragma once + +#include "platform.h" +#include "math.h" + +namespace stingray_plugin_foundation { + +// A fast LCG random number generator. The numbers it produces are not completely +// random but it is faster and more random than vanilla C rand(). It should be good +// enough for most purposes. +class Random +{ + // This variable should NOT need to be volatile, but there is a bug in VC++. If + // this variable is not volatile Vector3(random(), random(), random()) sets all + // components to the same value. + volatile unsigned _state; + +public: + static const unsigned A = 1664525 , B = 1013904223; + + __forceinline Random() : _state(0) {} + __forceinline Random(unsigned s) : _state(s) {} + __forceinline unsigned seed() const {return _state;} + __forceinline void set_seed(unsigned s) {_state = s;} + + __forceinline void next() {_state = A * _state + B;} + __forceinline unsigned rand_u32() {next(); return _state;} + __forceinline double rand_double() {return double(rand_u32()) * (0.5 / 0x80000000);} + __forceinline float rand_float() {return float(rand_u32()) * (0.5f / 0x80000000);} + + __forceinline double operator()(double max) {return max * rand_double();} + __forceinline double operator()(double min, double max) {return min + (max - min)*rand_double();} + + __forceinline float operator()() {return rand_float();} + __forceinline float operator()(float max) {return max * rand_float();} + __forceinline float operator()(float min, float max) {return min + (max - min)*rand_float();} + + __forceinline int operator()(int max_plus_1) {return (int)floor(max_plus_1*rand_double());} + __forceinline int operator()(int min, int max) {return (int)floor(min + (max - min + 1)*rand_double());} + + __forceinline unsigned operator()(unsigned max_plus_1) {return unsigned(max_plus_1*rand_double());} + __forceinline unsigned operator()(unsigned min, unsigned max) {return unsigned(min + (max - min + 1)*rand_double());} + + // Convenience methods -- coin toss + __forceinline bool heads() {return rand_float() < 0.5f;} + __forceinline bool tails() {return rand_float() > 0.5f;} + + // Convenience methods -- random picking + template __forceinline T &pick(T &t1, T &t2) {return rand_float() < 0.5f ? t1 : t2;} + template __forceinline const T &pick(const T &t1, const T &t2) {return rand_float() < 0.5f ? t1 : t2;} + template __forceinline T &pick( T &v ) {return v[ (*this)(v.size()) ];} + template __forceinline const T &pick( const T &v ) {return v[ (*this)(v.size()) ];} + + // Random pick with weight. T must have "weight" field. + template __forceinline T &pick_weighted( T &v ) { + float sum = 0; + typename T::iterator it, begin = v.begin(), end = v.end(); + for (it=begin; itweight; + float pick = (*this)(sum); + float acc = 0; + for (it=begin; itweight; + if (pick < acc) return *it; + } + return v.back(); + } + template __forceinline const T &pick_weighted( T &v ) { + float sum = 0; + typename T::const_iterator it, begin = v.begin(), end = v.end(); + for (it=begin; itweight; + float pick = (*this)(sum); + float acc = 0; + for (it=begin; itweight; + if (pick < acc) return *it; + } + return v.back(); + } +}; + +} diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/scene_flags.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/scene_flags.h new file mode 100644 index 0000000..65d7ef7 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/scene_flags.h @@ -0,0 +1,41 @@ +#pragma once + +namespace stingray_plugin_foundation { + +struct SceneFlags +{ + unsigned *_data; + unsigned _allocated_flag_count; + void *_allocator; + + // Sets the i'th flag + inline void set(unsigned i) { + i++; +#if defined(_DEBUG) + XENSURE(i < _allocated_flag_count); +#endif + _data[i/32] |= (1 << (i%32)); + set_any(); + } + + // Clears the i'th flag (does not update ANY flag). + inline void clear(unsigned i) { + i++; +#if defined(_DEBUG) + XENSURE(i < _allocated_flag_count); +#endif + _data[i/32] &= ~(1 << (i%32)); + } + + +protected: + + inline void set_any() { +#if defined(_DEBUG) + XENSURE(_allocated_flag_count > 0); +#endif + _data[0] |= 1; + } +}; + +} // namespace stingray_plugin_foundation diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/scene_tree.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/scene_tree.h new file mode 100644 index 0000000..7984745 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/scene_tree.h @@ -0,0 +1,490 @@ +#pragma once + +#include "matrix4x4.h" +#include "allocator.h" +#include "hash_function.h" +#include "hash_function_string.h" +#include "vector.h" +#include "hash_map.h" +#include "id_string.h" + +namespace stingray_plugin_foundation { + + +enum ChannelType { + CT_FLOAT1 = 0, + CT_FLOAT2, + CT_FLOAT3, + CT_FLOAT4, + CT_MATRIX4x4, + CT_QUATERNION, + CT_FLOAT3_CMP_11_11_10, + CT_HALF1, + CT_HALF2, + CT_HALF3, + CT_HALF4, + CT_UBYTE4, + CT_SHORT1, + CT_SHORT2, + CT_SHORT3, + CT_SHORT4, + CT_COUNT +}; + +uint32_t channel_size(ChannelType type); +const char *Parameter_LocalTransform(); +const char *Channel_LocalTransform(); +const char *Channel_BlendShapeWeight(); + +// General container for storing data +struct Stream { + ALLOCATOR_AWARE; + Stream(Allocator &a) : data(a), channels(a), size(0), stride(0) { } + + // Structure describing a single data channel in the stream + struct Channel { + ALLOCATOR_AWARE; + Channel(Allocator &a) : name(a) { } + + // Semantic name of channel + DynamicString name; + + // Semantic index of channel + unsigned index; + + // Data contained within channel + ChannelType type; + }; + + // List of channels describing the contents of this stream + Vector channels; + + // Number of elements in stream + unsigned size; + + // Stride in bytes between two elements + unsigned stride; + + // Stream data + Array data; +}; + +bool operator==(const Stream::Channel &lhs, const Stream::Channel &rhs); +bool operator!=(const Stream::Channel &lhs, const Stream::Channel &rhs); + +typedef Vector Streams; + +// Structure that represents a scene node +struct Node { + ALLOCATOR_AWARE; + Node(Allocator &a) : parent(a), children(a), geometries(a), viewport_visible(true), has_local_mirroring(false) { } + + + // Name of parent (can be empty) + DynamicString parent; + + // List with names of this nodes children + Vector children; + + // Local transformation matrix + Matrix4x4 local; + + // List with names of geometries attached to this node + Vector geometries; + + // Initial visibility preference (overridden by renderables section of .unit) + bool viewport_visible; + + // We keep this information here to avoid computing the local transform determinant + // every time we want to know whether the transform is mirrored or not. + // NOTE: we neither serialize this information but compute it from local once read. + bool has_local_mirroring; + + void swap(Node &o) { + parent.swap(o.parent); + children.swap(o.children); + std::swap(local, o.local); + geometries.swap(o.geometries); + std::swap(viewport_visible, o.viewport_visible); + std::swap(has_local_mirroring, o.has_local_mirroring); + } +}; + +// Structure that represents mesh topology +struct Indices { + ALLOCATOR_AWARE; + Indices(Allocator &a) : streams(a), n_indices(0), type(TRIANGLE_LIST) { } + + // Number of indices + unsigned n_indices; + + // Primitive type - currently we are only handling TRIANGLE_LIST + enum PrimitiveType { TRIANGLE_LIST }; + PrimitiveType type; + + struct Stream { + ALLOCATOR_AWARE; + Stream(Allocator &a) : indices(a) { } + + Array indices; + }; + // List of indices for each stream in a mesh + Vector streams; +}; + +// Structure describing a Skin modifier +struct Skin { + ALLOCATOR_AWARE; + Skin(Allocator &a) : joints(a), max_affecting_bones(0) { } + + // Describes a skin joint + struct Joint { + ALLOCATOR_AWARE; + Joint(Allocator &a) : name(a) { } + + // Name of joint + DynamicString name; + // Inverse bind matrix for joint + Matrix4x4 inv_bind_matrix; + }; + + // Formerly "Bind shape matrix for skin". + // This information is actually stored by cluster in FBX and there is no such + // global bind matrix anymore there. Nevertheless, it is used in BSI exporters + // so we keep it for backward-compatibility there and remove it from anywhere + // else, namely the engine. +#ifdef BSI_PLUGIN + Matrix4x4 bind_matrix; +#endif + + // Maximum number of influences + unsigned max_affecting_bones; + + // Skin joints + Vector joints; +}; + +// Structure describing a mesh instance +struct GeometryInstance { + ALLOCATOR_AWARE; + GeometryInstance(Allocator &a) : geometry(a), materials(a) { } + + DynamicString geometry; + Vector materials; +}; + +// Structure describing a mesh +struct Geometry { + ALLOCATOR_AWARE; + Geometry(Allocator &a) : name(a), streams(a), indices(a), materials(a), skin(a), primitive_smoothing(a), blend_shape_targets(a), shadow_caster(true), vertex_position_remapping(a), vertex_normal_remapping(a) { } + + DynamicString name; + + // List of vertex data streams + Streams streams; + + // Indices of mesh + Indices indices; + + // Name of skin if mesh is skinned + DynamicString skin; + + // Structure describing a mesh material + struct Material { + ALLOCATOR_AWARE; + Material(Allocator &a) : name(a), primitives(a) { } + + // Material name + DynamicString name; + + // List of primitive indices that the material is assigned to + Array primitives; + }; + + // List of materials assigned to this mesh + Vector materials; + + // Per primitive smoothing group information + Array primitive_smoothing; + + // Structure describing a blend shape target + struct BlendShapeTarget { + ALLOCATOR_AWARE; + BlendShapeTarget(Allocator &a) : name(a), streams(a) { } + + // Name of blend_shape target + DynamicString name; + + // Blend Shape Target vertex data streams + Streams streams; + }; + + // BlendShape targets + Vector blend_shape_targets; + + // Initial shadow preference (overridden by renderables section of .unit) + bool shadow_caster; + + Array vertex_position_remapping; + Array vertex_normal_remapping; +}; + +// Structure describing a light +struct Light { + + enum DefinitionType { // same enum values as found in: source\engine\engine\scene\light.h + OMNI = 0, + SPOT = 1, + BOX = 2, + DIRECTIONAL = 3 + }; + DefinitionType type; + + float color[4]; + + float falloff_start; // units are meters + float falloff_end; // units are meters + + float spot_angle_start; // radians + float spot_angle_end; // radians + + bool cast_shadow; +}; + +// Structure describing a camera +struct Camera { + + enum DefinitionType { // same enum values as found in source\engine\engine\scene\camera.h + ORTHOGRAPHIC, + PERSPECTIVE + }; + DefinitionType type; + + float near_plane; // units are meters + float far_plane; // units are meters + float vertical_fov; // units are radians +}; + +// Structure describing a animation. +// there are 4 types of animation curve : +// NODE_LOCAL_TRANSFORM : in this case, parameter == "local_tm". The animation has 1 channel of CT_MATRIX4x4 of name "matrix". +// NODE_PROPERTY : in this case, parameter is the name of the animated property. The animation has up to 4 channels of CT_FLOAT1 named "0","1","2","3" +// NODE_BLENDSHAPECHANNEL : in this case, parameter is the name of the blend shape channel. The animation has 1 channel of CT_FLOAT1 named "weight" +// MATERIAL_PROPERTY : in this case, parameter is the name of the animated property. The animation has up to 4 channels of CT_FLOAT1 named "0","1","2","3" +struct Animation { + ALLOCATOR_AWARE; + + Animation(Allocator &a) : node(a), parameter(a), times(a), data(a) { } + + bool is_local_transform_anim() const { return data.channels.size() == 1 && data.channels[0].type == CT_MATRIX4x4 && parameter == Parameter_LocalTransform() && data.channels[0].name == Channel_LocalTransform(); } + + // Name of node this animation affects, or name of the material + DynamicString node; + + // Name of affected parameter + DynamicString parameter; + + // List of time keys + Array times; + + // Data stream containing the animation data (1:1 mapping with 'times' indices) + Stream data; +}; + +// Structure describing an animation take +struct AnimationTake { + ALLOCATOR_AWARE; + + AnimationTake(Allocator &a) : animations(a), start_time(0), end_time(0), nb_samples(0) { } + + // infos + float start_time; + float end_time; + unsigned nb_samples; + + // animations for each node + Vector animations; +}; + +// Structure describing a surface material +struct SurfaceMaterial { + ALLOCATOR_AWARE; + + SurfaceMaterial(Allocator& a) : type(LAMBERT), properties(a), nb_influences(0) { } + + // Type of definition + enum DefinitionType { + LAMBERT = 0, + PHONG = 1, + SHADER = 2 + }; + DefinitionType type; + + // Next version, we should consider adding a Datatype attribute so we know what kind of data is stored + // by the property. This will help representing shaders parameters since they can be: bool, ints, enums, + // floats, etc... + struct Property { + ALLOCATOR_AWARE; + + Property(Allocator& a) : n_integers(0), n_floats(0), name(a), value_string(a), textures(a) { } + + unsigned n_integers; + int integer; + unsigned n_floats; + float floats[4]; + + DynamicString name; + DynamicString value_string; + + // reference to textures attached to this property + Vector textures; + }; + + typedef Vector Properties; + Properties properties; + + // number of bones influences [0..4] + unsigned nb_influences; +}; + +// Structure describing a texture +struct Texture { + ALLOCATOR_AWARE; + + Texture(Allocator& a) : file_path(a), relative_path(a), embedded(false), uv_rotation(0) + { + uv_offset.x = uv_offset.y = 0; + uv_scale.x = uv_scale.y = 1; + } + + DynamicString file_path; + DynamicString relative_path; + + // was embedded in source .fbx file + bool embedded; + + Vector2 uv_offset; + Vector2 uv_scale; + float uv_rotation; +}; + +// Structure describing a Level of Details +struct LevelOfDetail { + ALLOCATOR_AWARE; + + LevelOfDetail(Allocator& a) : orientation_node(a), bounding_volume(a), requires_predefined_pct(0), steps(a) { } + + DynamicString orientation_node; + DynamicString bounding_volume; + bool requires_predefined_pct; + + struct Step { + ALLOCATOR_AWARE; + + Step(Allocator& a) : nodes(a), min_pct(0.0f), max_pct(1.0f) {} + + Vector nodes; + float min_pct; + float max_pct; + }; + + Vector steps; +}; + + +// Structure describing how a scene is interpreted when importing + +struct SceneImportOptions { + SceneImportOptions() : + combine_meshes(false), + combine_meshes_by_material(false), + reverse_forward_axis(false), + skip_create_extra_root(false), + skip_textures(false), + skip_lights(false), + skip_cameras(false), + create_missing_uvs(false), + tangents(TANGENTS_IMPORT) + { } + + enum TangentsOption {TANGENTS_IMPORT, TANGENTS_MIKKTSPACE}; + + bool combine_meshes; + bool combine_meshes_by_material; + bool reverse_forward_axis; + bool skip_create_extra_root; + bool skip_textures; + bool skip_lights; + bool skip_cameras; + bool create_missing_uvs; + TangentsOption tangents; +}; + +// Structure describing a scene +struct SceneDatabase { + SceneDatabase(Allocator &a) : nodes(a), roots(a), geometry_instances(a), geometries(a), lights(a), cameras(a), skins(a), materials(a), textures(a), lods(a), anim_takes(a), source_path(a), properties(a), geometry_entries(a) { } + Allocator &allocator() const {return nodes.allocator();} + + typedef HashMap Nodes; + Nodes nodes; + Vector roots; + + typedef HashMap GeometryInstances; + GeometryInstances geometry_instances; + + typedef Vector Geometries; + Geometries geometries; + + typedef HashMap Lights; + Lights lights; + + typedef HashMap Cameras; + Cameras cameras; + + typedef HashMap Skins; + Skins skins; + + typedef HashMap Materials; + Materials materials; + + typedef HashMap Textures; + Textures textures; + + typedef HashMap Lods; + Lods lods; + + typedef HashMap AnimTakes; + AnimTakes anim_takes; + + DynamicString source_path; + + SceneImportOptions import_options; + + typedef HashMap Properties; + Properties properties; + + ////////////////////////////////////////////////////////////////////////// + typedef HashMap GeometryEntries; + GeometryEntries geometry_entries; + + Geometry *find_geometry(const char *name) { + const IdString32 id(name); + auto it = geometry_entries.find(id); + return it != geometry_entries.end() ? &geometries[it->second] : nullptr; + } + + Geometry &add_geometry(const char *name) { + const IdString32 id(name); + geometry_entries.insert(id, geometries.size()); + + Geometry &geom = geometries.extend(); + geom.name = name; + return geom; + } +}; + + +} + +#include "scene_tree.inl" + diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/scene_tree.inl b/lib/dt_p2p/stingray_sdk/plugin_foundation/scene_tree.inl new file mode 100644 index 0000000..c33edb7 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/scene_tree.inl @@ -0,0 +1,42 @@ +namespace stingray_plugin_foundation { + +__forceinline uint32_t channel_size(ChannelType type) { + switch (type) { + case CT_FLOAT1: return 1*sizeof(float); + case CT_FLOAT2: return 2*sizeof(float); + case CT_FLOAT3: return 3*sizeof(float); + case CT_FLOAT4: return 4*sizeof(float); + case CT_MATRIX4x4: return 16*sizeof(float); + case CT_QUATERNION: return 4*sizeof(float); + case CT_FLOAT3_CMP_11_11_10: return sizeof(unsigned); + case CT_HALF1: return 1*sizeof(short); + case CT_HALF2: return 2*sizeof(short); + case CT_HALF3: return 3*sizeof(short); + case CT_HALF4: return 4*sizeof(short); + case CT_UBYTE4: return sizeof(unsigned); + case CT_SHORT1: return 1*sizeof(short); + case CT_SHORT2: return 2*sizeof(short); + case CT_SHORT3: return 3*sizeof(short); + case CT_SHORT4: return 4*sizeof(short); + default: return 0; + } + + return 0; +} + +__forceinline const char *Parameter_LocalTransform() +{ + return "matrix"; +} + +__forceinline const char *Channel_LocalTransform() +{ + return "local_tm"; +} + +__forceinline const char *Channel_BlendShapeWeight() +{ + return "blend_shape_channel_weight"; +} + +} diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/scene_tree_api_convert.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/scene_tree_api_convert.h new file mode 100644 index 0000000..a20882c --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/scene_tree_api_convert.h @@ -0,0 +1,8 @@ +#pragma once + +#include "scene_tree.h" +#include "../engine_plugin_api/plugin_scene_database_api.h" + +namespace stingray_plugin_foundation { + #include "scene_tree_api_convert.inl" +} diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/scene_tree_api_convert.inl b/lib/dt_p2p/stingray_sdk/plugin_foundation/scene_tree_api_convert.inl new file mode 100644 index 0000000..65dd184 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/scene_tree_api_convert.inl @@ -0,0 +1,498 @@ + +template +__forceinline ValueType *allocate_plugin_array(uint32_t size, Allocator &a) +{ + if (size == 0) + return nullptr; + Array *container = MAKE_NEW(a, Array, size, a); + return &(*container)[0]; +} + +__forceinline void to_plugin(const char *&dest, const DynamicString &source) +{ + dest = !source.empty() ? source.c_str() : nullptr; +} +__forceinline void from_plugin(DynamicString &dest, const char *source) +{ + dest = source ? source : ""; +} + +__forceinline void to_plugin(SDB_StringList &dest, const Vector &source, Allocator &a) +{ + dest.size = source.size(); + dest.data = dest.size > 0 ? allocate_plugin_array(dest.size, a) : nullptr; + for (uint32_t i=0; i < dest.size; ++i) { + to_plugin(dest.data[i], source[i]); + } +} +__forceinline void from_plugin(Vector &dest, const SDB_StringList &source) +{ + dest.resize(source.size); + for (uint32_t i=0; i < source.size; ++i) { + from_plugin(dest[i], source.data[i]); + } +} + +template +__forceinline void vector_to_plugin_internal(uint32_t &dest_size, DestContainerType &dest_data, DestDataType *dummy_value, SourceContainerType &source, Allocator &a) +{ + dest_size = source.size(); + dest_data = dest_size > 0 ? allocate_plugin_array(dest_size, a) : nullptr; + for (uint32_t i=0; i < dest_size; ++i) { + to_plugin(dest_data[i], source[i], a); + } +} +template +__forceinline void vector_to_plugin(uint32_t &dest_size, DestContainerType &dest_data, SourceContainerType &source, Allocator &a) +{ + vector_to_plugin_internal(dest_size, dest_data, dest_data, source, a); +} +template +__forceinline void vector_from_plugin(uint32_t source_size, DestContainerType &dest, SourceContainerType &source_data) +{ + dest.resize(source_size); + for (uint32_t i=0; i < source_size; ++i) { + from_plugin(dest[i], source_data[i]); + } +} + +template +__forceinline void array_to_plugin(uint32_t &dest_size, T *&dest_data, const Array &source, Allocator &a) +{ + dest_size = source.size(); + if (dest_size > 0) { + dest_data = allocate_plugin_array(dest_size, a); + memcpy(dest_data, &source[0], dest_size * sizeof(T)); + } else { + dest_data = nullptr; + } +} +template +__forceinline void array_from_plugin(const uint32_t source_size, Array &dest, const T *source_data) +{ + dest.resize(source_size); + if (source_size > 0) { + memcpy(&dest[0], source_data, source_size * sizeof(T)); + } +} + +template +__forceinline void hashmap_to_plugin_internal(ExternalContainerType &dest, InternalContainerType &source, ValueType *dummy_value, Allocator &a) +{ + dest.size = source.size(); + dest.data = dest.size > 0 ? allocate_plugin_array(dest.size, a) : nullptr; + uint32_t i=0; + for (const auto &it : source) { + to_plugin(dest.data[i++], it.second, it.first.c_str(), a); + } +} + +template +__forceinline void hashmap_to_plugin(ExternalContainerType &dest, InternalContainerType &source, Allocator &a) +{ + hashmap_to_plugin_internal(dest, source, dest.data, a); +} + +template +__forceinline void hashmap_from_plugin(InternalContainerType &dest, ExternalContainerType &source) +{ + dest.reserve(source.size); + for (uint32_t i=0; i < source.size; ++i) { + auto &dest_item = dest[source.data[i].name]; + from_plugin(dest_item, source.data[i]); + } +} + +////////////////////////////////////////////////////////////////////////////////////////// + +__forceinline void to_plugin(SDB_Channel &dest, const Stream::Channel &source, Allocator &a) +{ + to_plugin(dest.name, source.name); + dest.index = source.index; + dest.type = (SDB_ChannelType)source.type; +} +__forceinline void from_plugin(Stream::Channel &dest, const SDB_Channel &source) +{ + from_plugin(dest.name, source.name); + dest.index = source.index; + dest.type = (ChannelType)source.type; +} + +__forceinline void to_plugin(SDB_Stream &dest, const Stream &source, Allocator &a) +{ + vector_to_plugin(dest.n_channels, dest.channels, source.channels, a); + dest.size = source.size; + dest.stride = source.stride; + dest.n_data = source.data.size(); + dest.data = dest.n_data > 0 ? (uint8_t *)&source.data[0] : nullptr; +} +__forceinline void from_plugin(Stream &dest, const SDB_Stream &source) +{ + vector_from_plugin(source.n_channels, dest.channels, source.channels); + dest.size = source.size; + dest.stride = source.stride; + dest.data.resize(source.n_data); + if (source.n_data > 0) { + memcpy(&dest.data[0], source.data, source.n_data); + } +} + +__forceinline void to_plugin(SDB_Node &dest, const Node &source, const char *name, Allocator &a) +{ + dest.name = name; + to_plugin(dest.parent, source.parent); + to_plugin(dest.children, source.children, a); + memcpy(dest.local, &source.local, sizeof(Matrix4x4)); + to_plugin(dest.geometries, source.geometries, a); + dest.viewport_visible = source.viewport_visible; + dest.has_local_mirroring = source.has_local_mirroring; +} +__forceinline void from_plugin(Node &dest, const SDB_Node &source) +{ + from_plugin(dest.parent, source.parent); + from_plugin(dest.children, source.children); + memcpy(&dest.local, &source.local, sizeof(Matrix4x4)); + from_plugin(dest.geometries, source.geometries); + dest.viewport_visible = source.viewport_visible == 1; + dest.has_local_mirroring = source.has_local_mirroring == 1; +} + +__forceinline void to_plugin(SDB_IndicesStream &dest, const Indices::Stream &source, Allocator &a) +{ + array_to_plugin(dest.n_indices, dest.indices, source.indices, a); +} +__forceinline void from_plugin(Indices::Stream &dest, const SDB_IndicesStream &source) +{ + array_from_plugin(source.n_indices, dest.indices, source.indices); +} + +__forceinline void to_plugin(SDB_Indices &dest, const Indices &source, Allocator &a) +{ + dest.n_indices = source.n_indices; + vector_to_plugin(dest.n_streams, dest.streams, source.streams, a); +} +__forceinline void from_plugin(Indices &dest, const SDB_Indices &source) +{ + dest.n_indices = source.n_indices; + vector_from_plugin(source.n_streams, dest.streams, source.streams); +} + +__forceinline void to_plugin(SDB_Joint &dest, const Skin::Joint &source, Allocator &a) +{ + to_plugin(dest.name, source.name); + memcpy(dest.inv_bind_matrix, &source.inv_bind_matrix, sizeof(Matrix4x4)); +} +__forceinline void from_plugin(Skin::Joint &dest, const SDB_Joint &source) +{ + from_plugin(dest.name, source.name); + memcpy(&dest.inv_bind_matrix, source.inv_bind_matrix, sizeof(Matrix4x4)); +} + +__forceinline void to_plugin(SDB_Skin &dest, const Skin &source, const char *name, Allocator &a) +{ + dest.name = name; + dest.max_affecting_bones = source.max_affecting_bones; + vector_to_plugin(dest.n_joints, dest.joints, source.joints, a); +} +__forceinline void from_plugin(Skin &dest, const SDB_Skin &source) +{ + dest.max_affecting_bones = source.max_affecting_bones; + vector_from_plugin(source.n_joints, dest.joints, source.joints); +} + +__forceinline void to_plugin(SDB_GeometryInstance &dest, const GeometryInstance &source, const char *name, Allocator &a) +{ + dest.name = name; + to_plugin(dest.geometry, source.geometry); + to_plugin(dest.materials, source.materials, a); +} +__forceinline void from_plugin(GeometryInstance &dest, const SDB_GeometryInstance &source) +{ + from_plugin(dest.geometry, source.geometry); + from_plugin(dest.materials, source.materials); +} + +__forceinline void to_plugin(SDB_GeometryMaterial &dest, const Geometry::Material &source, Allocator &a) +{ + to_plugin(dest.name, source.name); + array_to_plugin(dest.n_primitives, dest.primitives, source.primitives, a); +} +__forceinline void from_plugin(Geometry::Material &dest, const SDB_GeometryMaterial &source) +{ + from_plugin(dest.name, source.name); + array_from_plugin(source.n_primitives, dest.primitives, source.primitives); +} + +__forceinline void to_plugin(SDB_GeometryBlendShapeTarget &dest, const Geometry::BlendShapeTarget &source, Allocator &a) +{ + to_plugin(dest.name, source.name); + vector_to_plugin(dest.n_streams, dest.streams, source.streams, a); +} +__forceinline void from_plugin(Geometry::BlendShapeTarget &dest, const SDB_GeometryBlendShapeTarget &source) +{ + from_plugin(dest.name, source.name); + vector_from_plugin(source.n_streams, dest.streams, source.streams); +} + +__forceinline void to_plugin(SDB_Geometry &dest, const Geometry &source, Allocator &a) +{ + to_plugin(dest.name, source.name); + vector_to_plugin(dest.n_streams, dest.streams, source.streams, a); + to_plugin(dest.indices, source.indices, a); + to_plugin(dest.skin, source.skin); + vector_to_plugin(dest.n_materials, dest.materials, source.materials, a); + array_to_plugin(dest.n_primitive_smoothing, dest.primitive_smoothing, source.primitive_smoothing, a); + vector_to_plugin(dest.n_blend_shape_targets, dest.blend_shape_targets, source.blend_shape_targets, a); + dest.shadow_caster = source.shadow_caster; + array_to_plugin(dest.n_vertex_position_remapping, dest.vertex_position_remapping, source.vertex_position_remapping, a); + array_to_plugin(dest.n_vertex_normal_remapping, dest.vertex_normal_remapping, source.vertex_normal_remapping, a); +} +__forceinline void from_plugin(Geometry &dest, const SDB_Geometry &source) +{ + from_plugin(dest.name, source.name); + vector_from_plugin(source.n_streams, dest.streams, source.streams); + from_plugin(dest.indices, source.indices); + from_plugin(dest.skin, source.skin); + vector_from_plugin(source.n_materials, dest.materials, source.materials); + array_from_plugin(source.n_primitive_smoothing, dest.primitive_smoothing, source.primitive_smoothing); + vector_from_plugin(source.n_blend_shape_targets, dest.blend_shape_targets, source.blend_shape_targets); + dest.shadow_caster = source.shadow_caster == 1; + array_from_plugin(source.n_vertex_position_remapping, dest.vertex_position_remapping, source.vertex_position_remapping); + array_from_plugin(source.n_vertex_normal_remapping, dest.vertex_normal_remapping, source.vertex_normal_remapping); +} + +__forceinline void to_plugin(SDB_Light &dest, const Light &source, const char *name, Allocator &a) +{ + dest.name = name; + dest.type = (SDB_LightDefinitionType)source.type; + memcpy(dest.color, source.color, 4 * sizeof(float)); + dest.falloff_start = source.falloff_start; + dest.falloff_end = source.falloff_end; + dest.spot_angle_start = source.spot_angle_start; + dest.spot_angle_end = source.spot_angle_end; + dest.cast_shadow = source.cast_shadow; +} +__forceinline void from_plugin(Light &dest, const SDB_Light &source) +{ + dest.type = (Light::DefinitionType)source.type; + memcpy(dest.color, source.color, 4 * sizeof(float)); + dest.falloff_start = source.falloff_start; + dest.falloff_end = source.falloff_end; + dest.spot_angle_start = source.spot_angle_start; + dest.spot_angle_end = source.spot_angle_end; + dest.cast_shadow = source.cast_shadow == 1; +} + +__forceinline void to_plugin(SDB_Camera &dest, const Camera &source, const char *name, Allocator &a) +{ + dest.name = name; + dest.type = (SDB_CameraDefinitionType)source.type; + dest.near_plane = source.near_plane; + dest.far_plane = source.far_plane; + dest.vertical_fov = source.vertical_fov; +} +__forceinline void from_plugin(Camera &dest, const SDB_Camera &source) +{ + dest.type = (Camera::DefinitionType)source.type; + dest.near_plane = source.near_plane; + dest.far_plane = source.far_plane; + dest.vertical_fov = source.vertical_fov; +} + +__forceinline void to_plugin(SDB_Animation &dest, const Animation &source, Allocator &a) +{ + to_plugin(dest.node, source.node); + to_plugin(dest.parameter, source.parameter); + array_to_plugin(dest.n_times, dest.times, source.times, a); + to_plugin(dest.data, source.data, a); +} +__forceinline void from_plugin(Animation &dest, const SDB_Animation &source) +{ + from_plugin(dest.node, source.node); + from_plugin(dest.parameter, source.parameter); + array_from_plugin(source.n_times, dest.times, source.times); + from_plugin(dest.data, source.data); +} + +__forceinline void to_plugin(SDB_AnimationTake &dest, const AnimationTake &source, const char *name, Allocator &a) +{ + dest.name = name; + dest.start_time = source.start_time; + dest.end_time = source.end_time; + dest.nb_samples = source.nb_samples; + vector_to_plugin(dest.n_animations, dest.animations, source.animations, a); +} +__forceinline void from_plugin(AnimationTake &dest, const SDB_AnimationTake &source) +{ + dest.start_time = source.start_time; + dest.end_time = source.end_time; + dest.nb_samples = source.nb_samples; + vector_from_plugin(source.n_animations, dest.animations, source.animations); +} + +__forceinline void to_plugin(SDB_SurfaceMaterialProperty &dest, const SurfaceMaterial::Property &source, Allocator &a) +{ + to_plugin(dest.name, source.name); + dest.n_integers = source.n_integers; + dest.integer = source.integer; + dest.n_floats = source.n_floats; + memcpy(dest.floats, source.floats, 4 * sizeof(float)); + to_plugin(dest.value_string, source.value_string); + to_plugin(dest.textures, source.textures, a); +} +__forceinline void from_plugin(SurfaceMaterial::Property &dest, const SDB_SurfaceMaterialProperty &source) +{ + from_plugin(dest.name, source.name); + dest.n_integers = source.n_integers; + dest.integer = source.integer; + dest.n_floats = source.n_floats; + memcpy(dest.floats, source.floats, 4 * sizeof(float)); + from_plugin(dest.value_string, source.value_string); + from_plugin(dest.textures, source.textures); +} + +__forceinline void to_plugin(SDB_SurfaceMaterial &dest, const SurfaceMaterial &source, const char *name, Allocator &a) +{ + dest.name = name; + dest.type = (SDB_SurfaceMaterialDefinitionType)source.type; + vector_to_plugin(dest.properties.size, dest.properties.data, source.properties, a); + dest.nb_influences = source.nb_influences; +} +__forceinline void from_plugin(SurfaceMaterial &dest, const SDB_SurfaceMaterial &source) +{ + dest.type = (SurfaceMaterial::DefinitionType)source.type; + vector_from_plugin(source.properties.size, dest.properties, source.properties.data); + dest.nb_influences = source.nb_influences; +} + +__forceinline void to_plugin(SDB_Texture &dest, const Texture &source, const char *name, Allocator &a) +{ + dest.name = name; + to_plugin(dest.file_path, source.file_path); + to_plugin(dest.relative_path, source.relative_path); + dest.embedded = source.embedded; + dest.uv_offset[0] = source.uv_offset.x; + dest.uv_offset[1] = source.uv_offset.y; + dest.uv_scale[0] = source.uv_scale.x; + dest.uv_scale[1] = source.uv_scale.y; + dest.uv_rotation = source.uv_rotation; +} +__forceinline void from_plugin(Texture &dest, const SDB_Texture &source) +{ + from_plugin(dest.file_path, source.file_path); + from_plugin(dest.relative_path, source.relative_path); + dest.embedded = source.embedded == 1; + dest.uv_offset.x = source.uv_offset[0]; + dest.uv_offset.y = source.uv_offset[1]; + dest.uv_scale.x = source.uv_scale[0]; + dest.uv_scale.y = source.uv_scale[1]; + dest.uv_rotation = source.uv_rotation; +} + +__forceinline void to_plugin(SDB_LevelOfDetailStep &dest, const LevelOfDetail::Step &source, Allocator &a) +{ + to_plugin(dest.nodes, source.nodes, a); + dest.min_pct = source.min_pct; + dest.max_pct = source.max_pct; +} +__forceinline void from_plugin(LevelOfDetail::Step &dest, const SDB_LevelOfDetailStep &source) +{ + from_plugin(dest.nodes, source.nodes); + dest.min_pct = source.min_pct; + dest.max_pct = source.max_pct; +} + +__forceinline void to_plugin(SDB_LevelOfDetail &dest, const LevelOfDetail &source, const char *name, Allocator &a) +{ + dest.name = name; + to_plugin(dest.orientation_node, source.orientation_node); + to_plugin(dest.bounding_volume, source.bounding_volume); + dest.requires_predefined_pct = source.requires_predefined_pct; + vector_to_plugin(dest.n_steps, dest.steps, source.steps, a); +} +__forceinline void from_plugin(LevelOfDetail &dest, const SDB_LevelOfDetail &source) +{ + from_plugin(dest.orientation_node, source.orientation_node); + from_plugin(dest.bounding_volume, source.bounding_volume); + dest.requires_predefined_pct = source.requires_predefined_pct == 1; + vector_from_plugin(source.n_steps, dest.steps, source.steps); +} + +__forceinline void to_plugin(SDB_SceneImportOptions &dest, const SceneImportOptions &source) +{ + dest.combine_meshes = source.combine_meshes; + dest.combine_meshes_by_material = source.combine_meshes_by_material; + dest.reverse_forward_axis = source.reverse_forward_axis; + dest.skip_create_extra_root = source.skip_create_extra_root; + dest.skip_textures = source.skip_textures; + dest.skip_lights = source.skip_lights; + dest.skip_cameras = source.skip_cameras; + dest.create_missing_uvs = source.create_missing_uvs; + dest.tangents = (SDB_SceneImportTangents)source.tangents; +} +__forceinline void from_plugin(SceneImportOptions &dest, const SDB_SceneImportOptions &source) +{ + dest.combine_meshes = source.combine_meshes == 1; + dest.combine_meshes_by_material = source.combine_meshes_by_material == 1; + dest.reverse_forward_axis = source.reverse_forward_axis == 1; + dest.skip_create_extra_root = source.skip_create_extra_root == 1; + dest.skip_textures = source.skip_textures == 1; + dest.skip_lights = source.skip_lights == 1; + dest.skip_cameras = source.skip_cameras == 1; + dest.create_missing_uvs = source.create_missing_uvs == 1; + dest.tangents = (SceneImportOptions::TangentsOption)source.tangents; +} + +__forceinline void to_plugin(SDB_Properties &dest, const SceneDatabase::Properties &source, Allocator &a) +{ + dest.size = source.size(); + dest.data = dest.size > 0 ? allocate_plugin_array(dest.size, a) : nullptr; + uint32_t i=0; + for (const auto &it : source) { + auto &dest_item = dest.data[i++]; + to_plugin(dest_item.first, it.first); + to_plugin(dest_item.second, it.second); + } +} +__forceinline void from_plugin(SceneDatabase::Properties &dest, const SDB_Properties &source) +{ + dest.reserve(source.size); + for (uint32_t i=0; i < source.size; ++i) { + from_plugin(dest[source.data[i].first], source.data[i].second); + } +} + +__forceinline void to_plugin(SDB_SceneDatabase &dest, const SceneDatabase &source, Allocator &a) +{ + hashmap_to_plugin(dest.nodes, source.nodes, a); + to_plugin(dest.roots, source.roots, a); + hashmap_to_plugin(dest.geometry_instances, source.geometry_instances, a); + vector_to_plugin(dest.geometries.size, dest.geometries.data, source.geometries, a); + hashmap_to_plugin(dest.lights, source.lights, a); + hashmap_to_plugin(dest.cameras, source.cameras, a); + hashmap_to_plugin(dest.skins, source.skins, a); + hashmap_to_plugin(dest.materials, source.materials, a); + hashmap_to_plugin(dest.textures, source.textures, a); + hashmap_to_plugin(dest.lods, source.lods, a); + hashmap_to_plugin(dest.anim_takes, source.anim_takes, a); + to_plugin(dest.source_path, source.source_path); + to_plugin(dest.import_options, source.import_options); + to_plugin(dest.properties, source.properties, a); +} +__forceinline void from_plugin(SceneDatabase &dest, const SDB_SceneDatabase &source) +{ + hashmap_from_plugin(dest.nodes, source.nodes); + from_plugin(dest.roots, source.roots); + hashmap_from_plugin(dest.geometry_instances, source.geometry_instances); + vector_from_plugin(source.geometries.size, dest.geometries, source.geometries.data); + hashmap_from_plugin(dest.lights, source.lights); + hashmap_from_plugin(dest.cameras, source.cameras); + hashmap_from_plugin(dest.skins, source.skins); + hashmap_from_plugin(dest.materials, source.materials); + hashmap_from_plugin(dest.textures, source.textures); + hashmap_from_plugin(dest.lods, source.lods); + hashmap_from_plugin(dest.anim_takes, source.anim_takes); + from_plugin(dest.source_path, source.source_path); + from_plugin(dest.import_options, source.import_options); + from_plugin(dest.properties, source.properties); +} diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/sort_map.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/sort_map.h new file mode 100644 index 0000000..fa3f57f --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/sort_map.h @@ -0,0 +1,184 @@ +#pragma once + +#include "pair.h" +#include "vector.h" + +#include "allocator.h" + +#include "functional.h" + +namespace stingray_plugin_foundation { + +// A map data structure that needs to be explicitly sorted. +// +// This map is just a thin wrapper around a sorted Vector and has +// the expected performance characteristics. Since data is stored +// linearly it is very cache friendly and it should be fast for most +// operations unless the map is huge, in which case an UnsortedMap +// is better. +// +// Note that the map must be explicitly sorted before any lookups +// can be performed and inserting new objects requires a resort. +// If frequent insertion is needed, use an UnsortedMap or a Map instead. +// +// Warning: Any operation requiring data lookup, such as +// [], erase, begin, end, find, etc, won't work as expected unless +// the map has been sorted. Remember to call sort before doing such +// operations. +// +// * `K` The key type of the map. +// * `D` The data type of the map. +// * `COMPARE` The less-than compare functor, defaults to std::less. +template +class SortMap +{ +public: + ALLOCATOR_AWARE; + + typedef K key_type; + typedef D data_type; + typedef COMPARE key_compare; + typedef Pair value_type; + typedef Vector storage_type; + typedef typename storage_type::iterator iterator; + typedef typename storage_type::const_iterator const_iterator; + + SortMap(const NoAllocator &a); + explicit SortMap(Allocator &a); + SortMap(const SortMap &o); + void operator=(const SortMap &o); + void swap(SortMap &o); + + Allocator &allocator() const; + + // Sets the allocator of the sort map. You can only call this before any + // allocations have been made by the vector. + void set_allocator(Allocator &allocator); + + // Serializes the map to the stream. + template void serialize(STREAM &stream); + + unsigned size() const; + bool empty() const; + iterator begin(); + const_iterator begin() const; + iterator end(); + const_iterator end() const; + + template iterator find(const KEY_EQ &k); + template const_iterator find(const KEY_EQ &k) const; + template iterator lower_bound(const KEY_EQ &k); + template const iterator lower_bound(const KEY_EQ &k) const; + template iterator upper_bound(const KEY_EQ &k); + template const iterator upper_bound(const KEY_EQ &k) const; + template unsigned lower_bound_index(const KEY_EQ &k) const; + template unsigned upper_bound_index(const KEY_EQ &k) const; + + // True if the map has the key `k`. + template bool has(const KEY_EQ &k) const; + + // Number of occurances of the key `k`. + template int count(const KEY_EQ &k) const; + + // Access keys by index. + key_type &key(int i); + // Access keys by index. + const key_type &key(int i) const; + // Access data by index. + data_type &data(int i); + // Access data by index. + const data_type &data(int i) const; + // Access value by index. + value_type &value(int i); + // Access data by index. + const value_type &value(int i) const; + + value_type &front(); + const value_type &front() const; + + value_type &back(); + const value_type &back() const; + + // Returns the value for the key `k`. The behavior is undefined if the key + // does not exist. + template const data_type &operator[](const KEY_EQ &k) const; + + // Unlike std::map, [] cannot be used to insert new keys in a SortMap, + // only to change the values of existing keys. Returns a reference to + // the value. The behavior is undefined if the map doesn't have the key `k`. + template data_type &operator[](const KEY_EQ &k); + + // Returns the value for the key `k` or `def` if the key doesn't exist. + template const data_type &get(const KEY_EQ &k, const data_type &def) const; + + // Clears all elements in the sort map (but does not deallocate memory). + void clear(); + + // Resets the sort map to its initial state (no memory allocated). + void reset() {set_capacity(0);} + + // Sets the capacity of the sort map to exactly the specified number of elements. + // This operation always reallocates the memory of the backing vector, no + // swap trick is necessary to enforce reallocation. + void set_capacity(unsigned capacity); + + // Inserts the data pair (`k`, `v`) at the end of the map. + template void insert(const KEY_EQ &k, const DATA_EQ &v); + + // Inserts the data pair (`k`, `v`) at the iterator position. + template void insert(iterator pos, const KEY_EQ &k, const data_type &v); + + iterator erase(iterator i); + template void erase(const KEY_EQ &k); + + #ifdef DEVELOPMENT + // Returns true if the map is sorted. + bool is_sorted(); + #endif + + // Sorts the map. You must call this before using any function that looks up + // values by key. + void sort(); + + // Marks the map as sorted (without sorting it). Use this if you know that + // the elements have been inserted in sorted order. + void mark_sorted(); + + // Returns true if the map contains duplicate keys. + // You must sort the map before using this function. + bool is_multi_map(); + + // Sets the capacity of this map to its current size. + void trim(); + + // Reserves space + void reserve(unsigned n); + + // Resizes + void resize(unsigned n); + +private: + template unsigned find_index(const KEY_EQ &k) const; + void mark_unsorted(); + void check_sorted() const; + + class value_compare { + public: + value_compare(key_compare less) : _less(less) {} + bool operator()(const value_type& left, const value_type& right) const + {return (_less(left.first, right.first));} + protected: + key_compare _less; + }; + + key_compare _less; + storage_type _data; + + #ifdef DEVELOPMENT + bool _is_sorted; + #endif +}; + +} // namespace stingray_plugin_foundation + +#include "sort_map.inl" diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/sort_map.inl b/lib/dt_p2p/stingray_sdk/plugin_foundation/sort_map.inl new file mode 100644 index 0000000..25ed0fd --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/sort_map.inl @@ -0,0 +1,403 @@ +#include "assert.h" + +namespace stingray_plugin_foundation { + +template +SortMap::SortMap(Allocator &a) : _data(a) +{ + mark_sorted(); +} + +template +SortMap::SortMap(const NoAllocator &a) : _data(a) +{ + mark_sorted(); +} + +template +void SortMap::set_capacity(unsigned capacity) +{ + _data.set_capacity(capacity); +} + +template +void SortMap::set_allocator(Allocator &allocator) +{ + _data.set_allocator(allocator); +} + +template +SortMap::SortMap(const SortMap &o) : _less(o._less), _data(o._data) +{ + #ifdef DEVELOPMENT + _is_sorted = o._is_sorted; + #endif +} + +template +void SortMap::operator=(const SortMap &o) +{ + _less = o._less; + _data = o._data; + #ifdef DEVELOPMENT + _is_sorted = o._is_sorted; + #endif +} + +template +void SortMap::swap(SortMap &o) +{ + std::swap(_less, o._less); + std::swap(_data, o._data); + #ifdef DEVELOPMENT + std::swap(_is_sorted, o._is_sorted); + #endif +} + +template +Allocator &SortMap::allocator() const +{ + return _data.allocator(); +} + +template +unsigned SortMap::size() const +{ + return _data.size(); +} + +template +bool SortMap::empty() const +{ + return _data.empty(); +} + +template +typename SortMap::iterator SortMap::begin() +{ + return _data.begin(); +} + +template +typename SortMap::const_iterator SortMap::begin() const +{ + return _data.begin(); +} + +template +typename SortMap::iterator SortMap::end() +{ + return _data.end(); +} + +template +typename SortMap::const_iterator SortMap::end() const +{ + return _data.end(); +} + +template template +typename SortMap::iterator SortMap::find(const KEY_EQ &k) +{ + check_sorted(); + return begin() + find_index(k); +} + +template template +typename SortMap::const_iterator SortMap::find(const KEY_EQ &k) const +{ + check_sorted(); + return begin() + find_index(k); +} + +template template +typename SortMap::iterator SortMap::lower_bound(const KEY_EQ &k) +{ + check_sorted(); + return begin() + lower_bound_index(k); +} + +template template +const typename SortMap::iterator SortMap::lower_bound(const KEY_EQ &k) const +{ + check_sorted(); + return begin() + lower_bound_index(k); +} + +template template +typename SortMap::iterator SortMap::upper_bound(const KEY_EQ &k) +{ + check_sorted(); + return begin() + upper_bound_index(k); +} + +template template +const typename SortMap::iterator SortMap::upper_bound(const KEY_EQ &k) const +{ + check_sorted(); + return begin() + upper_bound_index(k); +} + +template template +bool SortMap::has(const KEY_EQ &k) const +{ + return find(k) != end(); +} + +template template +int SortMap::count(const KEY_EQ &k) const +{ + return upper_bound_index(k) - lower_bound_index(k); +} + +template +typename SortMap::key_type &SortMap::key(int i) +{ + return _data[i].first; +} + +template +const typename SortMap::key_type &SortMap::key(int i) const +{ + return _data[i].first; +} + +template +typename SortMap::data_type &SortMap::data(int i) +{ + return _data[i].second; +} + +template +const typename SortMap::data_type & SortMap::data(int i) const +{ + return _data[i].second; +} + +template +typename SortMap::value_type &SortMap::value(int i) +{ + return _data[i]; +} + +template +const typename SortMap::value_type & SortMap::value(int i) const +{ + return _data[i]; +} + +template +typename SortMap::value_type &SortMap::front() +{ + return _data.front(); +} + +template +const typename SortMap::value_type & SortMap::front() const +{ + return _data.front(); +} + +template +typename SortMap::value_type &SortMap::back() +{ + return _data.back(); +} + +template +const typename SortMap::value_type & SortMap::back() const +{ + return _data.back(); +} + +template template +const typename SortMap::data_type & SortMap::operator[](const KEY_EQ &k) const +{ + return find(k)->second; +} + +template template +typename SortMap::data_type & SortMap::operator[](const KEY_EQ &k) +{ + iterator it = find(k); + XENSURE(it != end()); + return it->second; +} + +template template +const typename SortMap::data_type & SortMap::get(const KEY_EQ &k, const data_type &def) const +{ + const_iterator it = find(k); + if (it == end()) return def; + return it->second; +} + +template +void SortMap::clear() +{ + _data.clear(); + mark_sorted(); +} + +template template +void SortMap::insert(const KEY_EQ &k, const DATA_EQ &v) +{ + // It might be better to inplace construct the pair in the + // vector rather than constructing and copying... I'm not sure + // if that can be done. + _data.resize( _data.size() + 1); + _data.back().first = k; + #pragma warning(push) + #pragma warning(disable : 4267) // templated, hard to fix warning for possible data loss + _data.back().second = v; + #pragma warning(pop) + mark_unsorted(); +} + +template template +void SortMap::insert(iterator pos, const KEY_EQ &k, const data_type &v) +{ + value_type value(k,v); + _data.insert(pos, value); + mark_unsorted(); +} + +template +typename SortMap::iterator SortMap::erase(iterator i) +{ + return _data.erase(i); +} + +template template +void SortMap::erase(const KEY_EQ &k) +{ + _data.erase( find(k) ); +} + +template +void SortMap::sort() +{ + std::sort(_data.begin(), _data.end(), value_compare(_less)); + mark_sorted(); +} + + +template +bool SortMap::is_multi_map() +{ + check_sorted(); + for (unsigned i=1; i<_data.size(); ++i) { + if (!_less(_data[i].first, _data[i-1].first) && + !_less(_data[i-1].first, _data[i].first)) + return true; + } + return false; +} + +template +void SortMap::trim() +{ + _data.trim(); +} + +template +void SortMap::reserve(unsigned n) +{ + _data.reserve(n); +} + +template +void SortMap::resize(unsigned n) +{ + _data.resize(n); +} + +template template +unsigned SortMap::find_index(const KEY_EQ &k) const +{ + unsigned lo = 0; + unsigned hi = size(); + while (true) { + if (hi <= lo) + return size(); + unsigned mid = (lo + hi) / 2; + if (_less(_data[mid].first, k)) + lo = mid+1; + else if (_less(k, _data[mid].first)) + hi = mid; + else + return mid; + } +} + +template template +unsigned SortMap::lower_bound_index(const KEY_EQ &k) const +{ + unsigned lo = 0; + unsigned hi = size(); + + if (hi == 0 || !_less(_data[lo].first, k)) + return 0; + + while (true) { + if (hi <= lo+1) + return hi; + unsigned mid = (lo + hi) / 2; + if (_less(_data[mid].first, k)) + lo = mid; + else + hi = mid; + } +} + +template template +unsigned SortMap::upper_bound_index(const KEY_EQ &k) const +{ + unsigned lo = 0; + unsigned hi = size(); + + if (hi == 0 || _less(k, _data[lo].first)) + return 0; + + while (true) { + if (hi <= lo+1) + return hi; + unsigned mid = (lo + hi) / 2; + if (_less(k, _data[mid].first)) + hi = mid; + else + lo = mid; + } +} + +template +void SortMap::mark_sorted() +{ + #ifdef DEVELOPMENT + _is_sorted = true; + #endif +} + +template +void SortMap::mark_unsorted() +{ + #ifdef DEVELOPMENT + _is_sorted = false; + #endif +} + +template +void SortMap::check_sorted() const +{ + XASSERT(_is_sorted, "SortMap not sorted"); +} + +template +template void SortMap::serialize(STREAM &stream) +{ + check_sorted(); + stream & _data; + mark_sorted(); +} + +} // namespace stingray_plugin_foundation diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/sort_set.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/sort_set.h new file mode 100644 index 0000000..949706b --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/sort_set.h @@ -0,0 +1,68 @@ +#pragma once + +#include "functional.h" + +namespace stingray_plugin_foundation { + +// Set implementation having the same structure and performance characteristics as +// SortedMap. +template < class K, class COMPARE = less > +class SortSet +{ +public: + ALLOCATOR_AWARE; + + typedef K key_type; + typedef COMPARE key_compare; + typedef Vector storage_type; + typedef typename storage_type::iterator iterator; + typedef typename storage_type::const_iterator const_iterator; + + explicit SortSet(Allocator &a); + explicit SortSet(const SortSet &o); + void operator=(const SortSet &o); + void swap(SortSet &o); + + // Serializes the sort set to the stream. + template void serialize(STREAM &stream); + + Allocator & allocator() const; + + unsigned size() const; + void resize(unsigned size); + bool empty() const; + iterator begin(); + const_iterator begin() const; + iterator end(); + const_iterator end() const; + + template unsigned find_index(const KEY_EQ &k) const; + template unsigned lower_bound_index(const KEY_EQ &k) const; + template unsigned upper_bound_index(const KEY_EQ &k) const; + + template iterator find(const KEY_EQ &k); + template const_iterator find(const KEY_EQ &k) const; + template iterator lower_bound(const KEY_EQ &k); + template const_iterator lower_bound(const KEY_EQ &k) const; + template iterator upper_bound(const KEY_EQ &k); + template const_iterator upper_bound(const KEY_EQ &k) const; + + template bool has(const KEY_EQ &k) const; + template int count(const KEY_EQ &k) const; + + void clear(); + template void insert(const KEY_EQ &k); + iterator erase(iterator i); + template void erase(const KEY_EQ &k); + void sort(); + void trim(); + bool is_multi_set() const; + +private: + key_compare _less; + storage_type _data; +}; + +} // namespace stingray_plugin_foundation + +#include "sort_set.inl" diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/sort_set.inl b/lib/dt_p2p/stingray_sdk/plugin_foundation/sort_set.inl new file mode 100644 index 0000000..06270c5 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/sort_set.inl @@ -0,0 +1,233 @@ +namespace stingray_plugin_foundation { + +template +SortSet::SortSet(Allocator &a) : _data(a) +{} + +template +SortSet::SortSet(const SortSet &o) : _less(o._less), _data(o._data) +{} + +template +void SortSet::operator=(const SortSet &o) +{ + _less = o._less; + _data = o._data; +} + +template +void SortSet::swap(SortSet &o) +{ + std::swap(_less, o._less); + std::swap(_data, o._data); +} + +template +template void SortSet::serialize(STREAM &stream) +{ + stream & _data; +} + +template +Allocator & SortSet::allocator() const +{ + return _data.allocator(); +} + +template +unsigned SortSet::size() const +{ + return _data.size(); +} + +template +void SortSet::resize(unsigned size) +{ + _data.resize(size); +} + +template +bool SortSet::empty() const +{ + return _data.empty(); +} + +template +typename SortSet::iterator SortSet::begin() +{ + return _data.begin(); +} + +template +typename SortSet::const_iterator SortSet::begin() const +{ + return _data.begin(); +} + +template +typename SortSet::iterator SortSet::end() +{ + return _data.end(); +} + +template +typename SortSet::const_iterator SortSet::end() const +{ + return _data.end(); +} + +template template +unsigned SortSet::find_index(const KEY_EQ &k) const +{ + unsigned lo = 0; + unsigned hi = size(); + while (true) { + if (hi <= lo) + return size(); + unsigned mid = (lo + hi) / 2; + if (_less(_data[mid], k)) + lo = mid+1; + else if (_less(k, _data[mid])) + hi = mid; + else + return mid; + } +} + +template template +unsigned SortSet::lower_bound_index(const KEY_EQ &k) const +{ + unsigned lo = 0; + unsigned hi = size(); + + if (hi == 0 || !_less(_data[lo], k)) + return 0; + + while (true) { + if (hi <= lo+1) + return hi; + unsigned mid = (lo + hi) / 2; + if (_less(_data[mid], k)) + lo = mid; + else + hi = mid; + } +} + +template template +unsigned SortSet::upper_bound_index(const KEY_EQ &k) const +{ + unsigned lo = 0; + unsigned hi = size(); + + if (hi == 0 || _less(k, _data[lo])) + return 0; + + while (true) { + if (hi <= lo+1) + return hi; + unsigned mid = (lo + hi) / 2; + if (_less(k, _data[mid])) + hi = mid; + else + lo = mid; + } +} + +template template +typename SortSet::iterator SortSet::find(const KEY_EQ &k) +{ + return begin() + find_index(k); +} + +template template +typename SortSet::const_iterator SortSet::find(const KEY_EQ &k) const +{ + return begin() + find_index(k); +} + +template template +typename SortSet::iterator SortSet::lower_bound(const KEY_EQ &k) +{ + return begin() + lower_bound_index(k); +} + +template template +typename SortSet::const_iterator SortSet::lower_bound(const KEY_EQ &k) const +{ + return begin() + lower_bound_index(k); +} + +template template +typename SortSet::iterator SortSet::upper_bound(const KEY_EQ &k) +{ + return begin() + upper_bound_index(k); +} + +template template +typename SortSet::const_iterator SortSet::upper_bound(const KEY_EQ &k) const +{ + return begin() + upper_bound_index(k); +} + +template template +bool SortSet::has(const KEY_EQ &k) const +{ + return find(k) != end(); +} + +template template +int SortSet::count(const KEY_EQ &k) const +{ + return upper_bound_index(k) - lower_bound_index(k); +} + +template +void SortSet::clear() +{ + _data.clear(); +} + +template template +void SortSet::insert(const KEY_EQ &k) +{ + _data.resize( _data.size()+1 ); + _data.back() = k; +} + +template +typename SortSet::iterator SortSet::erase(iterator i) +{ + return _data.erase(i); +} + +template template +void SortSet::erase(const KEY_EQ &k) +{ + _data.erase( find(k) ); +} + +template +void SortSet::sort() +{ + std::sort(_data.begin(), _data.end(), _less); +} + +template +void SortSet::trim() +{ + _data.trim(); +} + +template +bool SortSet::is_multi_set() const +{ + for (unsigned i=1; i<_data.size(); ++i) { + if (!_less(_data[i], _data[i-1]) && + !_less(_data[i-1], _data[i])) + return true; + } + return false; +} + +} // namespace stingray_plugin_foundation diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/stream.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/stream.h new file mode 100644 index 0000000..d87e4dc --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/stream.h @@ -0,0 +1,125 @@ +#pragma once + +#include "array.h" + +#include + +namespace stingray_plugin_foundation { + +// Functions for treating a Array or a char * as a memory stream that can be written to +// and read from. +namespace stream { + + // Packs the data in t to the stream. + template void pack(char *&v, const T &t) + { + memmove(v, &t, sizeof(T)); + v += sizeof(T); + } + + // Packs the data in t to the stream, resizing it if necessary. + template void pack(Array &v, const T &t) + { + v.resize(v.size() + sizeof(T)); + memmove(&v[0] + v.size() - sizeof(T), &t, sizeof(T)); + } + + // Patches already packed data at the specified location. + template void patch(char *&v, const T &t) + { + memmove(v, &t, sizeof(T)); + v += sizeof(T); + } + + // Patches already packed data at the specified offset. + template void patch(Array &v, unsigned &offset, const T &t) + { + memmove(&v[0] + offset, &t, sizeof(T)); + offset += sizeof(T); + } + + // Packs `count` bytes from `p` to the stream. + inline void pack_bytes(char *&v, const void *p, unsigned count) + { + memmove(v, p, count); + v += count; + } + + // Packs `count` bytes from `p` to the stream, resizing it if necessary. + inline void pack_bytes(Array &v, const void *p, unsigned count) + { + v.resize(v.size() + count); + memmove(&v[0] + v.size() - count, p, count); + } + + // Packs `count` zero bytes to the stream. + inline void pack_zeroes(char *&v, unsigned count) + { + memset(v, 0, count); + v += count; + } + + // Packs `count` zero bytes to the stream, resizing it if necessary. + inline void pack_zeroes(Array &v, unsigned count) + { + v.resize(v.size() + count); + memset(&v[0] + v.size() - count, 0, count); + } + + // Aligns the stream to the specified alignment. + inline void pack_align(Array &v, unsigned align) { + while (v.size() % align != 0) + v.push_back(0); + } + + // Unpacks an object of type T from the stream and returns it. The stream + // pointer is advanced to the next object. Note that since this operation + // only casts the pointer, it can have alignment problems if objects in the + // stream are not aligned. To unpack potentially unaligned objects, use the + // call unpack(stream, t) instead. + template const T &unpack(const char *&stream) + { + const T* t = (const T *)stream; + stream += sizeof(T); + return *t; + } + + template T &unpack(char *&stream) + { + T* t = (T *)stream; + stream += sizeof(T); + return *t; + } + + + // Unpacks an object of type T from the stream into the varaible t. + template void unpack(const char *&stream, T &t) + { + memmove(&t, stream, sizeof(T)); + stream += sizeof(T); + } + + template void unpack(char *&stream, T &t) + { + memmove(&t, stream, sizeof(T)); + stream += sizeof(T); + } + + // Unpacks count raw bytes from the stream into `p` and returns them. + // The stream pionter is advanced to beyond the bytes. + inline void unpack_bytes(char *&stream, void *p, unsigned count) + { + memmove(p, stream, count); + stream += count; + } + + // Aligns the stream to the specified alignment. + inline void unpack_align(char *&stream, unsigned align) + { + unsigned skip = (align - (uintptr_t)stream % align) % align; + stream += skip; + } + +} // namespace stream + +} // namespace stingray_plugin_foundation diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/string.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/string.h new file mode 100644 index 0000000..9ed8d43 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/string.h @@ -0,0 +1,322 @@ +#pragma once + +#include "allocator.h" +#include "assert.h" + +#include "array.h" + +#include +#include +#include + +namespace stingray_plugin_foundation { + +template class Vector; + +// ---------------------------------------------------------------------- +// Functions that extend the normal ANSI C string interface. +// ---------------------------------------------------------------------- + +// Returns the length of the string a 32-bit number (unsigned rather +// than size_t). +inline unsigned strlen32(const char *s); + +// Returns the length of the string a 32-bit number (unsigned rather +// than size_t). +inline unsigned strlenw32(const wchar_t *s); + +// Returns true if strings s1 and s2 are identical. +inline bool strequal(const char *s1, const char *s2); + +// Returns true if strings s1 and s2 are identical when ignoring case. +// Only ascii characters (A-Z) are considered when comparing case. +bool strequali(const char *s1, const char *s2); + +// Returns true if string s is empty. +inline bool strempty(const char *s); + +// Converts s to an integer and returns the result. +inline int to_int(const char *s); + +// Converts s to an unsigned and returns the result. +inline unsigned to_unsigned(const char *s); + +// Converts s to a float and returns the result. +inline float to_float(const char *s); + +// Converts s to an integer and returns the result. +inline int to_int(const char *s, bool &error); + +// Converts s to an unsigned and returns the result. +inline unsigned to_unsigned(const char *s, bool &error); + +// Converts s to a float and returns the result. +inline float to_float(const char *s, bool &error); + +// ---------------------------------------------------------------------- + +// A thin wrapper around a const char * that just adds a == operator for string +// comparison. Note especially that it doesn't make a copy of the string. The +// original string pointer must be valid as long as this class is used. +// +// Typically, this class is used to make string comparisons easier to read +// and prevent mistakes. An example: +// +// ConstString s(p) +// if (s == "open") +// ... +class ConstString +{ +public: + // ConstString that wraps the empty string. + ConstString() : s("") {} + + // ConstString that wraps the specified string. + ConstString(const char *s_) : s(s_) {} + + // Returns the raw string pointer. + const char *c_str() const {return s;} + + // Returns true if the string is empty. + bool empty() const {return *s == 0;} + + // Returns the length of the string + unsigned size() const {return strlen32(s);} + + const char *s; +}; + +// Comparison operators for ConstString. +inline bool operator==(const ConstString &s1, const char *s2) {return strcmp(s1.s, s2) == 0;} +inline bool operator==(const char *s1, const ConstString &s2) {return strcmp(s1, s2.s) == 0;} +inline bool operator==(const ConstString &s1, const ConstString &s2) {return strcmp(s1.s, s2.s) == 0;} +inline bool operator!=(const ConstString &s1, const char *s2) {return strcmp(s1.s, s2) != 0;} +inline bool operator!=(const char *s1, const ConstString &s2) {return strcmp(s1, s2.s) != 0;} +inline bool operator!=(const ConstString &s1, const ConstString &s2) {return strcmp(s1.s, s2.s) != 0;} +inline bool operator<(const ConstString &s1, const char *s2) {return strcmp(s1.s, s2) < 0;} +inline bool operator<(const char *s1, const ConstString &s2) {return strcmp(s1, s2.s) < 0;} +inline bool operator<(const ConstString &s1, const ConstString &s2) {return strcmp(s1.s, s2.s) < 0;} + +// ---------------------------------------------------------------------- + +// Class that represents a dynamic string -- a string whose content can be modified. +// This class is basically just a thin wrapper around an Array buffer that stores +// the content of the string. +class DynamicString +{ +public: + ALLOCATOR_AWARE; + + // Creates a new dynamic string using the specified allocator. + DynamicString(Allocator &a) : _buffer(a) {} + + // Creates a new dynamic string initialized from s. + DynamicString(Allocator &a, const char *s) : _buffer(a) { unsigned length = s ? strlen32(s) : 0; if (length > 0) { _buffer.resize(length + 1); memmove(_buffer.begin(), s, _buffer.size()); } } + + // Creates a new dynamic string initialized from the first n characters of s. + DynamicString(Allocator &a, const char *s, unsigned n) : _buffer(a) { if (n > 0) { _buffer.resize(n + 1); memmove(_buffer.begin(), s, n); _buffer[n] = 0; } } + + // Copy constructor + DynamicString(const DynamicString &o) : _buffer(o._buffer) {} + + // Assignment. + void operator=(const char *s) { unsigned length = strlen32(s); if (length > 0) { _buffer.resize(length + 1); memmove(_buffer.begin(), s, _buffer.size()); } else _buffer.clear(); } + + // Assigns the characters from ds to this string. Does not change the allocator. + void operator=(const DynamicString &ds) { _buffer = ds._buffer; } + + // Returns the size/length of the string. The size does not include the terminating zero. + unsigned size() const {return _buffer.empty() ? 0 : _buffer.size() - 1;} + + // Returns true if the string is empty. + bool empty() const {return size() == 0;} + + // Returns the C-string held by this dynamic string. + char *c_str() { return _buffer.empty() ? empty_string() : _buffer.begin(); } + const char *c_str() const {return _buffer.empty() ? empty_string() : _buffer.begin();} + + // Returns a pointer to the terminating zero at the end of C-string. + char *end() { return _buffer.empty() ? c_str() : _buffer.end() - 1; } + const char *end() const { return _buffer.empty() ? c_str() : _buffer.end() - 1; } + + // Accesses characters in the string. + char &operator[](unsigned i) { return c_str()[i];} + const char &operator[](unsigned i) const { return c_str()[i]; } + + // Resizes the string to the specified size (size does not include terminating zero). + void resize(unsigned size) { bool empty = _buffer.empty(); _buffer.resize(size + 1); if (empty) _buffer[0] = '\0'; _buffer[size] = '\0'; } + + // Extends the string with the specified number of bytes. + void extend(unsigned bytes) {resize(size() + bytes);} + + // Clears the memory and sets this string to the empty string. + void clear() { _buffer.clear(); } + + // Returns the allocator of the string. + Allocator &allocator() const {return _buffer.allocator();} + + // Swaps the contents efficiently. + void swap(DynamicString &other); + + // Serializes the string to the stream + template void serialize(STREAM &s) { + unsigned sz = size(); + s & sz; + if (sz != size()) + resize(sz); + + if (sz != 0) { + if (s.is_output()) + s.write(_buffer.begin(), sz); + else + s.read(_buffer.begin(), sz); + } + } + + Array &buffer() { if (_buffer.empty()) _buffer.push_back(0); return _buffer; } + private: + // Raw access to the string buffer. + Array _buffer; + static char *empty_string() { static char c = '\0'; return &c; } +}; + +// Comparison operators +inline bool operator==(const DynamicString &s1, const char *s2) {return strcmp(s1.c_str(), s2) == 0;} +inline bool operator==(const char *s1, const DynamicString &s2) {return strcmp(s1, s2.c_str()) == 0;} +inline bool operator==(const DynamicString &s1, const DynamicString &s2) {return strcmp(s1.c_str(), s2.c_str()) == 0;} +inline bool operator!=(const DynamicString &s1, const char *s2) {return strcmp(s1.c_str(), s2) != 0;} +inline bool operator!=(const char *s1, const DynamicString &s2) {return strcmp(s1, s2.c_str()) != 0;} +inline bool operator!=(const DynamicString &s1, const DynamicString &s2) {return strcmp(s1.c_str(), s2.c_str()) != 0;} +inline bool operator<(const DynamicString &s1, const char *s2) {return strcmp(s1.c_str(), s2) < 0;} +inline bool operator<(const char *s1, const DynamicString &s2) {return strcmp(s1, s2.c_str()) < 0;} +inline bool operator<(const DynamicString &s1, const DynamicString &s2) {return strcmp(s1.c_str(), s2.c_str()) < 0;} + +// Appends `s` to the end of `str`. +inline void append(DynamicString &str, const char *s); + +// Appends `c` to the end of `str`. +inline void append(DynamicString &str, char c); + +// Appends `len` characters beginning from `s` to the end of `str`. +inline void append(DynamicString &str, const char *s, unsigned len); + +// Inserts `s` in front of any characters in `str`. +inline void prefix(DynamicString &str, const char *s); + +// ---------------------------------------------------------------------- + +// Namespace for string operations. +namespace string { + + const unsigned npos = UINT_MAX; + + // Returns true if c is a whitespace character. + bool is_whitespace(char c); + + // Returns the index of the first occurrence of `c` in + // `s` or `npos` if not found. + unsigned find(const char *s, char c); + + // Returns the index of the last occurrence of `c` in + // `s` or `npos` if not found. + unsigned find_last(const char *s, char c); + + // Returns the index of the first occurrence of `substring` in + // `s` or `npos` if not found. + unsigned find(const char *s, const char *substring); + + // Returns the index of the last occurrence of `substring` in + // `s` or `npos` if not found. + unsigned find_last(const char *s, const char *substring); + + // Returns true if `s` contains `substring`. + bool contains(const char *s, const char *substring); + + // Splits the string `s` on the first instance of `split_on` and stores the + // results in `first` and `second`. If `split_on` is not found, `first` + // will get the entire string. + void split(const char *s, const char *split_on, DynamicString &first, DynamicString &second); + + // Splits the string `s` on all instances of `split_on` and stores the + // results in `result` + void split(const char *s, const char *split_by, Vector &result); + + enum SkipEmpty { SKIP_EMPTY, DONT_SKIP_EMPTY }; + // Joins each string in `strings` into a single string separated by `separator` and stores the result in `result`. + void join(const DynamicString* strings, unsigned num_strings, const char* separator, DynamicString& result, SkipEmpty skip_empty = DONT_SKIP_EMPTY); + + // Returns a pointer to a string with n spaces for indentation purposes. If n > 200 a string with 200 spaces + // will be returned. + const char *spaces(int n); + + // Returns true if s is a lowercase string. + bool is_lowercase(const char *s); + + // Replaces the character range (start, start+size) in the string s with the + // replacement rep. + void replace(DynamicString &s, unsigned start, unsigned size, const char *rep); + + // Replaces the occurances of the string `find` with the replacement `rep` and returns the number of successful replacements made. + unsigned replace_all(DynamicString &s, const char *find, const char *rep); + + // In-place converts the string to lower case + void to_lower_case(char *s); + + // In-place converts the string to upper case + void to_upper_case(char *s); + + // Converts from camel case to underscore representation. + DynamicString from_camel_case(const char *s, Allocator &a); + + // Returns the string with the character stripped out. + DynamicString strip(const char *s, char c, Allocator &a); + + // Trims whitespace from the start and end of the string and returns the result. + DynamicString trim(const char *s, Allocator &a); + + // Returns a substring of s starting at start and of length. + DynamicString substring(const char *s, unsigned start, unsigned length, Allocator &a); + + // Returns true if `str` contains `c`. + bool in_string(const char *str, char c); + + // Returns true if `str` only contains characters in `allowed`. + bool consists_of(const char *str, const char *allowed); + + // Returns true if `str` begins with `begins`. + bool begins_with(const char *str, const char *begins); + + // Returns true if `str` ends with `ends`. + bool ends_with(const char *str, const char *ends); + bool ends_with(const wchar_t *str, const wchar_t *ends); + + // Returns a copy of the string `str` allocated with the allocator `a`. + char* copy(const char *str, Allocator& a); + + // Copies src to dest. Truncates the copy if necessary so that more than + // `dest_size` bytes are never written to `dest`. Always terminates + // dest with a \0 character. Utf-8 characters are guaranteed to not get + // truncated in the middle of a multibyte character. + void copy(char *dest, const char *src, unsigned dest_size); + void copy(wchar_t *dest, const wchar_t *src, unsigned dest_size); + + // Appends `src` to the end of `dest`. Truncates `dest` if necessary so that + // more than `dest_size` bytes are never written to `dest`. Always terminates + // dest with a \0 character. Utf-8 characters are guaranteed to not get + // truncated in the middle of a multibyte character. + void append(char *dest, const char *src, unsigned dest_size); + void append(wchar_t *dest, const wchar_t *src, unsigned dest_size); + + #ifdef DEVELOPMENT + // Returns a string allocated by `a` representing a typcial hex_view of the `data`. + // (Such as shown by a memory debugger, for instance.) + // `columns` is the number of columns of hex values in the view. + // If `ascii_column` is true a column that shows ascii representation is included. + DynamicString hex_view(Allocator &a, const char *data, unsigned size, unsigned columns = 16, bool ascii_column = true); + #endif + +} // namespace string + +} + +#include "string.inl" diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/string.inl b/lib/dt_p2p/stingray_sdk/plugin_foundation/string.inl new file mode 100644 index 0000000..265e353 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/string.inl @@ -0,0 +1,223 @@ +#include + +namespace stingray_plugin_foundation { + +// ---------------------------------------------------------------------- +// C string methods +// ---------------------------------------------------------------------- + +inline unsigned strlen32(const char *s) +{ + return (unsigned)strlen(s); +} + +inline unsigned strlenw32(const wchar_t *s) +{ + const wchar_t *e = s; + while (*e) ++e; + return (unsigned)(e-s); +} + +inline bool strequal(const char *s1, const char *s2) +{ + return strcmp(s1, s2) == 0; +} + +inline bool strequali(const char *s1, const char *s2) +{ + while (*s1 && *s2) { + if (*s1 != *s2) { + if (tolower(*s1) != tolower(*s2)) + return false; + } + ++s1; ++s2; + } + return *s1 == *s2; +} + + +inline bool strempty(const char *s) +{ + return *s == 0; +} + +inline int to_int(const char *s) +{ + return (int)strtol(s, nullptr, 10); +} + +inline float to_float(const char *s) +{ + return float(strtod(s, nullptr)); +} + +inline unsigned to_unsigned(const char *s) +{ + return (unsigned)strtoul(s, nullptr, 10); +} + +inline int to_int(const char *s, bool &error) +{ + char *e; + int i = (int)strtol(s, &e, 10); + error = *s == 0 || *e != 0; + return i; +} + +inline float to_float(const char *s, bool &error) +{ + char *e; + float f = float(strtod(s, &e)); + error = *s == 0 || *e != 0; + return f; +} + +inline unsigned to_unsigned(const char *s, bool &error) +{ + char *e; + unsigned u = (unsigned)strtoul(s, &e, 10); + error = *s == 0 || *e != 0; + return u; +} + +// ---------------------------------------------------------------------- +// ConstString +// ---------------------------------------------------------------------- + + +// ---------------------------------------------------------------------- +// DynamicString +// ---------------------------------------------------------------------- + +inline void DynamicString::swap(DynamicString &other) +{ + _buffer.swap(other._buffer); +} + +inline void append(DynamicString &str, const char *s) +{ + str.extend(strlen32(s)); + strcat(str.c_str(), s); +} + +inline void append(DynamicString &str, const char *s, unsigned len) +{ + str.extend(len); + strncat(str.c_str(), s, len); +} + +inline void append(DynamicString &str, char c) +{ + str.extend(1); + str.end()[-1] = c; +} + +inline void prefix(DynamicString &str, const char *s) +{ + unsigned len = strlen32(s); + str.extend(len); + memmove(str.buffer().begin() + len, str.buffer().begin(), str.buffer().size() - len); + memcpy(str.buffer().begin(), s, len); +} + +// ---------------------------------------------------------------------- +// string methods +// ---------------------------------------------------------------------- + +inline bool string::is_whitespace(char c) +{ + return c == '\t' || c == ' ' || c == '\n' || c == '\r'; +} + +inline const char *string::spaces(int n) +{ + const char *s = + " " " " " " " " " " + " " " " " " " " " " + " " " " " " " " " " + " " " " " " " " " "; + if (n > 200) + n = 200; + return s + 200 - n; +} + +inline bool string::contains(const char *s, const char *substring) +{ + return string::find(s, substring) != string::npos; +} + +inline unsigned string::find_last(const char *s, char c) +{ + unsigned n = strlen32(s); + for (int i=n - 1; i >= 0; --i) { + if (s[i] == c) + return i; + } + return npos; +} + +inline unsigned string::find(const char *s, char c) +{ + unsigned n = strlen32(s); + for (unsigned i=0; i<=n; ++i) { + if (s[i] == c) + return i; + } + return npos; +} + +inline unsigned string::find(const char *s, const char *substring) +{ + unsigned n = strlen32(s) - strlen32(substring); + if (n > 0x80000000) + return npos; + for (unsigned i=0; i<=n; ++i) { + for (unsigned j=0;; ++j) { + if (substring[j] == 0) + return i; + if (s[i+j] != substring[j]) + break; + } + } + return npos; +} + +inline void string::split(const char *s, const char *split_on, DynamicString &first, DynamicString &second) +{ + unsigned pos = find(s, split_on); + if (pos == npos) { + first = s; + second.clear(); + } else { + unsigned s_n = strlen32(s); + unsigned split_on_n = strlen32(split_on); + first.resize(pos); + memmove(&first[0], &s[0], pos); + second.resize(s_n - pos - split_on_n); + memmove(&second[0], &s[pos + split_on_n], s_n - pos - split_on_n); + } +} + +// Cannot be defined in plugin_foundation at the moment. The Scaleform plugin +// includes string.h, and the plugin also removes the PS4 platform define, +// leading to __forceinline being undefined when compiling PS4. A fix is in the +// works. For now, defining this function in Wwise plugin (its only use) +// inline void string::split(const char *s, const char *split_by, Vector &result) +// { +// Allocator & allocator = result.allocator(); +// DynamicString a(allocator), b(allocator); +// string::split(s, split_by, a, b); +// while( !a.empty() ) { +// result.resize(result.size() + 1); +// result.back() = a; +// if( b.empty() ) +// break; +// DynamicString temp = b; +// string::split(temp.c_str(), split_by, a, b); +// } +// } + +// ---------------------------------------------------------------------- + +} // namespace stingray_plugin_foundation + diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/string_stream.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/string_stream.h new file mode 100644 index 0000000..2fae303 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/string_stream.h @@ -0,0 +1,58 @@ +#pragma once + +#include "allocator.h" +#include "array.h" +#include "platform.h" + +namespace stingray_plugin_foundation { + +class StringStream +{ +public: + StringStream(Allocator &a); + StringStream &operator<<(char c); + StringStream &operator<<(char *s); + StringStream &operator<<(const char *s); + StringStream &operator<<(wchar_t *s); + StringStream &operator<<(const wchar_t *s); + StringStream &operator<<(double d); + StringStream &operator<<(float f); + StringStream &operator<<(int i); + StringStream &operator<<(unsigned u); + StringStream &operator<<(uint64_t u); + template StringStream &operator<<(T t) {t.other_types_are_not_allowed(); return *this;} + + // As regular printf, but prints to string stream. + StringStream &printf(const char *format, ...); + + // Push a chunk of non null terminated data to the stream. + StringStream &push(const char *data, unsigned int size); + + // Allocates size bytes of data at the end of the stream and returns a pointer for filling it. + char *allocate(unsigned int size); + + // Logs a hex dump of the data to the string stream. + StringStream &hex_dump(const char *p, unsigned size, int columns=16); + + void set_capacity(unsigned s); + + // Pads with spaces to arrive at the specified column. + void indent(unsigned column); + + // Adds a multi-line string so each line, padded with spaces, begins at the specified column `column` and returns the number of lines that was added; + unsigned add_indented_lines(unsigned column, const char* lines); + + // Adds the specified number of spaces. + void add_spaces(unsigned n); + + const char *c_str() const; + unsigned size() const; + void clear() {_buffer.clear();} + +private: + mutable Array _buffer; +}; + +} // namespace stingray_plugin_foundation + +#include "string_stream.inl" diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/string_stream.inl b/lib/dt_p2p/stingray_sdk/plugin_foundation/string_stream.inl new file mode 100644 index 0000000..5227031 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/string_stream.inl @@ -0,0 +1,116 @@ +#include +#include +#include + +#include "encoding.h" + +namespace stingray_plugin_foundation { + +inline StringStream::StringStream(Allocator &a) : _buffer(a) {} + +inline StringStream & StringStream::operator<<(char c) +{ + _buffer.push_back(c); + return *this; +} + +inline StringStream &StringStream::operator<<(const char *s) +{ + int end = _buffer.size(); + int n = (int)strlen(s); + _buffer.resize(end + n); + if (n > 0) + memmove(&_buffer[end], s, n); + return *this; +} + +inline StringStream &StringStream::operator<<(char *s) +{ + int end = _buffer.size(); + int n = (int)strlen(s); + _buffer.resize(end + n); + if (n > 0) + memmove(&_buffer[end], s, n); + return *this; +} + +inline StringStream &StringStream::operator<<(const wchar_t *s) +{ + while (*s) { + char utf8[6]; + *encoding::utf8_encode(*s, utf8) = 0; + (*this) << utf8; + ++s; + } + return *this; +} + +inline StringStream &StringStream::operator<<(wchar_t *s) +{ + while (*s) { + char utf8[6]; + *encoding::utf8_encode(*s, utf8) = 0; + (*this) << utf8; + ++s; + } + return *this; +} + +inline StringStream &StringStream::operator<<(double d) +{ + char buffer[64]; + sprintf(buffer, "%.17g", d); + (*this) << buffer; + return *this; +} + +inline StringStream &StringStream::operator<<(float f) +{ + char buffer[20]; + sprintf(buffer, "%.9g", f); + (*this) << buffer; + return *this; +} + +inline StringStream &StringStream::operator<<(int i) +{ + char buffer[20]; + sprintf(buffer, "%i", i); + (*this) << buffer; + return *this; +} + +inline StringStream &StringStream::operator<<(unsigned u) +{ + char buffer[20]; + sprintf(buffer, "%u", u); + (*this) << buffer; + return *this; +} + +inline StringStream &StringStream::operator<<(uint64_t u) +{ + char buffer[20]; + sprintf(buffer, "%016" "llx", u); + (*this) << buffer; + return *this; +} + +inline void StringStream::set_capacity(unsigned s) +{ + _buffer.set_capacity(s); +} + +inline const char *StringStream::c_str() const +{ + _buffer.push_back(0); + _buffer.pop_back(); + return _buffer.begin(); +} + +inline unsigned StringStream::size() const +{ + return _buffer.size(); +} + +} // namespace stingray_plugin_foundation diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/template_tools.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/template_tools.h new file mode 100644 index 0000000..47cdb7b --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/template_tools.h @@ -0,0 +1,51 @@ +#pragma once + +#include "assert.h" + +namespace stingray_plugin_foundation { + +// Convert integer to type. +template +struct Int2Type { enum {value=v}; }; + +// Determines if a class is allocator aware. +template +struct is_allocator_aware { + + template + static char test_fun(typename C::allocator_aware *); + + template + static int test_fun(...); + +public: + enum { + value = (sizeof(test_fun(0)) == sizeof(char)) + }; +}; + +#define IS_ALLOCATOR_AWARE(T) is_allocator_aware::value +#define IS_ALLOCATOR_AWARE_TYPE(T) Int2Type< IS_ALLOCATOR_AWARE(T) > + +// Allocator aware constuction +template inline T &construct(void *p, Allocator &a, Int2Type) {new (p) T(a); return *(T *)p;} + +template inline T &construct(void *p, Allocator &a, Int2Type) {new (p) T; return *(T *)p;} + +template inline T &construct(void *p, Allocator &a) {return construct(p, a, IS_ALLOCATOR_AWARE_TYPE(T)());} + +// Helper for casts using a union. This circumvents the aliasing problem that occurs when +// trying to reinterpret a float as int and vice versa for example. +template +A safe_reinterpret_cast(const B &b) { + static_assert(sizeof(A) == sizeof(B), "Types must have same size to be cast"); + union U { + A a; + B b; + } u; + u.b = b; + return u.a; +} + +} + diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/types.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/types.h new file mode 100644 index 0000000..890b28a --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/types.h @@ -0,0 +1,44 @@ +#pragma once + +#include "../engine_plugin_api/plugin_api_types.h" + +namespace stingray_plugin_foundation { + +typedef unsigned short half; + +typedef CApiVector2 Vector2; +typedef CApiVector3 Vector3; +typedef CApiVector4 Vector4; +typedef CApiMatrix4x4 Matrix4x4; +typedef CApiQuaternion Quaternion; +typedef CApiMatrix3x3 Matrix3x3; +typedef CApiLocalTransform LocalTransform; + +struct Matrix4x4Elements { + enum Enum { + xx, xy, xz, xw, + yx, yy, yz, yw, + zx, zy, zz, zw, + tx, ty, tz, tw + }; + int dummy; +}; + +struct WorldConfig : public CApiWorldConfig { + WorldConfig() + { + disable_physics = false; + disable_sound = false; + disable_rendering = false; + enable_replay = false; + physics_world_settings.apex_cloth = false; + physics_world_settings.apex_lod_resource_budget = 0.f; + physics_world_settings.step_frequency = 0; + physics_world_settings.max_substeps = 0; + physics_world_settings.async_timestep = false; + physics_world_settings.swept_integration = false; + decals = 0; + } +}; + +} diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/vector.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/vector.h new file mode 100644 index 0000000..3ccd26d --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/vector.h @@ -0,0 +1,176 @@ +#pragma once + +#include "allocator.h" +#include "template_tools.h" +#include "assert.h" +#include "math.h" +#include // memmove +#include + +#if !defined(PS4) + #pragma warning(disable:4345) +#endif + +namespace stingray_plugin_foundation { + +struct NoAllocator {}; + +// A replacement for the std::vector class. +// +// The main difference between an std::vector and this vector class, is that this vector +// uses a specific allocator (a pointer to the allocator is stored) and allocates all its +// memory through that allocator. This makes it easy to support various types of memory +// allocation strategies. +// +// This vector implementation assumes that the types are "raw-movable"... i.e. that they +// can be bit-wise copied from one memory location to another without invoking a copy- +// constructor and a destructor. +// +// Unimplemented functions from standard stl (add if needed): +// - vector(unsigned n, const T& t) +// - vector(InputIterator, InputIterator), +// - rbegin() +// - rend() +// - max_size(), +// - void insert(iterator pos, InputIterator f, InputIterator l) +// - void insert(iterator pos, unsigned n, const T& x) +// - void resize(n, t = T()) +// - bool operator==(const vector&, const vector&) +// - bool operator<(const vector&, const vector&) +template +class Vector +{ +public: + ALLOCATOR_AWARE; + + // Type definitions + + typedef Vector this_type; + typedef T value_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef T& reference; + typedef const T& const_reference; + typedef pointer iterator; + typedef const_pointer const_iterator; + + // Constructors + + // Creates a vector that uses the specified allocator to allocate memory. + Vector(Allocator &allocator); + + // Creates a vector and presizes it to the specified size. + Vector(unsigned size, Allocator &allocator); + + // Creates a vector without an allocator, one must be provided later with + // set_allocator() before the vector is resized. + Vector(const NoAllocator &); + + // Sets the allocator of the vector. You can only call this before any + // allocations have been made by the vector. + void set_allocator(Allocator &allocator); + + Vector( const Vector &o ); + ~Vector() {reset();} + + // Asignment operator -- note that we do not support chained assignments. + void operator=(const Vector &o); + + // Serializes the vector to the stream. + template void serialize(STREAM &stream); + + // std::vector interface + + iterator begin() {return _data;} + const_iterator begin() const {return _data;} + iterator end() {return _data + _size;} + const_iterator end() const {return _data + _size;} + + unsigned size() const {return _size;} + unsigned capacity() const {return _capacity;} + bool any() const {return _size != 0;} + bool empty() const {return _size == 0;} + + reference operator[](unsigned i); + const_reference operator[](unsigned i) const; + + void reserve(unsigned capacity); + + reference front() {XENSURE(_size > 0); return _data[0];} + const_reference front() const {XENSURE(_size > 0); return _data[0];} + reference back() {XENSURE(_size > 0); return _data[_size-1];} + const_reference back() const {XENSURE(_size > 0); return _data[_size-1];} + + template void push_back(const ASSIGNABLE &item); + void pop_back(); + + void swap(Vector &o); + + template iterator insert(iterator pos, const ASSIGNABLE & x); + iterator insert(iterator pos); + void insert(iterator pos, const_iterator from, const_iterator to); + iterator erase(iterator pos); + iterator erase(iterator first, iterator last); + + void clear() {resize(0);} + void resize(unsigned size); + + bool operator==(const Vector &o) const; + bool operator<(const Vector &o) const; + + // Vector extensions + + // Resets the vector to initial state (no memory allocated). + void reset() {set_capacity(0);} + + // Extends the vector with the specified number of elements. + void extend(unsigned elements) { resize(size() + elements); } + + // Extends the vector with one elements and returns a reference to the newly created element. + reference extend() { resize(size() + 1); return back(); } + + // Returns the allocator of the vector. + Allocator &allocator() const {return *_allocator;} + + // Sets the capacity of the vector to exactly the specified amount. + // This operation always reallocates the memory of the vector, no + // swap trick is necessary to enforce reallocation. + void set_capacity(unsigned capacity); + + // Trims the vector so that the capacity corresponds to its current size. + void trim() {set_capacity(size());} + + // Finds the first occurrence of x in the vector and returns it. + template iterator find(const EQUATABLE &x) {return std::find(begin(), end(), x);} + + // Finds the first occurrence of x in the vector and returns it. + template const_iterator find(const EQUATABLE &x) const {return std::find(begin(), end(), x);} + + // Returns the index of x in the vector (or size() if it is not in the vector). + template unsigned index_of(const EQUATABLE &x) const {return (unsigned)(find(x) - begin());} + + // Returns if x is in the vector + template bool has(const EQUATABLE &x) const {return (find(x) != end());} + + // Erases the first occurrence of x in the vector. + template void erase(const EQUATABLE &item); + +private: + void move(pointer to, pointer from, ptrdiff_t n); + + void construct(pointer p, const Int2Type &) {new (p) T(*_allocator);} + + void construct(pointer p, const Int2Type &) {new (p) T();} + + void grow(unsigned min_capacity = 0); + +private: + unsigned _size; + unsigned _capacity; + pointer _data; + Allocator * _allocator; +}; + +} + +#include "vector.inl" diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/vector.inl b/lib/dt_p2p/stingray_sdk/plugin_foundation/vector.inl new file mode 100644 index 0000000..c936c0f --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/vector.inl @@ -0,0 +1,245 @@ +namespace stingray_plugin_foundation { + +template Vector::Vector(Allocator &allocator) : _size(0), _capacity(0), _data(0), _allocator(&allocator) +{ +} + +template Vector::Vector(unsigned size, Allocator &allocator) : _size(0), _capacity(0), _data(0), _allocator(&allocator) +{ + resize(size); +} + +template Vector::Vector(const NoAllocator &) : _size(0), _capacity(0), _data(0), _allocator(0) +{ +} + +template void Vector::set_allocator(Allocator &allocator) +{ + _allocator = &allocator; +} + +template Vector::Vector( const Vector &o ) : _size(0), _capacity(0), _data(0), _allocator(o._allocator) +{ + set_capacity(o.size()); + for (unsigned i=0; i void Vector::operator=(const Vector &o) +{ + resize(o.size()); + for (unsigned i=0; i<_size; ++i) + _data[i] = o[i]; +} + +template typename Vector::reference Vector::operator[](unsigned i) { + #if defined(_DEBUG) + XASSERT(i < _size, "Vector index out of bounds %d >= %d", i, _size); + #endif + return _data[i]; +} +template typename Vector::const_reference Vector::operator[](unsigned i) const { + #if defined(_DEBUG) + XASSERT(i < _size, "Vector index out of bounds %d >= %d", i, _size); + #endif + return _data[i]; +} + +template void Vector::reserve(unsigned capacity) +{ + if (capacity > _capacity) + grow(capacity); +} + +template template +void Vector::push_back(const ASSIGNABLE &item) +{ + if (_size + 1 > _capacity) + grow(); + construct(_data + _size, IS_ALLOCATOR_AWARE_TYPE(T)()); + #pragma warning(push) + #pragma warning(disable:4244) // can't fix cast warning + _data[_size] = item; + #pragma warning(pop) + ++_size; +} + +template void Vector::pop_back() +{ + _size--; + _data[_size].~T(); +} + +template void Vector::swap(Vector &o) +{ + XENSURE(_allocator == o._allocator); + std::swap(_size, o._size); + std::swap(_capacity, o._capacity); + std::swap(_data, o._data); + std::swap(_allocator, o._allocator); +} + +template template +typename Vector::iterator Vector::insert(iterator pos, const ASSIGNABLE& x) +{ + if (_size + 1 > _capacity) { + unsigned i = (unsigned)(pos - _data); + grow(); + pos = _data + i; + } + move(pos + 1, pos, (_data + _size) - pos); + construct(pos, IS_ALLOCATOR_AWARE_TYPE(T)()); + *pos = x; + ++_size; + return pos; +} + +template typename Vector::iterator Vector::insert(iterator pos) +{ + if (_size + 1 > _capacity) { + unsigned i = (unsigned)(pos - _data); + grow(); + pos = _data + i; + } + move(pos + 1, pos, (_data + _size) - pos); + construct(pos, IS_ALLOCATOR_AWARE_TYPE(T)()); + ++_size; + return pos; +} + +template void Vector::insert(iterator pos, const_iterator from, const_iterator to) +{ + unsigned add = (unsigned)(to - from); + if (_size + add > _capacity) { + unsigned i = (unsigned)(pos - _data); + grow(_size + add); + pos = _data + i; + } + move(pos + add, pos, (_data + _size) - pos); + while (from < to) { + construct(pos, IS_ALLOCATOR_AWARE_TYPE(T)()); + *pos = *from; + ++pos; + ++from; + ++_size; + } +} + +template typename Vector::iterator Vector::erase(iterator pos) +{ + #if defined(_DEBUG) + XASSERT(pos >= begin() && pos < end(), "Trying to remove outside vector."); + #endif + pos->~T(); + move(pos, pos + 1, (_data + _size) - pos - 1); + --_size; + return pos; +} + +template typename Vector::iterator Vector::erase(iterator first, iterator last) +{ + #if defined(_DEBUG) + XASSERT(first <= last, "Trying to remove inverted range from vector."); + XASSERT(first >= begin() && last <= end(), "Trying to remove range outside vector."); + #endif + for (iterator p = first; p < last; ++p) + p->~T(); + move(first, last, (_data + _size) - last); + _size -= (unsigned)(last - first); + return first; +} + +template template void Vector::erase(const EQUATABLE &item) +{ + iterator it = find(item); + #if defined(_DEBUG) + XASSERT(it != end(), "Trying to remove nonexisting value in vector."); + #endif + erase(it); +} + +template void Vector::resize(unsigned size) +{ + if (size > _capacity) + grow(size); + + while (size > _size) { + construct(_data + _size, IS_ALLOCATOR_AWARE_TYPE(T)()); + ++_size; + } + + while (_size > size) { + --_size; + _data[_size].~T(); + } +} + +template void Vector::set_capacity(unsigned capacity) +{ + if (capacity == _capacity) + return; + + if (capacity < _size) + resize(capacity); + + pointer new_data = 0; + + if (capacity > 0) { + new_data = (pointer)_allocator->allocate(sizeof(value_type)*capacity, math::max((int)alignof(value_type), 4)); + move(new_data, _data, _size); + } + _allocator->deallocate(_data); + + _data = new_data; + _capacity = capacity; +} + +template void Vector::move(pointer to, pointer from, ptrdiff_t n) +{ + memmove(to, from, sizeof(T) * n); +} + +template +template void Vector::serialize(STREAM &stream) +{ + unsigned sz = size(); + stream & sz; + resize(sz); + for (unsigned i=0; i bool Vector::operator==(const Vector &o) const +{ + if (size() != o.size()) + return false; + for (unsigned i=0; i bool Vector::operator<(const Vector &o) const +{ + if (size() != o.size()) + return size() < o.size(); + for (unsigned i=0; i void Vector::grow(unsigned min_capacity) +{ + uint64_t new_capacity = (uint64_t)_capacity*2 + 10; + if (new_capacity < min_capacity) + new_capacity = min_capacity; + else if (new_capacity > UINT32_MAX) + new_capacity = UINT32_MAX; + set_capacity((unsigned)new_capacity); +} + +} diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/vector2.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/vector2.h new file mode 100644 index 0000000..8f3f1d2 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/vector2.h @@ -0,0 +1,53 @@ +#pragma once + +#include "platform.h" +#include "types.h" + +namespace stingray_plugin_foundation { + +// Operators +__forceinline Vector2 operator / (const Vector2 &lhs, const Vector2 &rhs); +__forceinline Vector2 operator * (const Vector2 &lhs, const Vector2 &rhs); +__forceinline Vector2 operator + (const Vector2 &lhs, const Vector2 &rhs); +__forceinline Vector2 operator - (const Vector2 &lhs, const Vector2 &rhs); +__forceinline void operator /= (Vector2 &lhs, const Vector2 &rhs); +__forceinline void operator *= (Vector2 &lhs, const Vector2 &rhs); +__forceinline void operator += (Vector2 &lhs, const Vector2 &rhs); +__forceinline void operator -= (Vector2 &lhs, const Vector2 &rhs); +__forceinline Vector2 operator - (const Vector2 &v); +__forceinline Vector2 operator + (const Vector2 &v); + +__forceinline Vector2 operator / (const Vector2 &lhs, float rhs); +__forceinline Vector2 operator * (const Vector2 &lhs, float rhs); +__forceinline Vector2 operator * (float lhs, const Vector2 &rhs); +__forceinline Vector2 operator + (const Vector2 &lhs, float rhs); +__forceinline Vector2 operator - (const Vector2 &lhs, float rhs); +__forceinline void operator /= (Vector2 &lhs, float rhs); +__forceinline void operator *= (Vector2 &lhs, float rhs); +__forceinline void operator += (Vector2 &lhs, float rhs); +__forceinline void operator -= (Vector2 &lhs, float rhs); + +__forceinline bool operator==(const Vector2 &lhs, const Vector2 &rhs); +__forceinline bool operator!=(const Vector2 &lhs, const Vector2 &rhs); + +// Methods +__forceinline Vector2 vector2(float x, float y); +__forceinline float & element(Vector2 &m, int i); +__forceinline const float & element(const Vector2 &m, int i); + +__forceinline bool is_zero(const Vector2 &v); +__forceinline bool is_zero(const Vector2 &v, float eps); +__forceinline void zero(Vector2 &v); +__forceinline float length(const Vector2 &v); +__forceinline float length_squared(const Vector2 &v); +__forceinline Vector2 normalize(const Vector2 &v); +__forceinline float dot(const Vector2 &v0, const Vector2 &v1); +__forceinline float distance(const Vector2 &v0, const Vector2 &v1); +__forceinline float distance_squared(const Vector2 &v0, const Vector2 &v1); +__forceinline Vector2 lerp(const Vector2 &a, const Vector2 &b, float t); +__forceinline Vector2 min(const Vector2 &v0, const Vector2 &v1); +__forceinline Vector2 max(const Vector2 &v0, const Vector2 &v1); + +} + +#include "vector2.inl" diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/vector2.inl b/lib/dt_p2p/stingray_sdk/plugin_foundation/vector2.inl new file mode 100644 index 0000000..160fda1 --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/vector2.inl @@ -0,0 +1,167 @@ +#include "math.h" + +namespace stingray_plugin_foundation { + +// Operators +__forceinline Vector2 operator / (const Vector2 &lhs, const Vector2 &rhs) { + return vector2(lhs.x/rhs.x, lhs.y/rhs.y); +} + +__forceinline Vector2 operator * (const Vector2 &lhs, const Vector2 &rhs) { + return vector2(lhs.x*rhs.x, lhs.y*rhs.y); +} + +__forceinline Vector2 operator + (const Vector2 &lhs, const Vector2 &rhs) { + return vector2(lhs.x+rhs.x, lhs.y+rhs.y); +} + +__forceinline Vector2 operator - (const Vector2 &lhs, const Vector2 &rhs) { + return vector2(lhs.x-rhs.x, lhs.y-rhs.y); +} + +__forceinline Vector2 operator - (const Vector2 &v) { + return vector2(-v.x, -v.y); +} + +__forceinline Vector2 operator + (const Vector2 &v) { + return v; +} + +__forceinline void operator /= (Vector2 &lhs, const Vector2 &rhs) { + lhs.x/=rhs.x; lhs.y/=rhs.y; +} + +__forceinline void operator *= (Vector2 &lhs, const Vector2 &rhs) { + lhs.x*=rhs.x; lhs.y*=rhs.y; +} + +__forceinline void operator += (Vector2 &lhs, const Vector2 &rhs) { + lhs.x+=rhs.x; lhs.y+=rhs.y; +} + +__forceinline void operator -= (Vector2 &lhs, const Vector2 &rhs) { + lhs.x-=rhs.x; lhs.y-=rhs.y; +} + +__forceinline Vector2 operator/(const Vector2 &lhs, float rhs) { + return vector2(lhs.x/rhs, lhs.y/rhs); +} + +__forceinline Vector2 operator*(const Vector2 &lhs, float rhs) { + return vector2(lhs.x*rhs, lhs.y*rhs); +} + +__forceinline Vector2 operator*(float lhs, const Vector2 &rhs) { + return vector2(rhs.x*lhs, rhs.y*lhs); +} + +__forceinline Vector2 operator+(const Vector2 &lhs, float rhs) { + return vector2(lhs.x+rhs, lhs.y+rhs); +} + +__forceinline Vector2 operator-(const Vector2 &lhs, float rhs) { + return vector2(lhs.x-rhs, lhs.y-rhs); +} + +__forceinline void operator/=(Vector2 &lhs, float rhs) { + lhs.x/=rhs; lhs.y/=rhs; +} + +__forceinline void operator*=(Vector2 &lhs, float rhs) { + lhs.x*=rhs; lhs.y*=rhs; +} + +__forceinline void operator+=(Vector2 &lhs, float rhs) { + lhs.x+=rhs; lhs.y+=rhs; +} + +__forceinline void operator-=(Vector2 &lhs, float rhs) { + lhs.x-=rhs; lhs.y-=rhs; +} + +__forceinline bool operator==(const Vector2 &lhs, const Vector2 &rhs) +{ + return lhs.x == rhs.x && lhs.y == rhs.y; +} + +__forceinline bool operator!=(const Vector2 &lhs, const Vector2 &rhs) +{ + return !(lhs == rhs); +} + +// Methods +__forceinline Vector2 vector2(float x, float y) { + Vector2 v; + v.x = x; + v.y = y; + return v; +} + +__forceinline float & element(Vector2 &v, int i) +{ + return *(&v.x + i); +} + +__forceinline const float & element(const Vector2 &v, int i) +{ + return *(&v.x + i); +} + +__forceinline bool is_zero(const Vector2 &v) +{ + return v.x == 0.0f && v.y == 0.0f; +} + +__forceinline bool is_zero(const Vector2 &v, float eps) +{ + return length_squared(v) <= eps*eps; +} + +__forceinline void zero(Vector2 &v) { + v.x=0.f; v.y=0.f; +} + +__forceinline float length(const Vector2 &v) { + return math::square_root(v.x*v.x + v.y*v.y); +} + +__forceinline float length_squared(const Vector2 &v) { + return v.x*v.x + v.y*v.y; +} + +__forceinline Vector2 normalize(const Vector2 &v) { + float l=length(v); + if (l<0.0001) + return vector2(0.f, 0.f); + return v / l; +} + +__forceinline float dot(const Vector2 &v0, const Vector2 &v1) { + return v0.x * v1.x + v0.y * v1.y; +} + +__forceinline float distance(const Vector2 &v0, const Vector2 &v1) { + Vector2 tmp = vector2(v0.x-v1.x,v0.y-v1.y); + return length(tmp); +} + +__forceinline float distance_squared(const Vector2 &v0, const Vector2 &v1) { + return (v0.x-v1.x)*(v0.x-v1.x) + (v0.y-v1.y)*(v0.y-v1.y); +} + +__forceinline Vector2 lerp(const Vector2 &a, const Vector2 &b, float p) +{ + return a * (1-p) + b * p; +} + +__forceinline Vector2 min(const Vector2 &v0, const Vector2 &v1) +{ + return vector2(math::min(v0.x,v1.x), math::min(v0.y,v1.y)); +} + +__forceinline Vector2 max(const Vector2 &v0, const Vector2 &v1) +{ + return vector2(math::max(v0.x,v1.x), math::max(v0.y,v1.y)); +} + +} diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/vector3.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/vector3.h new file mode 100644 index 0000000..8ab7a2b --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/vector3.h @@ -0,0 +1,82 @@ +#pragma once + +#include "platform.h" +#include "types.h" + +namespace stingray_plugin_foundation { + +// Operators +__forceinline Vector3 operator / (const Vector3 &lhs, const Vector3 &rhs); +__forceinline Vector3 operator * (const Vector3 &lhs, const Vector3 &rhs); +__forceinline Vector3 operator + (const Vector3 &lhs, const Vector3 &rhs); +__forceinline Vector3 operator - (const Vector3 &lhs, const Vector3 &rhs); +__forceinline void operator /= (Vector3 &lhs, const Vector3 &rhs); +__forceinline void operator *= (Vector3 &lhs, const Vector3 &rhs); +__forceinline void operator += (Vector3 &lhs, const Vector3 &rhs); +__forceinline void operator -= (Vector3 &lhs, const Vector3 &rhs); +__forceinline Vector3 operator - (const Vector3 &v); +__forceinline Vector3 operator + (const Vector3 &v); + +__forceinline Vector3 operator / (const Vector3 &lhs, float rhs); +__forceinline Vector3 operator * (const Vector3 &lhs, float rhs); +__forceinline Vector3 operator * (float lhs, const Vector3 &rhs); +__forceinline Vector3 operator + (const Vector3 &lhs, float rhs); +__forceinline Vector3 operator - (const Vector3 &lhs, float rhs); +__forceinline void operator /= (Vector3 &lhs, float rhs); +__forceinline void operator *= (Vector3 &lhs, float rhs); +__forceinline void operator += (Vector3 &lhs, float rhs); +__forceinline void operator -= (Vector3 &lhs, float rhs); + +__forceinline bool operator==(const Vector3 &lhs, const Vector3 &rhs); +__forceinline bool operator!=(const Vector3 &lhs, const Vector3 &rhs); +__forceinline bool operator< (const Vector3 &lhs, const Vector3 &rhs); +__forceinline bool operator<=(const Vector3 &lhs, const Vector3 &rhs); +__forceinline bool operator> (const Vector3 &lhs, const Vector3 &rhs); +__forceinline bool operator>=(const Vector3 &lhs, const Vector3 &rhs); + +// Methods +__forceinline Vector3 vector3(float x, float y, float z); +__forceinline Vector3 vector3(const float v[3]); +__forceinline Vector3 vector3(const Vector2 &v); +__forceinline Vector3 vector3_base(int i); +__forceinline float & element(Vector3 &m, int i); +__forceinline const float & element(const Vector3 &m, int i); + +__forceinline bool all_gt(const Vector3& p1, const Vector3& p2); +__forceinline bool all_lt(const Vector3& p1, const Vector3& p2); +__forceinline void zero(Vector3 &v); +__forceinline bool is_zero(const Vector3 &v); +__forceinline bool is_zero(const Vector3 &v, float eps); +__forceinline float length(const Vector3 &v); +__forceinline float length_squared(const Vector3 &v); +__forceinline float norm(const Vector3 &v); +__forceinline float one_norm(const Vector3 &v); +__forceinline float infinity_norm(const Vector3 &v); +__forceinline Vector3 normalize(const Vector3 &v); +__forceinline float dot(const Vector3 &v0, const Vector3 &v1); +__forceinline Vector3 cross(const Vector3 &v0, const Vector3 &v1); +__forceinline float distance(const Vector3 &v0, const Vector3 &v1); +__forceinline float distance_squared(const Vector3 &v0, const Vector3 &v1); +__forceinline Vector3 normal_vector(const Vector3 &v0,const Vector3 &v1, const Vector3& v2); +__forceinline Vector3 min(const Vector3 &v0, const Vector3 &v1); +__forceinline Vector3 max(const Vector3 &v0, const Vector3 &v1); + +// Makes v orthonormal with respect to ref and returns the result. +__forceinline Vector3 orthonormalize(const Vector3 &v, const Vector3 &ref); + +// Given unit vector x finds two other axes y and z so that an orthonormal coordinate +// system is formed. +__forceinline void make_axes(const Vector3 &x, Vector3 &y, Vector3 &z); + +__forceinline Vector3 lerp(const Vector3 &a, const Vector3 &b, float t); + +struct MagnitudeAndDirection +{ + float magnitude; + Vector3 direction; +}; +__forceinline MagnitudeAndDirection magnitude_and_direction(const Vector3 &v); + +} + +#include "vector3.inl" diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/vector3.inl b/lib/dt_p2p/stingray_sdk/plugin_foundation/vector3.inl new file mode 100644 index 0000000..c09f8ed --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/vector3.inl @@ -0,0 +1,274 @@ +#include "math.h" + +namespace stingray_plugin_foundation { + +// Operators +__forceinline Vector3 operator / (const Vector3 &lhs, const Vector3 &rhs) { + return vector3(lhs.x/rhs.x, lhs.y/rhs.y, lhs.z/rhs.z); +} + +__forceinline Vector3 operator * (const Vector3 &lhs, const Vector3 &rhs) { + return vector3(lhs.x*rhs.x, lhs.y*rhs.y, lhs.z*rhs.z); +} + +__forceinline Vector3 operator + (const Vector3 &lhs, const Vector3 &rhs) { + return vector3(lhs.x+rhs.x, lhs.y+rhs.y, lhs.z+rhs.z); +} + +__forceinline Vector3 operator - (const Vector3 &lhs, const Vector3 &rhs) { + return vector3(lhs.x-rhs.x, lhs.y-rhs.y, lhs.z-rhs.z); +} + +__forceinline Vector3 operator - (const Vector3 &v) { + return vector3(-v.x, -v.y, -v.z); +} + +__forceinline Vector3 operator + (const Vector3 &v) { + return v; +} + +__forceinline void operator /= (Vector3 &lhs, const Vector3 &rhs) { + lhs.x/=rhs.x; lhs.y/=rhs.y; lhs.z/=rhs.z; +} + +__forceinline void operator *= (Vector3 &lhs, const Vector3 &rhs) { + lhs.x*=rhs.x; lhs.y*=rhs.y; lhs.z*=rhs.z; +} + +__forceinline void operator += (Vector3 &lhs, const Vector3 &rhs) { + lhs.x+=rhs.x; lhs.y+=rhs.y; lhs.z+=rhs.z; +} + +__forceinline void operator -= (Vector3 &lhs, const Vector3 &rhs) { + lhs.x-=rhs.x; lhs.y-=rhs.y; lhs.z-=rhs.z; +} + +__forceinline Vector3 operator/(const Vector3 &lhs, float rhs) { + return vector3(lhs.x/rhs, lhs.y/rhs, lhs.z/rhs); +} + +__forceinline Vector3 operator*(const Vector3 &lhs, float rhs) { + return vector3(lhs.x*rhs, lhs.y*rhs, lhs.z*rhs); +} + +__forceinline Vector3 operator*(float lhs, const Vector3 &rhs) { + return vector3(rhs.x*lhs, rhs.y*lhs, rhs.z*lhs); +} + +__forceinline Vector3 operator+(const Vector3 &lhs, float rhs) { + return vector3(lhs.x+rhs, lhs.y+rhs, lhs.z+rhs); +} + +__forceinline Vector3 operator-(const Vector3 &lhs, float rhs) { + return vector3(lhs.x-rhs, lhs.y-rhs, lhs.z-rhs); +} + +__forceinline void operator/=(Vector3 &lhs, float rhs) { + lhs.x/=rhs; lhs.y/=rhs; lhs.z/=rhs; +} + +__forceinline void operator*=(Vector3 &lhs, float rhs) { + lhs.x*=rhs; lhs.y*=rhs; lhs.z*=rhs; +} + +__forceinline void operator+=(Vector3 &lhs, float rhs) { + lhs.x+=rhs; lhs.y+=rhs; lhs.z+=rhs; +} + +__forceinline void operator-=(Vector3 &lhs, float rhs) { + lhs.x-=rhs; lhs.y-=rhs; lhs.z-=rhs; +} + +__forceinline bool operator==(const Vector3 &lhs, const Vector3 &rhs) +{ + return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z; +} + +__forceinline bool operator!=(const Vector3 &lhs, const Vector3 &rhs) +{ + return !(lhs == rhs); +} + +__forceinline bool operator< (const Vector3 &lhs, const Vector3 &rhs) +{ + if (lhs.x != rhs.x) return lhs.x < rhs.x; + if (lhs.y != rhs.y) return lhs.y < rhs.y; + return lhs.z < rhs.z; +} + +__forceinline bool operator<=(const Vector3 &lhs, const Vector3 &rhs) +{ + return (lhs < rhs) || (lhs == rhs); +} + +__forceinline bool operator> (const Vector3 &lhs, const Vector3 &rhs) +{ + return (rhs < lhs); +} + +__forceinline bool operator>=(const Vector3 &lhs, const Vector3 &rhs) +{ + return !(lhs < rhs); +} + +// Methods +__forceinline Vector3 vector3(float x, float y, float z) { + Vector3 v = {x, y, z}; + return v; +} + +__forceinline Vector3 vector3(const float v[3]) +{ + Vector3 r = {v[0], v[1], v[2]}; + return r; +} + +__forceinline Vector3 vector3(const Vector2 &v) { + Vector3 r = { v.x, v.y, 0.f }; + return r; +} + +__forceinline Vector3 vector3(const Vector2 &v, float z) { + Vector3 r = { v.x, v.y, z }; + return r; +} + +__forceinline Vector3 vector3_base(int i) +{ + if (i==0) + return vector3(1,0,0); + else if (i==1) + return vector3(0,1,0); + else if (i==2) + return vector3(0,0,1); + return vector3(0,0,0); +} + +__forceinline float & element(Vector3 &v, int i) +{ + return *(&v.x + i); +} + +__forceinline const float & element(const Vector3 &v, int i) +{ + return *(&v.x + i); +} + +__forceinline void zero(Vector3 &v) { + v.x=0.f; v.y=0.f; v.z=0.f; +} + +__forceinline bool is_zero(const Vector3 &v) +{ + return v.x == 0.0f && v.y == 0.0f && v.z == 0.0f; +} + +__forceinline bool is_zero(const Vector3 &v, float eps) +{ + return length_squared(v) <= eps*eps; +} + +__forceinline float length(const Vector3 &v) { + return math::square_root(v.x*v.x + v.y*v.y + v.z*v.z); +} + +__forceinline float length_squared(const Vector3 &v) { + return v.x*v.x + v.y*v.y + v.z*v.z; +} + +__forceinline float norm(const Vector3 &v) +{ + return math::square_root(v.x*v.x + v.y*v.y + v.z*v.z); +} + +__forceinline float one_norm(const Vector3 &v) +{ + return math::abs(v.x) + math::abs(v.y) + math::abs(v.z); +} + +__forceinline float infinity_norm(const Vector3 &v) +{ + return math::max3( math::abs(v.x), math::abs(v.y), math::abs(v.z) ); +} + +__forceinline Vector3 normalize(const Vector3 &v) { + float l=length(v); + if (l<0.0001) + return vector3(0.f, 0.f, 0.f); + return v / l; +} + +__forceinline float dot(const Vector3 &v0, const Vector3 &v1) { + return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z; +} + +__forceinline Vector3 cross(const Vector3 &v0, const Vector3 &v1) { + return vector3((v0.y*v1.z)-(v0.z*v1.y),(v0.z*v1.x)-(v0.x*v1.z),(v0.x*v1.y)-(v0.y*v1.x)); +} + +__forceinline float distance(const Vector3 &v0, const Vector3 &v1) { + Vector3 tmp = vector3(v0.x-v1.x,v0.y-v1.y,v0.z-v1.z); + return length(tmp); +} + +__forceinline float distance_squared(const Vector3 &v0, const Vector3 &v1) { + return (v0.x-v1.x)*(v0.x-v1.x) + (v0.y-v1.y)*(v0.y-v1.y) + (v0.z-v1.z)*(v0.z-v1.z); +} + +__forceinline Vector3 normal_vector(const Vector3 &v0,const Vector3 &v1, const Vector3& v2){ + return cross(v1-v0,v2-v0); +} + +__forceinline Vector3 orthonormalize(const Vector3 &v, const Vector3 &ref) +{ + Vector3 res = v - dot(v, ref) * ref; + return normalize(res); +} + +__forceinline Vector3 min(const Vector3 &v0, const Vector3 &v1) +{ + return vector3(math::min(v0.x,v1.x), math::min(v0.y,v1.y), math::min(v0.z,v1.z)); +} + +__forceinline Vector3 max(const Vector3 &v0, const Vector3 &v1) +{ + return vector3(math::max(v0.x,v1.x), math::max(v0.y,v1.y), math::max(v0.z,v1.z)); +} + +__forceinline bool all_gt(const Vector3& p1, const Vector3& p2) +{ + return p1.x > p2.x && p1.y > p2.y && p1.z > p2.z; +} + +__forceinline bool all_lt(const Vector3& p1, const Vector3& p2) +{ + return p1.x < p2.x && p1.y < p2.y && p1.z < p2.z; +} + +__forceinline void make_axes(const Vector3 &x, Vector3 &y, Vector3 &z) +{ + if (x.z > -0.5 && x.z < 0.5) { + y = vector3(-x.y, x.x, 0); + y = orthonormalize(y, x); + z = cross(x, y); + } else { + y = vector3(0, x.z, -x.y); + y = orthonormalize(y, x); + z = cross(x,y); + } +} + +__forceinline Vector3 lerp(const Vector3 &a, const Vector3 &b, float p) +{ + return a * (1-p) + b * p; +} + +__forceinline MagnitudeAndDirection magnitude_and_direction(const Vector3 &v) +{ + MagnitudeAndDirection md; + md.magnitude = norm(v); + md.direction = md.magnitude > 0 ? v / md.magnitude : vector3(0,0,0); + return md; +} + +} diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/vector4.h b/lib/dt_p2p/stingray_sdk/plugin_foundation/vector4.h new file mode 100644 index 0000000..dedba2f --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/vector4.h @@ -0,0 +1,58 @@ +#pragma once + +#include "platform.h" +#include "types.h" + +namespace stingray_plugin_foundation { + +// Operators +__forceinline Vector4 operator / (const Vector4 &lhs, const Vector4 &rhs); +__forceinline Vector4 operator * (const Vector4 &lhs, const Vector4 &rhs); +__forceinline Vector4 operator + (const Vector4 &lhs, const Vector4 &rhs); +__forceinline Vector4 operator - (const Vector4 &lhs, const Vector4 &rhs); +__forceinline void operator /= (Vector4 &lhs, const Vector4 &rhs); +__forceinline void operator *= (Vector4 &lhs, const Vector4 &rhs); +__forceinline void operator += (Vector4 &lhs, const Vector4 &rhs); +__forceinline void operator -= (Vector4 &lhs, const Vector4 &rhs); +__forceinline Vector4 operator - (const Vector4 &v); +__forceinline Vector4 operator + (const Vector4 &v); + +__forceinline Vector4 operator / (const Vector4 &lhs, float rhs); +__forceinline Vector4 operator * (const Vector4 &lhs, float rhs); +__forceinline Vector4 operator * (float lhs, const Vector4 &rhs); +__forceinline Vector4 operator + (const Vector4 &lhs, float rhs); +__forceinline Vector4 operator - (const Vector4 &lhs, float rhs); +__forceinline void operator /= (Vector4 &lhs, float rhs); +__forceinline void operator *= (Vector4 &lhs, float rhs); +__forceinline void operator += (Vector4 &lhs, float rhs); +__forceinline void operator -= (Vector4 &lhs, float rhs); + +__forceinline bool operator==(const Vector4 &lhs, const Vector4 &rhs); +__forceinline bool operator!=(const Vector4 &lhs, const Vector4 &rhs); + +// Methods +__forceinline Vector4 vector4(float x, float y, float z, float w); +__forceinline Vector4 vector4_base(int i); +__forceinline float & element(Vector4 &m, int i); +__forceinline const float & element(const Vector4 &m, int i); + +__forceinline void zero(Vector4 &v); +__forceinline float length(const Vector4 &v); +__forceinline float norm(const Vector4 &v); +__forceinline float one_norm(const Vector4 &v); +__forceinline float infinity_norm(const Vector4 &v); +__forceinline Vector4 normalize(const Vector4 &v); +__forceinline float dot(const Vector4 &v0, const Vector4 &v1); +__forceinline float distance(const Vector4 &v0, const Vector4 &v1); +__forceinline float distance_squared(const Vector4 &v0, const Vector4 &v1); +__forceinline Vector4 normal_vector(const Vector4 &v0,const Vector4 &v1, const Vector4& v2); +__forceinline Vector4 min(const Vector4 &v0, const Vector4 &v1); +__forceinline Vector4 max(const Vector4 &v0, const Vector4 &v1); + +__forceinline Vector4 lerp(const Vector4 &a, const Vector4 &b, float t); + +__forceinline Vector3 vector3(const Vector4 &a); + +} + +#include "vector4.inl" diff --git a/lib/dt_p2p/stingray_sdk/plugin_foundation/vector4.inl b/lib/dt_p2p/stingray_sdk/plugin_foundation/vector4.inl new file mode 100644 index 0000000..af150ed --- /dev/null +++ b/lib/dt_p2p/stingray_sdk/plugin_foundation/vector4.inl @@ -0,0 +1,193 @@ +#include "math.h" + +namespace stingray_plugin_foundation { + +// Operators +__forceinline Vector4 operator / (const Vector4 &lhs, const Vector4 &rhs) { + return vector4(lhs.x/rhs.x, lhs.y/rhs.y, lhs.z/rhs.z, lhs.w/rhs.w); +} + +__forceinline Vector4 operator * (const Vector4 &lhs, const Vector4 &rhs) { + return vector4(lhs.x*rhs.x, lhs.y*rhs.y, lhs.z*rhs.z, lhs.w*rhs.w); +} + +__forceinline Vector4 operator + (const Vector4 &lhs, const Vector4 &rhs) { + return vector4(lhs.x+rhs.x, lhs.y+rhs.y, lhs.z+rhs.z, lhs.w+rhs.w); +} + +__forceinline Vector4 operator - (const Vector4 &lhs, const Vector4 &rhs) { + return vector4(lhs.x-rhs.x, lhs.y-rhs.y, lhs.z-rhs.z, lhs.w-rhs.w); +} + +__forceinline Vector4 operator - (const Vector4 &v) { + return vector4(-v.x, -v.y, -v.z, -v.w); +} + +__forceinline Vector4 operator + (const Vector4 &v) { + return v; +} + +__forceinline void operator /= (Vector4 &lhs, const Vector4 &rhs) { + lhs.x/=rhs.x; lhs.y/=rhs.y; lhs.z/=rhs.z; lhs.w/=rhs.w; +} + +__forceinline void operator *= (Vector4 &lhs, const Vector4 &rhs) { + lhs.x*=rhs.x; lhs.y*=rhs.y; lhs.z*=rhs.z; lhs.w*=rhs.w; +} + +__forceinline void operator += (Vector4 &lhs, const Vector4 &rhs) { + lhs.x+=rhs.x; lhs.y+=rhs.y; lhs.z+=rhs.z; lhs.w+=rhs.w; +} + +__forceinline void operator -= (Vector4 &lhs, const Vector4 &rhs) { + lhs.x-=rhs.x; lhs.y-=rhs.y; lhs.z-=rhs.z; lhs.w-=rhs.w; +} + +__forceinline Vector4 operator/(const Vector4 &lhs, float rhs) { + return vector4(lhs.x/rhs, lhs.y/rhs, lhs.z/rhs, lhs.w/rhs); +} + +__forceinline Vector4 operator*(const Vector4 &lhs, float rhs) { + return vector4(lhs.x*rhs, lhs.y*rhs, lhs.z*rhs, lhs.w*rhs); +} + +__forceinline Vector4 operator*(float lhs, const Vector4 &rhs) { + return vector4(rhs.x*lhs, rhs.y*lhs, rhs.z*lhs, rhs.w*lhs); +} + +__forceinline Vector4 operator+(const Vector4 &lhs, float rhs) { + return vector4(lhs.x+rhs, lhs.y+rhs, lhs.z+rhs, lhs.w+rhs); +} + +__forceinline Vector4 operator-(const Vector4 &lhs, float rhs) { + return vector4(lhs.x-rhs, lhs.y-rhs, lhs.z-rhs, lhs.w-rhs); +} + +__forceinline void operator/=(Vector4 &lhs, float rhs) { + lhs.x/=rhs; lhs.y/=rhs; lhs.z/=rhs; lhs.w/=rhs; +} + +__forceinline void operator*=(Vector4 &lhs, float rhs) { + lhs.x*=rhs; lhs.y*=rhs; lhs.z*=rhs; lhs.w*=rhs; +} + +__forceinline void operator+=(Vector4 &lhs, float rhs) { + lhs.x+=rhs; lhs.y+=rhs; lhs.z+=rhs; lhs.w+=rhs; +} + +__forceinline void operator-=(Vector4 &lhs, float rhs) { + lhs.x-=rhs; lhs.y-=rhs; lhs.z-=rhs; lhs.w-=rhs; +} + +__forceinline bool operator==(const Vector4 &lhs, const Vector4 &rhs) +{ + return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z && lhs.w == rhs.w; +} + +__forceinline bool operator!=(const Vector4 &lhs, const Vector4 &rhs) +{ + return !(lhs == rhs); +} + +// Methods +__forceinline Vector4 vector4(float x, float y, float z, float w) { + Vector4 v; + v.x = x; v.y = y; v.z = z; v.w = w; + return v; +} + +__forceinline Vector4 vector4_base(int i) +{ + if (i==0) + return vector4(1,0,0,0); + else if (i==1) + return vector4(0,1,0,0); + else if (i==2) + return vector4(0,0,1,0); + else if (i==3) + return vector4(0,0,0,1); + return vector4(0,0,0,0); +} + +__forceinline float & element(Vector4 &v, int i) +{ + return *(&v.x + i); +} + +__forceinline const float & element(const Vector4 &v, int i) +{ + return *(&v.x + i); +} + +__forceinline void zero(Vector4 &v) { + v.x=0.f; v.y=0.f; v.z=0.f; v.w = 0.f; +} + +__forceinline float length(const Vector4 &v) { + return math::square_root(v.x*v.x + v.y*v.y + v.z*v.z + v.w*v.w); +} + +__forceinline float norm(const Vector4 &v) +{ + return math::square_root(v.x*v.x + v.y*v.y + v.z*v.z + v.w*v.w); +} + +__forceinline float one_norm(const Vector4 &v) +{ + return math::abs(v.x) + math::abs(v.y) + math::abs(v.z) + math::abs(v.w); +} + +__forceinline float infinity_norm(const Vector4 &v) +{ + return math::max( math::max(math::abs(v.x), math::abs(v.y)), math::max(math::abs(v.z), math::abs(v.w) )); +} + +__forceinline Vector4 normalize(const Vector4 &v) { + float l=length(v); + if (l<0.0001) + return vector4(0.f, 0.f, 0.f, 0.f); + return v / l; +} + +__forceinline float dot(const Vector4 &v0, const Vector4 &v1) { + return v0.x * v1.x + v0.y * v1.y + v0.z * v1.z + v0.w * v1.w; +} + +__forceinline float distance(const Vector4 &v0, const Vector4 &v1) { + Vector4 tmp = vector4(v0.x-v1.x,v0.y-v1.y,v0.z-v1.z,v0.w-v1.w); + return length(tmp); +} + +__forceinline float distance_squared(const Vector4 &v0, const Vector4 &v1) { + return (v0.x-v1.x)*(v0.x-v1.x) + (v0.y-v1.y)*(v0.y-v1.y) + (v0.z-v1.z)*(v0.z-v1.z) + (v0.w-v1.w)*(v0.w-v1.w); +} + +__forceinline Vector4 orthonormalize(const Vector4 &v, const Vector4 &ref) +{ + Vector4 res = v - dot(v, ref) * ref; + return normalize(res); +} + +__forceinline Vector4 min(const Vector4 &v0, const Vector4 &v1) +{ + return vector4(math::min(v0.x,v1.x), math::min(v0.y,v1.y), math::min(v0.z,v1.z), math::min(v0.w,v1.w)); +} + +__forceinline Vector4 max(const Vector4 &v0, const Vector4 &v1) +{ + return vector4(math::max(v0.x,v1.x), math::max(v0.y,v1.y), math::max(v0.z,v1.z), math::max(v0.w,v1.w)); +} + +__forceinline Vector4 lerp(const Vector4 &a, const Vector4 &b, float p) +{ + return a * (1-p) + b * p; +} + +__forceinline Vector3 vector3(const Vector4 &a) +{ + Vector3 v; + v.x = a.x; v.y = a.y; v.z = a.z; + return v; +} + +} diff --git a/lib/nat_traversal/.gitignore b/lib/nat_traversal/.gitignore new file mode 100644 index 0000000..4fffb2f --- /dev/null +++ b/lib/nat_traversal/.gitignore @@ -0,0 +1,2 @@ +/target +/Cargo.lock diff --git a/lib/nat_traversal/Cargo.toml b/lib/nat_traversal/Cargo.toml new file mode 100644 index 0000000..db49e37 --- /dev/null +++ b/lib/nat_traversal/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "nat_traversal" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/lib/nat_traversal/src/lib.rs b/lib/nat_traversal/src/lib.rs new file mode 100644 index 0000000..7d12d9a --- /dev/null +++ b/lib/nat_traversal/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +}