diff --git a/CMakeLists.txt b/CMakeLists.txt index 166f01a2..7d56cfc1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,20 +39,15 @@ build_core_library( tests/scene.test.cpp tests/jolt_type_conversion.test.cpp tests/jolt_engine.test.cpp - # tests/object.test.cpp PACKAGES tinyobjloader - TinyGLTF - # shaderc # uncomment to use shaderc ${SHADERC_PACKAGE} watcher vulkan-cpp LINK_PACKAGES tinyobjloader::tinyobjloader - TinyGLTF::TinyGLTF - # shaderc::shaderc # uncomment to use shaderc ${SHADERC_LINK_PACKAGE} watcher::watcher vulkan-cpp::vulkan-cpp diff --git a/atlas/core/common.hpp b/atlas/core/common.hpp index 65f3fea8..eee99ad2 100644 --- a/atlas/core/common.hpp +++ b/atlas/core/common.hpp @@ -2,6 +2,7 @@ // core includes #include +#include #include #include #include diff --git a/atlas/core/scene/exceptions.hpp b/atlas/core/scene/exceptions.hpp new file mode 100644 index 00000000..bbacc037 --- /dev/null +++ b/atlas/core/scene/exceptions.hpp @@ -0,0 +1,23 @@ +#pragma once +#include + +namespace atlas { + struct exception_block { + const char* data = nullptr; + }; + + class invalid_access_exception : public std::exception { + public: + invalid_access_exception() = default; + invalid_access_exception(const char* p_data) + : m_block(p_data) {} + + //! @return message given when this exception gets triggered + [[nodiscard]] const char* what() const noexcept override { + return m_block.data; + } + + private: + exception_block m_block; + }; +}; \ No newline at end of file diff --git a/atlas/core/scene/game_object.hpp b/atlas/core/scene/game_object.hpp new file mode 100644 index 00000000..972a33b0 --- /dev/null +++ b/atlas/core/scene/game_object.hpp @@ -0,0 +1,84 @@ +#pragma once +#include +#include + +namespace atlas { + + /** + * @brief Creates a pointer wrapper which extends capabilities of + * flecs::entity + * + * Provides our own construct of API's that handles any workload around some + * of the raw flecs API's that can still be used by other flecs API's + * without completely interacting touching raw flecs API + */ + class game_object : public flecs::entity { + public: + //! @brief Should not construct a scene object not created through + //! flecs::world + game_object() = delete; + + game_object(flecs::world_t* p_registry, flecs::entity_t p_id); + + game_object(const flecs::entity& p_base); + + explicit game_object(flecs::entity& p_base); + + /** + * @brief sets the entity to be a parent of the specified entity + * + * @param p_entity is the specified entity to specify as the parent. + * + * + * Example Usage: + * + * ```C++ + * + * atlas::game_object obj1 = entity("Parent"); + * + * atlas::game_object obj2 = entity("Chlid"); + * + * // obj2 is the child of obj1 + * // As obj1 is a parent node + * obj2.child_of(obj1); + * + * ``` + * + */ + void child_of(const std::optional& p_parent); + + /** + * @brief iterates through all children entities if the given entity is + * a parent of any given entities + * + * Example Usage: + * + * + * ```C++ + * atlas::game_object obj1 = entity("Parent Node"); + * atlas::game_object obj2 = entity("Chlid Node"); + * + * // obj1 is the parent of obj2. + * obj2.child_of(parent); + * + * // iteration should only include for "Child Node" + * obj1.children([](flecs::entity p_child){ + * // do stuff with the child entity + * }); + * + * ``` + */ + template + void children(UFunction&& p_callback) { + children(p_callback); + } + }; + + /** + * @brief Alias to std::optional + * + * This alias serves as a representation of game objects users can create + * and manage components with + */ + using game_object_optional = std::optional; +}; \ No newline at end of file diff --git a/atlas/core/scene/scene.hpp b/atlas/core/scene/scene.hpp index 12af1a79..68f67083 100644 --- a/atlas/core/scene/scene.hpp +++ b/atlas/core/scene/scene.hpp @@ -1,10 +1,8 @@ #pragma once #include -#include -#include #include -#include #include +#include namespace atlas { @@ -23,30 +21,33 @@ namespace atlas { * helps manages these scenes and consider them as contexts that can be * switched/toggled based on users transforms. */ - class scene_scope { + class scene { public: /** * @param p_name is the name given to this scene * @param p_bus is the globalized event bus that is given access to the * scene to subscribe events to it. */ - scene_scope(const std::string& p_name, event::event_bus& p_bus) - : m_name(p_name) - , m_bus(&p_bus) {} + scene(const std::string& p_name, event::event_bus& p_bus); - virtual ~scene_scope() = default; + virtual ~scene() = default; /** - * @brief Used to creating a game object + * @brief Retrieves if an entity already exists within the registry, + * create new entity otherwise * - * @param p_name is specified when creating or searching the object + * @param p_name is a string to set the name of the entity + */ + game_object entity(std::string_view p_name); + + /** + * @brief Retrieves if an entity already exists within the registry, + * create new entity otherwise * - * @return strong_ptr + * @param p_entity_id is the ID to retrieve an entity if it exists, + * otherwise returns a new entity. */ - strong_ref create_object(const std::string& p_name) { - return create_strong_ref( - m_allocator, &m_registry, p_name); - } + game_object entity(uint64_t p_id); /** * @brief subscribes an event to the event::bus to get invoked when @@ -59,6 +60,7 @@ namespace atlas { * callback belongs to * @param p_callback is the callback that contains an arbitrary task * that gets invoked when incoming updates occur from the publisher + * */ template void subscribe(UObject* p_instance, const UCallback& p_callback) { @@ -96,11 +98,38 @@ namespace atlas { std::forward(args)...); } + /** + * @return the number of children entities + * + * Example Usage: + * + * + * ```C++ + * + * atlas::scene scene("New Scene"); + * + * // creating obj1 (parent) and obj2 (child) + * atlas::game_object obj1 = scene.create("Parent"); + * + * atlas::game_object obj2 = scene.create("Chlid"); + * + * // obj2 is the child of obj1 + * // As obj1 is a parent node + * + * obj2.child_of(obj1); + * + * // Returns 1 + * uint32_t obj1_children = scene.children_count(obj1); + * + * ``` + */ + uint32_t children_count(const game_object& p_parent); + /** * @brief Defer operations until end of frame. - * When this operation is invoked while iterating, operations inbetween - * the defer_begin() and defer_end() operations are executed at the end - * of the frame. + * When this operation is invoked while iterating, operations + * inbetween the defer_begin() and defer_end() operations are executed + * at the end of the frame. * * This operation is thread safe. * @@ -120,22 +149,20 @@ namespace atlas { */ bool defer_end() { return m_registry.defer_end(); } - //! @return the name of atlas::scene_object + //! @return the name of the scene [[nodiscard]] std::string name() const { return m_name; } - //! @return the event::bus handle to do the subscription operation of - //! events + //! @return the event::bus handle for subscribing events [[nodiscard]] event::event_bus* event_handle() const { return m_bus; } /** * @brief Requires to return flecs::world is returned by reference to * prevent making copies of flecs::world */ - operator world&() { return m_registry; } + operator flecs::world&() { return m_registry; } private: - std::pmr::polymorphic_allocator<> m_allocator; - world m_registry; + flecs::world m_registry; std::string m_name; event::event_bus* m_bus = nullptr; }; diff --git a/atlas/core/scene/scene_object.hpp b/atlas/core/scene/scene_object.hpp deleted file mode 100644 index 3c8bf869..00000000 --- a/atlas/core/scene/scene_object.hpp +++ /dev/null @@ -1,177 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include - -namespace atlas { - - /** - * @brief scene_object represents a game obejct that is associated to a - * specific scene. - * - * This class is a wrapper around flecs::entity that provides API's useful - * for the user to perform specific operations. - * - * Operations that are included is iterations over children entities if the - * specific entity is a parent over any specified entity. - * - * atlas::scene_object are represented through the strong_ptr type to ensure - * for memory safety. Ensuring objects that are being created are not - * temporary, but also do not invoke default construction. - * - * - * Example Usage: - * - * ```C++ - * strong_ptr obj1 = scene->create_object("Cube"); - * obj1->add(); - * ``` - * - * TOOD: Need attention into revising how this is currently designed. - */ - class scene_object { - public: - /*** - * @param p_registry is the address to the ecs registry - * @param p_name is the name supplied to the entity - */ - scene_object(flecs::world* p_registry, const std::string& p_name); - - /*** - * @param p_registry is the address to the ecs registry - * @param p_name is the name supplied to the entity - * @param p_lookup is the tag to indicate lookup for alread-existing - * entity in flecs::world - */ - scene_object(flecs::world* p_registry, - const std::string& p_name, - bool p_lookup); - - /** - * @param p_registry is a strong_ptr that is expected to be always valid - * and manages this entity when application closes - */ - scene_object(strong_ref& p_registry, - const std::string& p_name); - - ~scene_object(); - - //! @brief adds a component to the entity - template - void add() { - m_entity.add(); - } - - //! @brief adds a component with an assigned value to the entity - template - void add(UComponent p_component_value) const { - m_entity.add(p_component_value); - } - - //! @brief sets the scene object to correspond to a specified parent - void child_of(const strong_ref& p_parent) { - flecs::entity e = *p_parent; - m_entity.add(flecs::ChildOf, e); - } - - //! @brief iterates the entity children entities - template - void children(UFunction&& p_callback) { - m_entity.children(p_callback); - } - - //! @return the entity's ID - [[nodiscard]] uint32_t id() const { return m_entity.id(); } - - //! @return true if entity is alive, otherwise return false - [[nodiscard]] bool is_alive() const { return m_entity.is_alive(); } - - //! @return true if entity is valid, otherwise return false - [[nodiscard]] bool is_valid() const { return m_entity.is_valid(); } - - /** - * @brief Adds multiple components with no values assigned to them - * EXPERIEMENTAL: Function to add multiple components but still in its - * experiemental stages. - * - * Ideally this would be a shorthand for adding in multiple components - * onto a single given entity - * - * Example: - * ```C++ - * m_entity_example->add_query(); - * ``` - */ - template - void add_query() { - using tuple_variadic = std::tuple; - std::variant conditions; - std::visit( - [&](const auto& p_component) { - std::apply( - [&](auto&... p_placeholder) { - (m_entity.add>(), - ...); - }, - p_component); - }, - conditions); - } - - //! @return nullptr if entity is not found, otherwise return view of the - //! component - template - [[nodiscard]] const UComponent* get() const { - return m_entity.get(); - } - - //! @return nullptr if entity is not found, otherwise return mutable - //! component - template - [[nodiscard]] UComponent* get_mut() { - return m_entity.get_mut(); - } - - //! @brief is true if component stored in this entity - template - bool has() { - return m_entity.has(); - } - - /** - * @brief set is used to set a component and to set the values of - * that specified component to the entity as an entire operation - * - * @tparam UComponent is the type of component - * - */ - template - void set(const UComponent& p_component) { - m_entity.set(p_component); - } - - //! @brief removes specified component from the entity - template - [[nodiscard]] flecs::entity& remove() const { - return m_entity.remove(); - } - - //! @brief Explicitly for deleting the entity - void destruct() const { m_entity.destruct(); } - - //! @brief treating atlas::scene_object class as a const flecs::entity - //! for ease of access, if we do not want to modify this overload - //! specifically - operator flecs::entity() const { return m_entity; } - - //! @brief treating atlas::scene_object class as a flecs::entity for - //! ease of access - operator flecs::entity() { return m_entity; } - - private: - entity_t m_entity; - }; -}; // namespace atlas \ No newline at end of file diff --git a/atlas/core/scene/types.hpp b/atlas/core/scene/types.hpp deleted file mode 100644 index fb0e7b6f..00000000 --- a/atlas/core/scene/types.hpp +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include - -namespace atlas { - // Alias to flecs::entity - using entity_t = flecs::entity; - - // Alias to flecs::world - using world = flecs::world; -}; \ No newline at end of file diff --git a/atlas/core/scene/world.hpp b/atlas/core/scene/world.hpp index 8a3bda8d..f8fd96fb 100644 --- a/atlas/core/scene/world.hpp +++ b/atlas/core/scene/world.hpp @@ -24,18 +24,19 @@ namespace atlas { * * */ - class world_scope { + class world { public: - world_scope() = delete; + world() = delete; /** - * @brief construct a new world_scope with a specified name associated + * @brief construct a new world with a specified name associated * with it */ - world_scope(const std::string& p_name); - ~world_scope(); + world(const std::string& p_name); - //! @return the name of world_scope + virtual ~world() = default; + + //! @return the name of world [[nodiscard]] std::string name() const { return m_name; } /** @@ -45,16 +46,7 @@ namespace atlas { * scenes as this is quite problematic. Should direct attention to this * soon. */ - void add_scene(const ref& p_scene_context); - - template - ref create_custom_scene(const std::string& p_name) { - static_assert( - std::is_base_of_v, - "Must be a scene that inherits from scene_scope as a base class"); - m_scene_container[p_name] = create_ref(p_name); - return m_scene_container[p_name]; - } + void add_scene(const ref& p_scene_context); /** * @brief get_scene allows for specifically querying for current scenes @@ -64,18 +56,18 @@ namespace atlas { * the player is in within the world, then provide the current scene * based on that information */ - ref get_scene(const std::string& p_tag) { + ref get_scene(const std::string& p_tag) { if (!m_scene_container.contains(p_tag)) { throw std::runtime_error( - "Could not access ref from " - "world_scope::get_scene(const string& p_tag)!!!"); + "Could not access ref from " + "world::get_scene(const string& p_tag)!!!"); } return m_scene_container[p_tag]; } private: - std::map> m_scene_container; - ref m_world_shared_instance; + std::map> m_scene_container; + ref m_world_shared_instance; std::string m_name = "Undefined Tag"; }; }; // namespace atlas \ No newline at end of file diff --git a/atlas/core/serialize/serializer.hpp b/atlas/core/serialize/serializer.hpp index 4abf817b..ac5c09ba 100644 --- a/atlas/core/serialize/serializer.hpp +++ b/atlas/core/serialize/serializer.hpp @@ -24,7 +24,7 @@ namespace atlas { * @param p_scene_ctx is the current scene to perform * serialization/deserialization to */ - serializer(const ref& p_scene_ctx); + serializer(const ref& p_scene_ctx); /** * @param p_filepath is the specified path to save the file @@ -42,7 +42,7 @@ namespace atlas { const flecs::world& p_registry); private: - ref m_current_scene_ctx; + ref m_current_scene_ctx; }; }; // namespace atlas \ No newline at end of file diff --git a/atlas/core/system/registry.hpp b/atlas/core/system/registry.hpp index 0c7382d4..5333f255 100644 --- a/atlas/core/system/registry.hpp +++ b/atlas/core/system/registry.hpp @@ -37,7 +37,7 @@ namespace atlas { */ /** - * @brief constructs a new world_scope + * @brief constructs a new world * * Initially this was used to create a world with a specified name * associated with it @@ -45,30 +45,30 @@ namespace atlas { * This was used for getting world to be maintained implicitly by * system_registry, though this will be changing. */ - static ref create_world(const std::string& p_tag); + static ref create_world(const std::string& p_tag); - //! @brief Searches and returns world_scope if found - //! @brief Returns nullptr if world_scope not found + //! @brief Searches and returns world if found + //! @brief Returns nullptr if world not found /** * @brief searches in getting the world and looks up based on its * specified name * * @return nullptr if not found, otherwise return - * shared_ptr + * shared_ptr */ - static ref get_world(const std::string& p_tag); + static ref get_world(const std::string& p_tag); private: - ref search_world(const std::string& p_tag); + ref search_world(const std::string& p_tag); - void append_world(const ref& p_world); + // void append_world(const ref& p_world); - ref append_world_scope(const ref& p_world); + ref append_world_and_get(const ref& p_world); private: static system_registry* s_instance; std::string m_tag = "Undefined"; - std::map> m_world_registered; + std::map> m_world_registered; }; }; \ No newline at end of file diff --git a/atlas/core/ui/widgets.hpp b/atlas/core/ui/widgets.hpp index 483e16bf..3043670c 100644 --- a/atlas/core/ui/widgets.hpp +++ b/atlas/core/ui/widgets.hpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include namespace atlas::ui { @@ -64,11 +64,13 @@ namespace atlas::ui { float p_reset_value = 0.f); /** - * @brief For UI rendering text as input + * @brief UI rendering input text * - * @param p_value is specified string for drawing input text to imgui's + * + * @param p_dst is the destination string to be changed + * @param p_src is the original string that was previously given */ - void draw_input_text(std::string& p_value); + void draw_input_text(std::string& p_dst, std::string& p_src); /** * @brief For UI rendering text to display and not input diff --git a/atlas/objects_10.engine b/atlas/objects_10.engine deleted file mode 100644 index 0c752c66..00000000 --- a/atlas/objects_10.engine +++ /dev/null @@ -1,210 +0,0 @@ -Scene: Untitled -Entities: - - Entity: 13670344671586780811 - Tag Component: - Tag: Actor 10 - TransformComponent: - Translation: [-0.600000024, 6.4000001, 0] - Rotation: [0, 0, 0.466002911] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [0.276053309, 0.759803891, 0.245818913, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 1 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 565836664600690285 - Tag Component: - Tag: Actor 9 - TransformComponent: - Translation: [-1.5, 5.0999999, 0] - Rotation: [0, 0, 0.588175952] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [0.123798534, 0.789215684, 0.123798534, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 1 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 11429847431533605332 - Tag Component: - Tag: Actor 8 - TransformComponent: - Translation: [1.20000005, 4.5999999, 0] - Rotation: [0, 0, 0] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [0.769607842, 0.27539891, 0.27539891, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 1 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 5257323963177412509 - Tag Component: - Tag: Actor 7 - TransformComponent: - Translation: [-2, 3.9000001, 0] - Rotation: [0, 0, 0.752236903] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [0.663481951, 0.159602046, 0.79411763, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 1 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 5806905725956582174 - Tag Component: - Tag: Actor 6 - TransformComponent: - Translation: [0.300000012, 5.5, 0] - Rotation: [0, 0, 0.542797387] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [0.389081091, 0.528394043, 0.862745106, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 1 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 12473161709214016708 - Tag Component: - Tag: Actor 5 - TransformComponent: - Translation: [-1.60000002, 2.5999999, 0] - Rotation: [0, 0, 0.706858337] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [0.42892158, 0.857843161, 0.529844284, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 1 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 266257173355641678 - Tag Component: - Tag: Actor 4 - TransformComponent: - Translation: [0.400000006, 2.79999995, 0] - Rotation: [0, 0.104719758, 0.778416812] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [0.344675094, 0.732204258, 0.799019575, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 1 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 4527899839142223245 - Tag Component: - Tag: Actor 3 - TransformComponent: - Translation: [-0.600000024, 3.70000005, 0] - Rotation: [0, 0, 0] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [0.63233602, 0.41522494, 0.784313738, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 1 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 10652494166102869686 - Tag Component: - Tag: Actor 2 - TransformComponent: - Translation: [-0.0891839564, 1.15999997, 0] - Rotation: [0, 0, 0.125115439] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [0.941176474, 0.226066872, 0.226066872, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 1 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 8530241877619612650 - Tag Component: - Tag: Camera - TransformComponent: - Translation: [0, 0, 0] - Rotation: [0, 0, 0] - Scale: [1, 1, 1] - CameraComponent: - Camera: - ProjectionType: 1 - PerspectiveFOV: 0.785398185 - PerspectiveNear: 0.00999999978 - PerspectiveFar: 1000 - OrthographicSize: 10 - OrthographicNear: -1 - OrthographicFar: 1 - Primary: true - FixedAspectRatio: false - - Entity: 4010856451712828404 - Tag Component: - Tag: Actor 1 - TransformComponent: - Translation: [1.4940106e-08, -1.10000014, 0] - Rotation: [0, 0, 0.125663668] - Scale: [7.30000067, 0.5, 5.19999981] - SpriteRendererComponent: - Color: [1, 1, 1, 1] - RigidBody2DComponent: - BodyType: Static - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 1 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 \ No newline at end of file diff --git a/atlas/objects_20.engine b/atlas/objects_20.engine deleted file mode 100644 index 705bf4d2..00000000 --- a/atlas/objects_20.engine +++ /dev/null @@ -1,381 +0,0 @@ -Scene: Untitled -Entities: - - Entity: 17198966059941728731 - Tag Component: - Tag: Actor 20 - TransformComponent: - Translation: [1.20000005, 8, 0] - Rotation: [0, 0, 0] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [1, 1, 1, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 1 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 6801278441136382236 - Tag Component: - Tag: Actor 19 - TransformComponent: - Translation: [-1.60000002, 6.5, 0] - Rotation: [0, 0, 0] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [1, 1, 1, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 1 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 5027702570458899016 - Tag Component: - Tag: Actor 18 - TransformComponent: - Translation: [3, 9.5, 0] - Rotation: [0, 0, 0] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [1, 1, 1, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 1 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 924190211859625645 - Tag Component: - Tag: Actor 17 - TransformComponent: - Translation: [1.39999998, 0.200000003, 0] - Rotation: [0, 0, 0] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [1, 1, 1, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 1 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 14096078862407024834 - Tag Component: - Tag: Actor 16 - TransformComponent: - Translation: [0, 0, 0] - Rotation: [0, 0, 0.600393295] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [1, 1, 1, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 1 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 4325675049849306465 - Tag Component: - Tag: Actor 15 - TransformComponent: - Translation: [0, 9.39999962, 0] - Rotation: [0, 0, 0.612610519] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [1, 1, 1, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 1 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 13455568828216614227 - Tag Component: - Tag: Actor 14 - TransformComponent: - Translation: [0.899999976, 6.69999981, 0] - Rotation: [0, 0, 0.565486729] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [0.284265667, 0.380295038, 0.828431368, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 1 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 7728243223071681250 - Tag Component: - Tag: Actor 13 - TransformComponent: - Translation: [-1.39999998, 8.39999962, 0] - Rotation: [0, 0, 0.35953784] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [0.862745106, 0.186082274, 0.604021192, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 1 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 17907352828054141178 - Tag Component: - Tag: Actor 12 - TransformComponent: - Translation: [0, 8.30000019, -1.39999998] - Rotation: [0, 0, 0.617846549] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [0.877451003, 0.768655181, 0.137639359, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 1 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 891104325792 - Tag Component: - Tag: Actor 1 - TransformComponent: - Translation: [1.4940106e-08, -3.5999999, 0] - Rotation: [0, 0, 0.125663668] - Scale: [23.6000004, 2.0999999, 5.19999981] - SpriteRendererComponent: - Color: [1, 1, 1, 1] - RigidBody2DComponent: - BodyType: Static - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 0.5 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 891104325792 - Tag Component: - Tag: Camera - TransformComponent: - Translation: [0, 0, 0] - Rotation: [0, 0, 0] - Scale: [1, 1, 1] - CameraComponent: - Camera: - ProjectionType: 1 - PerspectiveFOV: 0.785398185 - PerspectiveNear: 0.00999999978 - PerspectiveFar: 1000 - OrthographicSize: 10 - OrthographicNear: -1 - OrthographicFar: 1 - Primary: true - FixedAspectRatio: false - - Entity: 891104325792 - Tag Component: - Tag: Actor 2 - TransformComponent: - Translation: [-0.0891839564, 1.15999997, 0] - Rotation: [0, 0, 0.125115439] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [0.941176474, 0.226066872, 0.226066872, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 0.5 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 891104325792 - Tag Component: - Tag: Actor 3 - TransformComponent: - Translation: [-0.600000024, 3.70000005, 0] - Rotation: [0, 0, 0] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [0.63233602, 0.41522494, 0.784313738, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 0.5 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 891104325792 - Tag Component: - Tag: Actor 4 - TransformComponent: - Translation: [0.400000006, 2.79999995, 0] - Rotation: [0, 0.104719758, 0.778416812] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [0.344675094, 0.732204258, 0.799019575, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 0.5 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 891104325792 - Tag Component: - Tag: Actor 5 - TransformComponent: - Translation: [-1.60000002, 2.5999999, 0] - Rotation: [0, 0, 0.706858337] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [0.42892158, 0.857843161, 0.529844284, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 0.5 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 891104325792 - Tag Component: - Tag: Actor 6 - TransformComponent: - Translation: [0.300000012, 5.5, 0] - Rotation: [0, 0, 0.542797387] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [0.389081091, 0.528394043, 0.862745106, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 0.5 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 891104325792 - Tag Component: - Tag: Actor 7 - TransformComponent: - Translation: [-2, 3.9000001, 0] - Rotation: [0, 0, 0.752236903] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [0.663481951, 0.159602046, 0.79411763, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 0.5 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 891104325792 - Tag Component: - Tag: Actor 8 - TransformComponent: - Translation: [1.20000005, 4.5999999, 0] - Rotation: [0, 0, 0] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [0.769607842, 0.27539891, 0.27539891, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 0.5 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 891104325792 - Tag Component: - Tag: Actor 9 - TransformComponent: - Translation: [-1.5, 5.0999999, 0] - Rotation: [0, 0, 0.588175952] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [0.123798534, 0.789215684, 0.123798534, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 0.5 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 - - Entity: 891104325792 - Tag Component: - Tag: Actor 10 - TransformComponent: - Translation: [-0.600000024, 6.4000001, 0] - Rotation: [0, 0, 0.466002911] - Scale: [1, 1, 1] - SpriteRendererComponent: - Color: [0.276053309, 0.759803891, 0.245818913, 1] - RigidBody2DComponent: - BodyType: Dynamic - FixedRotation: false - BoxCollider2DComponent: - Offset: [0, 0] - Size: [0.5, 0.5] - Density: 0.5 - Friction: 0.5 - Resitution: 0 - ResitutionThreshold: 0.5 \ No newline at end of file diff --git a/conanfile.py b/conanfile.py index 43acfe52..e3006948 100644 --- a/conanfile.py +++ b/conanfile.py @@ -6,7 +6,7 @@ class AtlasRecipe(ConanFile): name = "atlas" - version = "0.3" + version = "0.4" package_type = "library" license = "Apache-2.0" homepage = "https://github.com/engine3d-dev/TheAtlasEngine" @@ -33,7 +33,7 @@ def requirements(self): self.requires("imguidocking/2.0") self.requires("flecs/4.0.4") self.requires("glfw/3.4") - self.requires("spdlog/1.15.1") + self.requires("spdlog/1.16.0") self.requires("glm/1.0.1") self.requires("yaml-cpp/0.8.0") @@ -41,7 +41,6 @@ def requirements(self): self.requires("vulkan-headers/1.3.290.0") self.requires("vulkan-cpp/3.0") self.requires("tinyobjloader/2.0.0-rc10") - self.requires("tinygltf/2.9.0") self.requires("stb/cci.20230920") self.requires("nfd/1.0") diff --git a/editor/application.cpp b/editor/application.cpp index efb8950f..6c9ccc3e 100644 --- a/editor/application.cpp +++ b/editor/application.cpp @@ -1,15 +1,31 @@ #include #include "editor_world.hpp" +#include +#include +/** + * This represents our editor's application + * + * TODO: Add a preload API to preload the application. For providing user + * preferences, project settings, or other configuration settings that are + * projects-related + */ class editor_application : public atlas::application { public: editor_application(const atlas::application_settings& p_settings) : application(p_settings) { - m_world = atlas::create_ref("Editor World"); + std::pmr::monotonic_buffer_resource resource{ 4096 }; + m_allocator.construct(&resource); + + // TODO -- this is going to be changed with the use of the level + // streamer API + m_world = + atlas::create_strong_ref(m_allocator, "Editor World"); } private: - atlas::ref m_world; + std::pmr::polymorphic_allocator m_allocator; + atlas::optional_ref m_world; }; namespace atlas { diff --git a/editor/editor_world.cpp b/editor/editor_world.cpp index 2a96082f..b0b070ef 100644 --- a/editor/editor_world.cpp +++ b/editor/editor_world.cpp @@ -1,6 +1,7 @@ #include "editor_world.hpp" #include #include +#include "level_scene.hpp" editor_world::editor_world() { console_log_fatal("Instantiate Default editor_world!"); @@ -15,6 +16,7 @@ editor_world::editor_world(const std::string& p_tag) { m_bus.create_listener(); m_bus.create_listener(); - m_first_scene = atlas::create_ref("LevelScene", m_bus); - m_main_world->add_scene(m_first_scene); + atlas::ref first_scene = + atlas::create_ref("LevelScene", m_bus); + m_main_world->add_scene(first_scene); } \ No newline at end of file diff --git a/editor/editor_world.hpp b/editor/editor_world.hpp index 29460b02..4426dbc7 100644 --- a/editor/editor_world.hpp +++ b/editor/editor_world.hpp @@ -1,5 +1,4 @@ #pragma once -#include "level_scene.hpp" #include #include @@ -9,10 +8,7 @@ class editor_world { editor_world(const std::string& p_tag); private: - // atlas::ref m_main_world; - atlas::ref m_main_world; - //! TODO: Would be handled by our system registry - atlas::ref m_first_scene; + atlas::ref m_main_world; atlas::event::event_bus m_bus; }; \ No newline at end of file diff --git a/editor/level_scene-new.cpp b/editor/level_scene-new.cpp deleted file mode 100644 index 4e2681a8..00000000 --- a/editor/level_scene-new.cpp +++ /dev/null @@ -1,719 +0,0 @@ -#include "level_scene.hpp" -#include -#include -#include -#include - -level_scene::level_scene(const std::string& p_name, - atlas::event::event_bus& p_bus) - : atlas::scene_scope(p_name, p_bus) { - m_camera = create_object("Editor Camera"); - m_camera->add>(); - m_camera->set({ - .position = { 3.50f, 4.90f, 36.40f }, - .scale{ 1.f }, - }); - m_camera->set({ - .plane = { 0.1f, 5000.f }, - .is_active = true, - .field_of_view = 45.f, - }); - - m_object = create("Bob"); - - m_object2 = create2("Bob2"); - - m_viking_room = create_object("Viking Room"); - m_viking_room->add(); - m_viking_room->set({ - .position = { -2.70f, 2.70, -8.30f }, - .rotation = { 2.30f, 95.90f, 91.80f }, - .scale{ 1.f }, - }); - - m_viking_room->set({ - .radius = 1.0f, - }); - - m_viking_room->set({ - .friction = 15.f, - .restitution = 0.3f, - .body_movement_type = atlas::dynamic, - }); - - m_cube = create_object("Aircraft"); - - m_cube->set({ - .position = { 0.f, 2.10f, -7.30f }, - .scale = { 0.9f, 0.9f, 0.9f }, - }); - - m_cube->set({ - .color = { 1.f, 1.f, 1.f, 1.f }, - // .model_path = "assets/models/E 45 Aircraft_obj.obj", - .model_path = "assets/backpack/backpack.obj", - .diffuse = "assets/backpack/diffuse.jpg", - .specular = "assets/backpack/specular.jpg" - // .diffuse = "assets/models/E-45-steel detail_2_col.jpg", - }); - - // atlas::material_metadata data = { - // .ambient = {0.2f, 0.2f, 0.2f}, - // .diffuse = {0.5f, 0.5f, 0.5f}, - // .specular = {1.0f, 1.0f, 1.0f}, - // .shininess = 64.f, - // }; - // m_cube->set(data); - - m_robot_model = create_object("Cube"); - m_robot_model->add(); - // m_robot_model->add(); - m_robot_model->set({ - .position = { -2.70, 3.50f, 4.10f }, - .scale = { 1.f, 1.f, 1.f }, - }); - - m_robot_model->set( - { .color = { 1.f, 1.f, 1.f, 1.f }, - .model_path = "assets/models/cube.obj", - .diffuse = "assets/models/container_diffuse.png", - .specular = "assets/models/container_specular.png" }); - - m_robot_model->set({ - .half_extent = { 1.f, 1.f, 1.f }, - }); - m_robot_model->set({ - // .restitution = 1.f, - .body_movement_type = atlas::dynamic, - }); - - m_child_object = create_object("Child"); - m_child_object->child_of(m_robot_model); - - m_platform = create_object("Platform"); - - m_platform->set({ - .scale = { 15.f, 0.30f, 10.0f }, - }); - m_platform->set({ - .model_path = "assets/models/cube.obj", - .diffuse = "assets/models/wood.png", - }); - m_platform->set({ - .body_movement_type = atlas::fixed, - }); - m_platform->set({ - .half_extent = { 15.f, 0.30f, 10.0f }, - }); - - m_point_light = create_object("Point Light 1"); - m_point_light->set({ - .position = { 0.f, 2.10f, -7.30f }, - .scale = { 0.9f, 0.9f, 0.9f }, - }); - - m_point_light->set({ - .model_path = "assets/models/cube.obj", - .diffuse = "assets/models/wood.png", - }); - m_point_light->add(); - - // for(size_t i = 0; i < 26; i++) { - // auto obj = create_object(std::format("Object #{}", i)); - // obj->set({ - // .restitution = 1.25f, - // .body_movement_type = atlas::dynamic, - // }); - - // obj->set( - // { - // .radius = 1.0f, - // }); - - // glm::vec3 pos = {float(0*1.4),float(0 * 1.4),float(0 * -3) }; - - // obj->set({ - // .position = pos, - // .rotation = {.3f, 0.0f, 0.0f}, - // }); - - // obj->set({ - // .model_path = "assets/models/Ball OBJ.obj", - // .diffuse = "assets/models/clear.png", - // }); - // m_many_objects.emplace_back(obj); - // } - - // Just adding this here, for testing purposes - // Basic serialization for testing to conform how the editor may work - // TODO -- this would be done through either a stream_writer that can - // look at the structure of the graph and serialize according - // m_post_serializer_test = serializer(current_scene); - // m_post_serializer_test.save("LevelScene"); - m_deserializer_test = atlas::serializer(); - m_current_selected_file = "LevelScene"; - - subscribe(this, - &level_scene::collision_enter); - - atlas::register_start(this, &level_scene::start); - atlas::register_physics(this, &level_scene::physics_update); - atlas::register_update(this, &level_scene::on_update); - atlas::register_ui(this, &level_scene::on_ui_update); -} - -void -level_scene::collision_enter(atlas::event::collision_enter& p_event) { - console_log_warn("collision_enter event!!!"); - flecs::world registry = *this; - flecs::entity e1 = registry.entity(p_event.entity1); - flecs::entity e2 = registry.entity(p_event.entity2); - - console_log_warn("Entity1 = {}", e1.name().c_str()); - console_log_warn("Entity2 = {}", e2.name().c_str()); -} - -void -level_scene::collision_persisted(atlas::event::collision_persisted& p_event) { - console_log_warn("collision_persisted(p_event) invoked!!"); - flecs::world registry = *this; - flecs::entity e1 = registry.entity(p_event.entity1); - flecs::entity e2 = registry.entity(p_event.entity2); - - console_log_warn("Entity1 = {}", e1.name().c_str()); - console_log_warn("Entity2 = {}", e2.name().c_str()); -} - -void -level_scene::runtime_start() { - // runs the physics simulation - m_physics_is_runtime = true; - - m_physics_engine_handler.start(); -} - -void -level_scene::runtime_stop() { - m_physics_is_runtime = false; - - m_physics_engine_handler.stop(); - - reset_objects(); -} - -void -level_scene::reset_objects() { - - if (!m_deserializer_test.load("LevelScene", *this)) { - console_log_error("Could not load yaml file LevelScene!!!"); - } -} - -void -ui_component_list(flecs::entity& p_selected_entity) { - std::string entity_name = p_selected_entity.name().c_str(); - atlas::ui::draw_input_text(entity_name); - - ImGui::SameLine(); - ImGui::PushItemWidth(-1); - if (ImGui::Button("Add Component")) { - ImGui::OpenPopup("Add Component"); - } - - if (ImGui::BeginPopup("Add Component")) { - if (!p_selected_entity.has()) { - if (ImGui::MenuItem("Perspective Camera")) { - p_selected_entity.add< - flecs::pair>(); - p_selected_entity.add(); - ImGui::CloseCurrentPopup(); - } - } - - if (!p_selected_entity.has()) { - if (ImGui::MenuItem("Mesh Source")) { - p_selected_entity.add(); - ImGui::CloseCurrentPopup(); - } - } - - if (!p_selected_entity.has()) { - if (ImGui::MenuItem("Point Light")) { - p_selected_entity.add(); - ImGui::CloseCurrentPopup(); - } - } - - if (!p_selected_entity.has()) { - if (ImGui::MenuItem("Serialize")) { - p_selected_entity.add(); - ImGui::CloseCurrentPopup(); - } - } - - if (!p_selected_entity.has()) { - if (ImGui::MenuItem("Physics Body")) { - p_selected_entity.add(); - ImGui::CloseCurrentPopup(); - } - } - - if (!p_selected_entity.has()) { - if (ImGui::MenuItem("Box Collider")) { - p_selected_entity.add(); - ImGui::CloseCurrentPopup(); - } - } - - if (!p_selected_entity.has()) { - if (ImGui::MenuItem("Sphere Collider")) { - p_selected_entity.add(); - ImGui::CloseCurrentPopup(); - } - } - - if (!p_selected_entity.has()) { - if (ImGui::MenuItem("Capsule Collider")) { - p_selected_entity.add(); - ImGui::CloseCurrentPopup(); - } - } - ImGui::EndPopup(); - } - - ImGui::PopItemWidth(); -} - -void -level_scene::on_ui_update() { - - // setting up the dockspace UI widgets at the window toolbar - m_editor_dockspace.begin(); - - try { - m_editor_menu.begin(); - } - catch (const atlas::ui::menu_bar_exception& e) { - } - - // specify the label and the state to execute when this specific widget has - // been triggered - m_editor_menu.add_child("Exit", []() { - glfwSetWindowShouldClose(atlas::application::get_window(), true); - }); - m_editor_menu.end(); - - if (ImGui::Begin("Viewport")) { - glm::vec2 viewport_panel_size = - glm::vec2{ atlas::application::get_window().width(), - atlas::application::get_window().height() }; - - ImGui::End(); - } - - defer_begin(); - auto query_builder = this->query_builder().build(); - - if (ImGui::Begin("Scene Heirarchy")) { - // @note right click on blank space - // @param string_id - // @param popup_flags - will be the mouse flag (0=right, 1=left) - if (atlas::ui::begin_popup_context_window(nullptr, 1, false)) { - if (ImGui::MenuItem("Create Empty Entity")) { - // TODO -- Converting the operation to use strong_ptr to make - // these operation more conformed - m_create_entity = create_object("Empty Entity"); - } - ImGui::EndPopup(); - } - - query_builder.each([&](flecs::entity p_entity, atlas::transform&) { - // We set the imgui flags for our scene heirarchy panel - // TODO -- Make the scene heirarchy panel a separate class that is - // used for specify the layout and other UI elements here - ImGuiTreeNodeFlags flags = - ((m_selected_entity == p_entity) ? ImGuiTreeNodeFlags_Selected - : 0) | - ImGuiTreeNodeFlags_OpenOnArrow; - flags |= ImGuiTreeNodeFlags_SpanAvailWidth; - flags |= ImGuiWindowFlags_Popup; - bool opened = ImGui::TreeNodeEx(p_entity.name().c_str(), flags); - if (ImGui::IsItemClicked()) { - m_selected_entity = p_entity; - // m_create_entity = search_entity(p_entity.name().c_str()); - } - - bool delete_entity = false; - if (ImGui::BeginPopupContextItem()) { - if (ImGui::MenuItem("Delete Entity")) { - delete_entity = true; - } - ImGui::EndPopup(); - } - - if (delete_entity) { - // _context->destroyEntity(entity); - m_selected_entity.destruct(); - } - - if (opened) { - flags = ImGuiTreeNodeFlags_OpenOnArrow | - ImGuiTreeNodeFlags_SpanAvailWidth; - auto query_children_builder = - this->query_builder().with(flecs::ChildOf, p_entity).build(); - int32_t child_count = query_children_builder.count(); - - // // Only show children in scene heirarchy panel if there are - // children entities - if (child_count > 0) { - m_selected_entity.children([&](flecs::entity p_child) { - opened = - ImGui::TreeNodeEx(p_child.name().c_str(), flags); - if (opened) { - if (ImGui::IsItemClicked()) { - m_selected_entity = p_child; - } - ImGui::TreePop(); - } - }); - } - - ImGui::TreePop(); - } - }); - - defer_end(); - ImGui::End(); - } - - if (ImGui::Begin("Properties")) { - if (m_selected_entity.is_alive()) { - ui_component_list(m_selected_entity); - - atlas::ui::draw_component( - "transform", - m_selected_entity, - [](atlas::transform* p_transform) { - atlas::ui::draw_vec3("Position", p_transform->position); - atlas::ui::draw_vec3("Scale", p_transform->scale); - atlas::ui::draw_vec3("Rotation", p_transform->rotation); - }); - - atlas::ui::draw_component( - "camera", - m_selected_entity, - [this](atlas::perspective_camera* p_camera) { - atlas::ui::draw_float("field of view", - p_camera->field_of_view); - ImGui::Checkbox("is_active", &p_camera->is_active); - ImGui::DragFloat("Speed", &m_movement_speed); - }); - - /* - atlas::ui::draw_component("Directional - Light", m_selected_entity, [](atlas::directional_light* - p_dir_light){ ImGui::DragFloat4("Direction", - glm::value_ptr(p_dir_light->direction)); ImGui::DragFloat4("View - Pos", glm::value_ptr(p_dir_light->view_position)); - ImGui::DragFloat4("Color", glm::value_ptr(p_dir_light->color)); - ImGui::DragFloat4("Ambient", - glm::value_ptr(p_dir_light->ambient)); ImGui::DragFloat4("Diffuse", - glm::value_ptr(p_dir_light->diffuse)); ImGui::DragFloat4("Specular", - glm::value_ptr(p_dir_light->specular)); - }); - */ - - atlas::ui::draw_component( - "Point Light", - m_selected_entity, - [](atlas::point_light* p_dir_light) { - ImGui::DragFloat4( - "Color", glm::value_ptr(p_dir_light->color), 0.01); - ImGui::DragFloat( - "Attenuation", &p_dir_light->attenuation, 0.001); - ImGui::DragFloat4( - "Ambient", glm::value_ptr(p_dir_light->ambient), 0.01); - ImGui::DragFloat4( - "Diffuse", glm::value_ptr(p_dir_light->diffuse), 0.01); - ImGui::DragFloat4( - "Specular", glm::value_ptr(p_dir_light->specular), 0.01); - ImGui::DragFloat("Constant", &p_dir_light->constant, 0.01); - ImGui::DragFloat("Linear", &p_dir_light->linear, 0.01); - ImGui::DragFloat("Quadratic", &p_dir_light->quadratic, 0.01); - }); - - atlas::ui::draw_component( - "atlas::mesh_source", - m_selected_entity, - [](atlas::mesh_source* p_source) { - atlas::ui::draw_input_text(p_source->model_path); - atlas::ui::draw_vec4("Color", p_source->color); - }); - - atlas::ui::draw_component( - "material", - m_selected_entity, - [](atlas::material_metadata* p_source) { - float speed = 0.01f; - ImGui::DragFloat4( - "Ambient", glm::value_ptr(p_source->ambient), speed); - ImGui::DragFloat4( - "Diffuse", glm::value_ptr(p_source->diffuse), speed); - ImGui::DragFloat4( - "Specular", glm::value_ptr(p_source->specular), speed); - atlas::ui::draw_float("Shininess", p_source->shininess); - }); - - atlas::ui::draw_component( - "Physics Body", - m_selected_entity, - [](atlas::physics_body* p_body) { - std::array items = { - "Static", - "Kinematic", - "Dynamic", - }; - std::string combo_preview = items[p_body->body_movement_type]; - - // Begin the combo box - if (ImGui::BeginCombo("Body Type", combo_preview.data())) { - for (int n = 0; n < 3; n++) { - // Check if the current item is selected - const bool is_selected = - (p_body->body_movement_type == n); - if (ImGui::Selectable(items[n].data(), is_selected)) { - // Update the current type when a new item is - // selected - p_body->body_movement_type = - static_cast(n); - } - - // Set the initial focus when the combo box is first - // opened - if (is_selected) { - ImGui::SetItemDefaultFocus(); - } - } - ImGui::EndCombo(); - } - - // physics body parameters - atlas::ui::draw_vec3("Linear Velocity", - p_body->linear_velocity); - atlas::ui::draw_vec3("Angular Velocity", - p_body->angular_velocity); - atlas::ui::draw_vec3("Force", p_body->force); - atlas::ui::draw_vec3("Impulse", p_body->impulse); - atlas::ui::draw_vec3("Torque", p_body->torque); - atlas::ui::draw_vec3("Center Mass", - p_body->center_mass_position); - }); - - atlas::ui::draw_component( - "Box Collider", - m_selected_entity, - [](atlas::box_collider* p_collider) { - atlas::ui::draw_vec3("Half Extent", p_collider->half_extent); - }); - - atlas::ui::draw_component( - "Box Collider", - m_selected_entity, - [](atlas::sphere_collider* p_collider) { - atlas::ui::draw_float("Radius", p_collider->radius); - }); - - atlas::ui::draw_component( - "Box Collider", - m_selected_entity, - [](atlas::capsule_collider* p_collider) { - atlas::ui::draw_float("Half Height", p_collider->half_height); - atlas::ui::draw_float("Radius", p_collider->radius); - }); - - atlas::ui::draw_component( - "Serialize", - m_selected_entity, - [](atlas::tag::serialize* p_serialize) { - ImGui::Checkbox("Enable", &p_serialize->enable); - }); - } - - ImGui::End(); - - // Note --- just added this temporarily for testing - // auto time = atlas::application::delta_time(); - - // if((int)(time * 10.0f) % 8 > 4) { - // m_blink = !m_blink; - // } - - // auto width = atlas::application::get_window().width(); - // auto height = atlas::application::get_window().height(); - - // ImGui::SetNextWindowPos(ImVec2(static_cast(width) * 0.5f, - // static_cast(height) * 0.5f), ImGuiCond_Always, ImVec2(0.5f, - // 0.5f)); ImGui::SetNextWindowSize(ImVec2(200, 20), ImGuiCond_Always); - // ImGuiWindowFlags flags = ImGuiWindowFlags_NoDecoration | - // ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoInputs; - // ImGui::SetNextWindowBgAlpha(0.f); - - // if(ImGui::Begin("Testing", nullptr, flags)) { - // ImGui::ProgressBar(10.f); - - // auto pos = ImGui::GetWindowPos(); - // pos.x += (float)width * 0.5f - 300.0f; - // pos.y += 50.0f; - // if(m_blink){ - // ImGui::GetForegroundDrawList()->AddText(m_font, 120.0f, - // pos, 0xffffffff, "Click to Play!"); - // } - - // ImGui::End(); - // } - } - - m_editor_dockspace.end(); -} - -void -level_scene::start() { - m_deserializer_test = atlas::serializer(); - - if (!m_deserializer_test.load("LevelScene", *this)) { - console_log_error("Could not load yaml file LevelScene!!!"); - } - - // testing the flip parameter inside atlas::mesh_source - m_viking_room->set({ - .flip = true, - .color = { 1.f, 1.f, 1.f, 1.f }, - .model_path = "assets/models/viking_room.obj", - .diffuse = "assets/models/viking_room.png", - // .model_path = "assets/models/Ball OBJ.obj", - // .diffuse = "assets/models/clear.png", - }); - - // TODO: Make this contain an atlas::directional_light - // If the scene opject dooes not have a atlas::directional_light, then we - // set the default values to 1.0f m_robot_model sets the cube.obj 3d model - // and loads it - m_robot_model->set({ - .shininess = 64.f, - }); - - // Initiating physics system - atlas::physics::jolt_settings settings = {}; - flecs::world registry = *this; - m_physics_engine_handler = - atlas::physics::physics_engine(settings, registry, *event_handle()); - - // Note -- just added for temporary - // ImGuiIO io = ImGui::GetIO(); - // m_font = io.Fonts->AddFontFromFileTTF("assets/OpenSans-Regular.ttf", - // 120.0f); -} - -void -level_scene::on_update() { - - auto query_cameras = - query_builder().build(); - - query_cameras.each([this](atlas::perspective_camera& p_camera, - atlas::transform& p_transform) { - if (!p_camera.is_active) { - return; - } - - float dt = atlas::application::delta_time(); - float default_speed = 10.f; // current default movement speed that does - // not applied modified speed - float rotation_speed = 1.f; - float velocity = default_speed * dt; - if (atlas::event::is_mouse_pressed(mouse_button_middle)) { - velocity = m_movement_speed * dt; - } - float rotation_velocity = rotation_speed * dt; - - glm::quat to_quaternion = atlas::to_quat(p_transform.quaternion); - - glm::vec3 up = glm::rotate(to_quaternion, atlas::math::up()); - glm::vec3 forward = glm::rotate(to_quaternion, atlas::math::backward()); - glm::vec3 right = glm::rotate(to_quaternion, atlas::math::right()); - - if (atlas::event::is_key_pressed(key_left_shift)) { - p_transform.position += up * velocity; - } - - if (atlas::event::is_key_pressed(key_space)) { - p_transform.position -= up * velocity; - } - - if (atlas::event::is_key_pressed(key_w)) { - p_transform.position += forward * velocity; - } - if (atlas::event::is_key_pressed(key_s)) { - p_transform.position -= forward * velocity; - } - - if (atlas::event::is_key_pressed(key_d)) { - p_transform.position += right * velocity; - } - if (atlas::event::is_key_pressed(key_a)) { - p_transform.position -= right * velocity; - } - - if (atlas::event::is_key_pressed(key_q)) { - p_transform.rotation.y += rotation_velocity; - } - if (atlas::event::is_key_pressed(key_e)) { - p_transform.rotation.y -= rotation_velocity; - } - - p_transform.set_rotation(p_transform.rotation); - }); -} - -void -level_scene::physics_update() { - float dt = atlas::application::delta_time(); - if (atlas::event::is_key_pressed(key_r) and !m_physics_is_runtime) { - runtime_start(); - } - - atlas::physics_body* sphere_body = - m_viking_room->get_mut(); - // U = +up - // J = -up - // H = +left - // L = -Left - if (atlas::event::is_key_pressed(key_space)) { - glm::vec3 linear_velocity = { 0.f, 10.0f, 0.f }; - sphere_body->linear_velocity = linear_velocity; - sphere_body->impulse = linear_velocity; - } - - if (atlas::event::is_key_pressed(key_j)) { - glm::vec3 angular_vel = { -10.f, 0.f, 0.f }; - sphere_body->angular_velocity = angular_vel; - } - - if (atlas::event::is_key_pressed(key_h)) { - glm::vec3 angular_vel = { 10.f, 0.f, 0.f }; - sphere_body->angular_velocity = angular_vel; - } - - if (atlas::event::is_key_pressed(key_l)) { - glm::vec3 angular_vel = { -0.1f, 0.f, 0.f }; - sphere_body->angular_velocity = angular_vel; - } - - if (m_physics_is_runtime) { - m_physics_engine_handler.update(dt); - } - - if (atlas::event::is_key_pressed(key_l) and m_physics_is_runtime) { - runtime_stop(); - } -} diff --git a/editor/level_scene-new.hpp b/editor/level_scene-new.hpp deleted file mode 100644 index 344e1a0e..00000000 --- a/editor/level_scene-new.hpp +++ /dev/null @@ -1,77 +0,0 @@ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/** - * @brief Implementation of a custom scene - * - * Represent a scene with an associated game objects that correspond to this - * game object. - * - */ - -class level_scene final : public atlas::scene_scope { -public: - level_scene(const std::string& p_tag, atlas::event::event_bus& p_bus); - - ~level_scene() override = default; - - void start(); - - void on_update(); - - void on_ui_update(); - - void physics_update(); - - void runtime_start(); - - void runtime_stop(); - - void reset_objects(); - - void collision_enter(atlas::event::collision_enter& p_event); - - void collision_persisted(atlas::event::collision_persisted& p_event); - -private: - bool m_blink = false; - atlas::serializer m_deserializer_test; - flecs::entity m_selected_entity; - // TEMP: this is only for when creating an entity in the editor-space - atlas::optional_ref m_create_entity; - atlas::optional_ref m_child_object; - atlas::optional_ref m_viking_room; - atlas::optional_ref m_cube; - atlas::optional_ref m_robot_model; - atlas::optional_ref m_platform; - std::pmr::polymorphic_allocator<> m_allocator; - atlas::optional_ref m_camera; - atlas::optional_ref m_point_light; - atlas::scene_object_view m_object; - flecs::atlas_entity m_object2; - float m_movement_speed = 10.f; - // std::vector> m_many_objects; - - // Setting physics system - // TODO -- when refactoring this would be at atlas::world layer - atlas::physics::physics_engine m_physics_engine_handler; - - bool m_physics_is_runtime = false; - - atlas::ui::dockspace m_editor_dockspace; - atlas::ui::menu_item m_editor_menu; - - // Note -- Added this temporarily - // ImFont* m_font; - - std::filesystem::path m_current_selected_file; -}; diff --git a/editor/level_scene.cpp b/editor/level_scene.cpp index 18947d46..dacac959 100644 --- a/editor/level_scene.cpp +++ b/editor/level_scene.cpp @@ -3,48 +3,54 @@ #include #include #include +#include level_scene::level_scene(const std::string& p_name, atlas::event::event_bus& p_bus) - : atlas::scene_scope(p_name, p_bus) { - m_camera = create_object("Editor Camera"); - m_camera->add>(); - m_camera->set({ + : atlas::scene(p_name, p_bus) { + auto editor_camera = entity("Editor Camera"); + editor_camera + .add>(); + editor_camera.set({ .position = { 3.50f, 4.90f, 36.40f }, .scale{ 1.f }, }); - m_camera->set({ + editor_camera.set({ .plane = { 0.1f, 5000.f }, .is_active = true, .field_of_view = 45.f, }); - m_viking_room = create_object("Viking Room"); - m_viking_room->add(); - m_viking_room->set({ + atlas::game_object bob_object = entity("Bob"); + + bob_object.add(); + + atlas::game_object viking_room = entity("Viking Room"); + viking_room.add(); + viking_room.set({ .position = { -2.70f, 2.70, -8.30f }, .rotation = { 2.30f, 95.90f, 91.80f }, .scale{ 1.f }, }); - m_viking_room->set({ + viking_room.set({ .radius = 1.0f, }); - m_viking_room->set({ + viking_room.set({ .friction = 15.f, .restitution = 0.3f, .body_movement_type = atlas::dynamic, }); - m_cube = create_object("Aircraft"); + atlas::game_object cube = entity("Aircraft"); - m_cube->set({ + cube.set({ .position = { 0.f, 2.10f, -7.30f }, .scale = { 0.9f, 0.9f, 0.9f }, }); - m_cube->set({ + cube.set({ .color = { 1.f, 1.f, 1.f, 1.f }, // .model_path = "assets/models/E 45 Aircraft_obj.obj", .model_path = "assets/backpack/backpack.obj", @@ -53,69 +59,78 @@ level_scene::level_scene(const std::string& p_name, // .diffuse = "assets/models/E-45-steel detail_2_col.jpg", }); - // atlas::material_metadata data = { - // .ambient = {0.2f, 0.2f, 0.2f}, - // .diffuse = {0.5f, 0.5f, 0.5f}, - // .specular = {1.0f, 1.0f, 1.0f}, - // .shininess = 64.f, - // }; - // m_cube->set(data); - - m_robot_model = create_object("Cube"); - m_robot_model->add(); - // m_robot_model->add(); - m_robot_model->set({ + atlas::game_object robot_model = entity("Cube"); + robot_model.add(); + // robot_model.add(); + robot_model.set({ .position = { -2.70, 3.50f, 4.10f }, .scale = { 1.f, 1.f, 1.f }, }); - m_robot_model->set( + robot_model.set( { .color = { 1.f, 1.f, 1.f, 1.f }, .model_path = "assets/models/cube.obj", .diffuse = "assets/models/container_diffuse.png", .specular = "assets/models/container_specular.png" }); - m_robot_model->set({ + robot_model.set({ .half_extent = { 1.f, 1.f, 1.f }, }); - m_robot_model->set({ + robot_model.set({ // .restitution = 1.f, .body_movement_type = atlas::dynamic, }); - m_child_object = create_object("Child"); - m_child_object->child_of(m_robot_model); - - m_platform = create_object("Platform"); + atlas::game_object platform = entity("Platform"); - m_platform->set({ + platform.set({ .scale = { 15.f, 0.30f, 10.0f }, }); - m_platform->set({ + platform.set({ .model_path = "assets/models/cube.obj", .diffuse = "assets/models/wood.png", }); - m_platform->set({ + platform.set({ .body_movement_type = atlas::fixed, }); - m_platform->set({ + platform.set({ .half_extent = { 15.f, 0.30f, 10.0f }, }); - m_point_light = create_object("Point Light 1"); - m_point_light->set({ + atlas::game_object point_light = entity("Point Light 1"); + point_light.set({ .position = { 0.f, 2.10f, -7.30f }, .scale = { 0.9f, 0.9f, 0.9f }, }); - m_point_light->set({ + point_light.set({ .model_path = "assets/models/cube.obj", .diffuse = "assets/models/wood.png", }); - m_point_light->add(); + point_light.add(); + + // benchmark + + // auto start = std::chrono::high_resolution_clock::now(); + // TEMP Code + // [[maybe_unused]] atlas::game_object point_light_test = entity("Point + // Light 1"); auto end = std::chrono::high_resolution_clock::now(); auto + // duration = (end - start); + + // auto seconds = + // std::chrono::duration_cast(duration).count(); auto + // nanoseconds = + // std::chrono::duration_cast(duration).count(); + // auto microseconds = + // std::chrono::duration_cast(duration).count(); + + // console_log_fatal("Seconds = {:.1f}", static_cast(seconds)); + // console_log_fatal("Nanoseconds = {:.1f}", + // static_cast(nanoseconds)); console_log_fatal("Microseconds = + // {:.1f}", static_cast(microseconds)); // for(size_t i = 0; i < 26; i++) { - // auto obj = create_object(std::format("Object #{}", i)); + // auto obj = entity(std::format("Object #{}", i)); // obj->set({ // .restitution = 1.25f, // .body_movement_type = atlas::dynamic, @@ -137,13 +152,12 @@ level_scene::level_scene(const std::string& p_name, // .model_path = "assets/models/Ball OBJ.obj", // .diffuse = "assets/models/clear.png", // }); - // m_many_objects.emplace_back(obj); // } - // Just adding this here, for testing purposes - // Basic serialization for testing to conform how the editor may work - // TODO -- have a stream writer/reader that can take a given scene structure - // for serialization + atlas::game_object gerald = entity("Gerald"); + gerald.add(); + + // TODO: Move this outside of level_scene m_deserializer_test = atlas::serializer(); subscribe(this, @@ -158,9 +172,8 @@ level_scene::level_scene(const std::string& p_name, void level_scene::collision_enter(atlas::event::collision_enter& p_event) { console_log_warn("collision_enter event!!!"); - flecs::world registry = *this; - flecs::entity e1 = registry.entity(p_event.entity1); - flecs::entity e2 = registry.entity(p_event.entity2); + atlas::game_object e1 = entity(p_event.entity1); + atlas::game_object e2 = entity(p_event.entity2); console_log_warn("Entity1 = {}", e1.name().c_str()); console_log_warn("Entity2 = {}", e2.name().c_str()); @@ -169,9 +182,8 @@ level_scene::collision_enter(atlas::event::collision_enter& p_event) { void level_scene::collision_persisted(atlas::event::collision_persisted& p_event) { console_log_warn("collision_persisted(p_event) invoked!!"); - flecs::world registry = *this; - flecs::entity e1 = registry.entity(p_event.entity1); - flecs::entity e2 = registry.entity(p_event.entity2); + atlas::game_object e1 = entity(p_event.entity1); + atlas::game_object e2 = entity(p_event.entity2); console_log_warn("Entity1 = {}", e1.name().c_str()); console_log_warn("Entity2 = {}", e2.name().c_str()); @@ -180,16 +192,16 @@ level_scene::collision_persisted(atlas::event::collision_persisted& p_event) { void level_scene::runtime_start() { // runs the physics simulation - m_physics_is_runtime = true; + m_physics_runtime = true; - m_physics_engine_handler.start(); + m_physics_engine.start(); } void level_scene::runtime_stop() { - m_physics_is_runtime = false; + m_physics_runtime = false; - m_physics_engine_handler.stop(); + m_physics_engine.stop(); reset_objects(); } @@ -205,7 +217,10 @@ level_scene::reset_objects() { void ui_component_list(flecs::entity& p_selected_entity) { std::string entity_name = p_selected_entity.name().c_str(); - atlas::ui::draw_input_text(entity_name); + std::string new_entity_name = ""; + atlas::ui::draw_input_text(new_entity_name, entity_name); + + p_selected_entity.set_name(new_entity_name.c_str()); ImGui::SameLine(); ImGui::PushItemWidth(-1); @@ -289,11 +304,20 @@ level_scene::on_ui_update() { catch (const atlas::ui::menu_bar_exception& e) { } - // specify the label and the state to execute when this specific widget has - // been triggered - m_editor_menu.add_child("Exit", []() { - glfwSetWindowShouldClose(atlas::application::get_window(), true); - }); + if (ImGui::BeginMenu("File")) { + if (ImGui::MenuItem("Save")) { + // m_deserializer_test.save("LevelScene"); + } + + ImGui::Separator(); + + if (ImGui::MenuItem("Exit")) { + glfwSetWindowShouldClose(atlas::application::get_window(), true); + } + + ImGui::EndMenu(); + } + m_editor_menu.end(); if (ImGui::Begin("Viewport")) { @@ -313,9 +337,7 @@ level_scene::on_ui_update() { // @param popup_flags - will be the mouse flag (0=right, 1=left) if (atlas::ui::begin_popup_context_window(nullptr, 1, false)) { if (ImGui::MenuItem("Create Empty Entity")) { - // TODO -- Converting the operation to use strong_ptr to make - // these operation more conformed - m_create_entity = create_object("Empty Entity"); + m_current_entity = entity("Empty Entity"); } ImGui::EndPopup(); } @@ -330,10 +352,12 @@ level_scene::on_ui_update() { ImGuiTreeNodeFlags_OpenOnArrow; flags |= ImGuiTreeNodeFlags_SpanAvailWidth; flags |= ImGuiWindowFlags_Popup; + flags |= ImGuiTreeNodeFlags_AllowItemOverlap; + bool opened = ImGui::TreeNodeEx(p_entity.name().c_str(), flags); + if (ImGui::IsItemClicked()) { m_selected_entity = p_entity; - // m_create_entity = search_entity(p_entity.name().c_str()); } bool delete_entity = false; @@ -345,10 +369,12 @@ level_scene::on_ui_update() { } if (delete_entity) { - // _context->destroyEntity(entity); m_selected_entity.destruct(); } + ImGui::SameLine(); + ImGui::TextDisabled("(%llu)", p_entity.id()); + if (opened) { flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_SpanAvailWidth; @@ -402,6 +428,29 @@ level_scene::on_ui_update() { ImGui::DragFloat("Speed", &m_movement_speed); }); + atlas::ui::draw_component( + "atlas::mesh_source", + m_selected_entity, + [](atlas::mesh_source* p_source) { + std::string mesh_src = p_source->model_path; + atlas::ui::draw_input_text(p_source->model_path, mesh_src); + atlas::ui::draw_vec4("Color", p_source->color); + }); + + atlas::ui::draw_component( + "material", + m_selected_entity, + [](atlas::material_metadata* p_source) { + float speed = 0.01f; + ImGui::DragFloat4( + "Ambient", glm::value_ptr(p_source->ambient), speed); + ImGui::DragFloat4( + "Diffuse", glm::value_ptr(p_source->diffuse), speed); + ImGui::DragFloat4( + "Specular", glm::value_ptr(p_source->specular), speed); + atlas::ui::draw_float("Shininess", p_source->shininess); + }); + /* atlas::ui::draw_component("Directional Light", m_selected_entity, [](atlas::directional_light* @@ -435,28 +484,6 @@ level_scene::on_ui_update() { ImGui::DragFloat("Quadratic", &p_dir_light->quadratic, 0.01); }); - atlas::ui::draw_component( - "atlas::mesh_source", - m_selected_entity, - [](atlas::mesh_source* p_source) { - atlas::ui::draw_input_text(p_source->model_path); - atlas::ui::draw_vec4("Color", p_source->color); - }); - - atlas::ui::draw_component( - "material", - m_selected_entity, - [](atlas::material_metadata* p_source) { - float speed = 0.01f; - ImGui::DragFloat4( - "Ambient", glm::value_ptr(p_source->ambient), speed); - ImGui::DragFloat4( - "Diffuse", glm::value_ptr(p_source->diffuse), speed); - ImGui::DragFloat4( - "Specular", glm::value_ptr(p_source->specular), speed); - atlas::ui::draw_float("Shininess", p_source->shininess); - }); - atlas::ui::draw_component( "Physics Body", m_selected_entity, @@ -577,28 +604,14 @@ level_scene::start() { console_log_error("Could not load yaml file LevelScene!!!"); } - // testing the flip parameter inside atlas::mesh_source - m_viking_room->set({ - .flip = true, - .color = { 1.f, 1.f, 1.f, 1.f }, - .model_path = "assets/models/viking_room.obj", - .diffuse = "assets/models/viking_room.png", - // .model_path = "assets/models/Ball OBJ.obj", - // .diffuse = "assets/models/clear.png", - }); - - // TODO: Make this contain an atlas::directional_light - // If the scene opject dooes not have a atlas::directional_light, then we - // set the default values to 1.0f m_robot_model sets the cube.obj 3d model - // and loads it - m_robot_model->set({ - .shininess = 64.f, - }); + atlas::game_object viking_room = entity("Viking Room"); + atlas::mesh_source* src = viking_room.get_mut(); + src->flip = true; // Initiating physics system atlas::physics::jolt_settings settings = {}; flecs::world registry = *this; - m_physics_engine_handler = + m_physics_engine = atlas::physics::physics_engine(settings, registry, *event_handle()); // Note -- just added for temporary @@ -671,12 +684,14 @@ level_scene::on_update() { void level_scene::physics_update() { float dt = atlas::application::delta_time(); - if (atlas::event::is_key_pressed(key_r) and !m_physics_is_runtime) { + if (atlas::event::is_key_pressed(key_r) and !m_physics_runtime) { runtime_start(); } + auto viking_room = entity("Viking Room"); + atlas::physics_body* sphere_body = - m_viking_room->get_mut(); + viking_room.get_mut(); // U = +up // J = -up // H = +left @@ -702,11 +717,11 @@ level_scene::physics_update() { sphere_body->angular_velocity = angular_vel; } - if (m_physics_is_runtime) { - m_physics_engine_handler.update(dt); + if (m_physics_runtime) { + m_physics_engine.update(dt); } - if (atlas::event::is_key_pressed(key_l) and m_physics_is_runtime) { + if (atlas::event::is_key_pressed(key_l) and m_physics_runtime) { runtime_stop(); } } diff --git a/editor/level_scene.hpp b/editor/level_scene.hpp index 17f26faa..5891afec 100644 --- a/editor/level_scene.hpp +++ b/editor/level_scene.hpp @@ -1,7 +1,6 @@ #pragma once #include #include -#include #include #include #include @@ -18,7 +17,7 @@ * */ -class level_scene final : public atlas::scene_scope { +class level_scene final : public atlas::scene { public: level_scene(const std::string& p_tag, atlas::event::event_bus& p_bus); @@ -38,32 +37,23 @@ class level_scene final : public atlas::scene_scope { void reset_objects(); +private: void collision_enter(atlas::event::collision_enter& p_event); void collision_persisted(atlas::event::collision_persisted& p_event); private: - bool m_blink = false; atlas::serializer m_deserializer_test; flecs::entity m_selected_entity; - // TEMP: this is only for when creating an entity in the editor-space - atlas::optional_ref m_create_entity; - atlas::optional_ref m_child_object; - atlas::optional_ref m_viking_room; - atlas::optional_ref m_cube; - atlas::optional_ref m_robot_model; - atlas::optional_ref m_platform; - std::pmr::polymorphic_allocator<> m_allocator; - atlas::optional_ref m_camera; - atlas::optional_ref m_point_light; + + atlas::game_object_optional m_current_entity; float m_movement_speed = 10.f; - // std::vector> m_many_objects; // Setting physics system - // TODO -- when refactoring this would be at atlas::world layer - atlas::physics::physics_engine m_physics_engine_handler; + // TODO -- when refactoring this would be at atlas::world level + atlas::physics::physics_engine m_physics_engine; - bool m_physics_is_runtime = false; + bool m_physics_runtime = false; atlas::ui::dockspace m_editor_dockspace; atlas::ui::menu_item m_editor_menu; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d4cb81c9..96322730 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -19,7 +19,8 @@ set( ${SRC_DIR}/core/platforms/win32.cpp # System-related stuff - ${SRC_DIR}/core/scene/scene_object.cpp + ${SRC_DIR}/core/scene/scene.cpp + ${SRC_DIR}/core/scene/game_object.cpp ${SRC_DIR}/core/system/registry.cpp # math sources diff --git a/src/atlas/core/application.cpp b/src/atlas/core/application.cpp index 4116f29a..a5161eac 100644 --- a/src/atlas/core/application.cpp +++ b/src/atlas/core/application.cpp @@ -81,9 +81,8 @@ namespace atlas { m_renderer->preload( m_window->current_swapchain().swapchain_renderpass()); - ref current_world = - system_registry::get_world("Editor World"); - ref current_scene = current_world->get_scene("LevelScene"); + ref current_world = system_registry::get_world("Editor World"); + ref current_scene = current_world->get_scene("LevelScene"); flecs::world current_world_scope = *current_scene; diff --git a/src/atlas/core/scene/game_object.cpp b/src/atlas/core/scene/game_object.cpp new file mode 100644 index 00000000..397f2072 --- /dev/null +++ b/src/atlas/core/scene/game_object.cpp @@ -0,0 +1,25 @@ +#include +#include +#include +#include + +namespace atlas { + game_object::game_object(flecs::world_t* p_registry, flecs::entity_t p_id) + : flecs::entity(p_registry, p_id) { + add(); + } + + game_object::game_object(const flecs::entity& p_base) + : flecs::entity(p_base) { + add(); + } + + game_object::game_object(flecs::entity& p_base) + : flecs::entity(p_base) { + add(); + } + + void game_object::child_of(const std::optional& p_parent) { + add(flecs::ChildOf, p_parent.value()); + } +}; \ No newline at end of file diff --git a/src/atlas/core/scene/scene.cpp b/src/atlas/core/scene/scene.cpp index db4886bb..6cb57848 100644 --- a/src/atlas/core/scene/scene.cpp +++ b/src/atlas/core/scene/scene.cpp @@ -1,3 +1,20 @@ #include -namespace atlas {}; \ No newline at end of file +namespace atlas { + scene::scene(const std::string& p_name, event::event_bus& p_bus) + : m_name(p_name) + , m_bus(&p_bus) {} + + game_object scene::entity(std::string_view p_name) { + return game_object(m_registry.entity(p_name.data())); + } + + game_object scene::entity(uint64_t p_id) { + return game_object(m_registry.entity(p_id)); + } + + uint32_t scene::children_count(const game_object& p_parent) { + return query_builder().with(flecs::ChildOf, p_parent).build().count(); + } + +}; \ No newline at end of file diff --git a/src/atlas/core/scene/scene_object.cpp b/src/atlas/core/scene/scene_object.cpp deleted file mode 100644 index e974d0e6..00000000 --- a/src/atlas/core/scene/scene_object.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include - -namespace atlas { - scene_object::scene_object(flecs::world* p_registry, - const std::string& p_name) { - m_entity = p_registry->entity(p_name.c_str()); - add(); - } - - scene_object::scene_object(flecs::world* p_registry, - const std::string& p_name, - [[maybe_unused]] bool p_lookup) { - m_entity = p_registry->lookup(p_name.c_str()); - } - - scene_object::scene_object(strong_ref& p_registry, - const std::string& p_name) { - m_entity = p_registry->entity(p_name.c_str()); - add(); - } - - scene_object::~scene_object() { - if (m_entity.is_alive()) { - m_entity.destruct(); - } - } -}; \ No newline at end of file diff --git a/src/atlas/core/scene/world.cpp b/src/atlas/core/scene/world.cpp index 340a661c..62d43aff 100644 --- a/src/atlas/core/scene/world.cpp +++ b/src/atlas/core/scene/world.cpp @@ -4,19 +4,15 @@ namespace atlas { - world_scope::world_scope(const std::string& p_name) + world::world(const std::string& p_name) : m_name(p_name) {} - world_scope::~world_scope() { - console_log_trace("~world_scope called!!!"); - } - /** * @brief Currently how to pass in the scene context to the world * TODO: Have a way of allowing creation and management of those - * created-scenes be done through world_scope + * created-scenes be done through world */ - void world_scope::add_scene(const ref& p_scene_context) { + void world::add_scene(const ref& p_scene_context) { m_scene_container.emplace(p_scene_context->name(), p_scene_context); } }; \ No newline at end of file diff --git a/src/atlas/core/serialize/serializer.cpp b/src/atlas/core/serialize/serializer.cpp index 2830bd9e..83f4d3a5 100644 --- a/src/atlas/core/serialize/serializer.cpp +++ b/src/atlas/core/serialize/serializer.cpp @@ -147,7 +147,7 @@ namespace atlas { } } - serializer::serializer(const ref& p_scene_ctx) + serializer::serializer(const ref& p_scene_ctx) : m_current_scene_ctx(p_scene_ctx) {} void serializer::save(const std::filesystem::path& p_filepath) { @@ -161,7 +161,7 @@ namespace atlas { //! entities that the engine (user creates through our API) // ref world_object = // system_registry::get_world("Editor World"); - // ref current_scene = + // ref current_scene = // world_object->get_scene("LevelScene"); // flecs::query<> q = diff --git a/src/atlas/core/system/registry.cpp b/src/atlas/core/system/registry.cpp index 84215993..c0ccf02a 100644 --- a/src/atlas/core/system/registry.cpp +++ b/src/atlas/core/system/registry.cpp @@ -12,24 +12,20 @@ namespace atlas { system_registry::~system_registry() = default; - ref system_registry::create_world(const std::string& p_tag) { - return s_instance->append_world_scope(create_ref(p_tag)); + ref system_registry::create_world(const std::string& p_tag) { + return s_instance->append_world_and_get(create_ref(p_tag)); } - ref system_registry::get_world(const std::string& p_tag) { + ref system_registry::get_world(const std::string& p_tag) { return s_instance->search_world(p_tag); } - ref system_registry::search_world(const std::string& p_tag) { + ref system_registry::search_world(const std::string& p_tag) { return m_world_registered[p_tag]; } - void system_registry::append_world(const ref& p_world) { - m_world_registered.emplace(p_world->name(), p_world); - } - - ref system_registry::append_world_scope( - const ref& p_world) { + ref system_registry::append_world_and_get( + const ref& p_world) { m_world_registered.emplace(p_world->name(), p_world); return m_world_registered[p_world->name()]; } diff --git a/src/atlas/core/ui/widgets.cpp b/src/atlas/core/ui/widgets.cpp index 5239ed14..9a134699 100644 --- a/src/atlas/core/ui/widgets.cpp +++ b/src/atlas/core/ui/widgets.cpp @@ -2,6 +2,8 @@ #include // Used to include "PushMultiItemsWidths" namespace atlas::ui { + using ::ImGui::InputText; + bool begin_popup_context_window(const char* str_id, ImGuiMouseButton mb, bool over_items) { @@ -220,10 +222,28 @@ namespace atlas::ui { ImGui::PopID(); } - void draw_input_text(std::string& p_value) { - // std::string value = ""; - // // ImGui::Text("%s", p_value.c_str()); - if (ImGui::InputText("##Tag", p_value.data(), p_value.size() + 1)) { + void draw_input_text(std::string& p_dst, std::string& p_src) { + std::string input_buffer = p_src; + + ImGuiInputTextFlags flags = ImGuiInputTextFlags_EnterReturnsTrue; + input_buffer.resize(255); // resize to allocate for 255 in the char + // array since this should be long enough + + if (ImGui::InputText("##Name", + (char*)input_buffer.c_str(), + input_buffer.size() + 1, + flags)) { + p_dst = input_buffer; + } + + if (p_dst.empty()) { + p_dst = p_src; + return; + } + + if (p_dst == p_src) { + p_dst = p_src; + return; } } diff --git a/src/atlas/drivers/vulkan-cpp/vk_renderer.cpp b/src/atlas/drivers/vulkan-cpp/vk_renderer.cpp index 260d3f9d..09a3b1b1 100644 --- a/src/atlas/drivers/vulkan-cpp/vk_renderer.cpp +++ b/src/atlas/drivers/vulkan-cpp/vk_renderer.cpp @@ -1,12 +1,8 @@ -#include -#include -#include - +#include #include +#include #include #include -#include - #include namespace atlas::vk { @@ -213,9 +209,8 @@ namespace atlas::vk { void vk_renderer::preload_assets(const VkRenderPass& p_renderpass) { m_final_renderpass = p_renderpass; // set 1 -- material uniforms - ref current_world = - system_registry::get_world("Editor World"); - ref current_scene = current_world->get_scene("LevelScene"); + ref current_world = system_registry::get_world("Editor World"); + ref current_scene = current_world->get_scene("LevelScene"); flecs::query<> caching = current_scene->query_builder().build(); @@ -483,9 +478,8 @@ namespace atlas::vk { // m_global_uniforms.update(bytes_data.data()); m_global_uniforms.update(&global_frame_ubo); - ref current_world = - system_registry::get_world("Editor World"); - ref current_scene = current_world->get_scene("LevelScene"); + ref current_world = system_registry::get_world("Editor World"); + ref current_scene = current_world->get_scene("LevelScene"); // query all entities that have a point light flecs::query query_point_lights = diff --git a/tests/entity_component_system.test.cpp b/tests/entity_component_system.test.cpp index f1e825b4..4e5b6ec5 100644 --- a/tests/entity_component_system.test.cpp +++ b/tests/entity_component_system.test.cpp @@ -4,7 +4,7 @@ #include #include -#include +#include namespace atlas { @@ -82,12 +82,12 @@ namespace atlas { //! @note Each scene will define flecs::world typically //! @note flecs::world is how flecs (ECS) stores entities and components - flecs::world scene_registry; + atlas::event::event_bus test_event_bus; + atlas::scene test_scene = atlas::scene("Mock Scene", test_event_bus); - "create_entity::add"_test = [&scene_registry] { + "create_entity::add"_test = [&test_scene] { // flecs::entity entity = scene_registry.entity("Mock Entity"); - atlas::scene_object entity = - atlas::scene_object(&scene_registry, "Mock Entity"); + atlas::game_object entity = test_scene.entity("Mock Entity"); // expect(entity.is_alive()); @@ -95,14 +95,12 @@ namespace atlas { expect(entity.has()); }; - "create_entity::get"_test = [&scene_registry]() { - atlas::scene_object entity = - atlas::scene_object(&scene_registry, "Mock Entity2"); + "create_entity::get"_test = [&test_scene]() { + atlas::game_object entity = test_scene.entity("Mock Entity 2"); entity.add(); - //! @note Flecs require you to get the component for the use of only - //! reading the data from component - //! @note To actually set values to that component you use the set - //! usnig their API they specify + // flecs requires reading only operations are through the get API + // to write or set new parameters you can use get_mut or + // set(T&&); in this case, I use set in this test case entity.set({ .tag = "New Entity" }); const test_tag_component* get_tag = @@ -110,11 +108,13 @@ namespace atlas { expect(get_tag->tag == "New Entity"); }; - "create_entity::set"_test = [&scene_registry]() { - atlas::scene_object entity = - atlas::scene_object(&scene_registry, "New Entity"); + "create_entity::set"_test = [&test_scene]() { + atlas::game_object entity = test_scene.entity("New Entity"); mock_projectile projectile; projectile.on_update(); + entity.set(projectile); + + expect(entity.has()); // test_transform transform; // transform.position = projectile.position(); @@ -125,7 +125,7 @@ namespace atlas { // expect(transform.position == projectile.position()); // expect(mock_velocity.position == - // entity.get()->position); + // entity.get().position); }; }; }; // namespace atlas diff --git a/tests/jolt_engine.test.cpp b/tests/jolt_engine.test.cpp index 1c042211..c20aa02d 100644 --- a/tests/jolt_engine.test.cpp +++ b/tests/jolt_engine.test.cpp @@ -1,19 +1,14 @@ -#include - -#include - -#include +#include #include #include -#include -#include -#include -#include #include +#include +#include #include #include -#include + +#include namespace atlas { @@ -25,58 +20,16 @@ namespace atlas { boost::ut::suite<"physics_engine_integration"> engine_test = [] { using namespace boost::ut; - class test_scene : public scene_scope { - public: - test_scene(const std::string& p_tag, event::event_bus& p_bus) - : scene_scope(p_tag, p_bus) {}; - - std::pmr::polymorphic_allocator<> m_object_allocator; - }; - - class editor_world : public world_scope { - public: - editor_world(const std::string& p_tag) - : world_scope(p_tag) {}; - }; - - "initialize_engine with physics_world and setup object"_test = [] { - system_registry m_log_registery = system_registry("Registry"); - - editor_world editor = editor_world("Editor World"); - - // ref physics_world = - // editor.create_custom_scene("LevelScene"); - // expect(eq(physics_world->get_tag(), std::string("LevelScene"))); - - /** - * @bug FIXME: This does not work because the operator in - * scene_scope: - * operator flecs::world() { return m_registry; } - * - * Returns a copy of the flecs world. This can be an invalid - * state. Instead have a get_world() function. - */ - // flecs::world test_world = *physics_world; - - // expect(test_world.get_info() != nullptr); - - // strong_ref physics_setup = - // physics_world->create_object("Physics Tooling"); - - // // Add required config components - // physics_setup->add(); - // physics_setup->add(); - - // // Now initialize the physics engine using that setup - // optional_ref engine = - // atlas::physics::initialize_engine(physics_world->m_object_allocator,physics_setup, - // test_world); + // Setup to do testing and assume we have a specified current scene that + // gets provided to you during that runtime + atlas::event::event_bus bus; + atlas::scene test_environment_scene = atlas::scene("Mock 1", bus); - // expect(engine != nullptr); + // Do some testing if these two collides or something like that + // atlas::game_object obj1 = test_environment_scene.entity("Entity + // 1"); atlas::game_object obj2 = + // test_environment_scene.entity("Entity 2"); - // engine->start_runtime(); - // engine->physics_step(); - // engine->stop_runtime(); - }; + "on_collision_enter"_test = [] {}; }; }; \ No newline at end of file diff --git a/tests/jolt_type_conversion.test.cpp b/tests/jolt_type_conversion.test.cpp index 350db5b9..76f52f79 100644 --- a/tests/jolt_type_conversion.test.cpp +++ b/tests/jolt_type_conversion.test.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include diff --git a/tests/scene.test.cpp b/tests/scene.test.cpp index de1c0013..32e567ec 100644 --- a/tests/scene.test.cpp +++ b/tests/scene.test.cpp @@ -1,21 +1,17 @@ #include #include #include +#include boost::ut::suite<"::scene"> scene_test = []() { using namespace boost::ut; atlas::event::event_bus test_event_bus; - atlas::scene_scope test_scope = - atlas::scene_scope("Mock Scene 1", test_event_bus); + atlas::scene test_scene = atlas::scene("Mock Scene 1", test_event_bus); - "create_object"_test = [&test_scope]() { - atlas::strong_ref test_object = - test_scope.create_object("Entity 1"); + "create_object"_test = [&test_scene]() { + atlas::game_object test_object = test_scene.entity("Entity 1"); + test_object.add(); - test_object->set({ .position{ 1.f } }); - glm::vec3 mock_pos{ 1.f }; - - const atlas::transform* t = test_object->get(); - expect(mock_pos == t->position); + expect(test_object.has()); }; };