Program Listing for File ProxyScene.h

Program Listing for File ProxyScene.h#

Return to documentation for file (include/Karana/ProxyScene/ProxyScene.h)

/*
 * Copyright (c) 2024-2026 Karana Dynamics Pty Ltd. All rights reserved.
 *
 * NOTICE TO USER:
 *
 * This source code and/or documentation (the "Licensed Materials") is
 * the confidential and proprietary information of Karana Dynamics Inc.
 * Use of these Licensed Materials is governed by the terms and conditions
 * of a separate software license agreement between Karana Dynamics and the
 * Licensee ("License Agreement"). Unless expressly permitted under that
 * agreement, any reproduction, modification, distribution, or disclosure
 * of the Licensed Materials, in whole or in part, to any third party
 * without the prior written consent of Karana Dynamics is strictly prohibited.
 *
 * THE LICENSED MATERIALS ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
 * KARANA DYNAMICS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
 * BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, AND
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * IN NO EVENT SHALL KARANA DYNAMICS BE LIABLE FOR ANY DAMAGES WHATSOEVER,
 * INCLUDING BUT NOT LIMITED TO LOSS OF PROFITS, DATA, OR USE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, WHETHER IN CONTRACT, TORT,
 * OR OTHERWISE ARISING OUT OF OR IN CONNECTION WITH THE LICENSED MATERIALS.
 *
 * U.S. Government End Users: The Licensed Materials are a "commercial item"
 * as defined at 48 C.F.R. 2.101, and are provided to the U.S. Government
 * only as a commercial end item under the terms of this license.
 *
 * Any use of the Licensed Materials in individual or commercial software must
 * include, in the user documentation and internal source code comments,
 * this Notice, Disclaimer, and U.S. Government Use Provision.
 */

/**
 * @file
 * @brief Contains the declarations for the ProxyScene class.
 */

#pragma once
#include "Karana/KCore/CallbackRegistry.h"
#include "Karana/KCore/SharedPointer.h"
#include "Karana/ProxyScene/ClientRegistry.h"
#include "Karana/ProxyScene/ProxySceneNode.h"
#include "Karana/ProxyScene/ProxyScenePart.h"
#include "Karana/Scene/CollisionScene.h"
#include "Karana/Scene/GraphicalScene.h"
#include "Karana/Scene/Layer.h"
#include "Karana/Scene/Scene.h"

namespace Karana::Scene {
    namespace kf = Karana::Frame;
    namespace km = Karana::Math;

    /**
     * @brief A Scene implementation acting as a proxy to any number of
     * registered 'client' Scenes.
     *
     * See \sref{scene_layer_sec} for more discussion on
     * the scene layer.
     */
    class ProxyScene : public Scene {
        // For create/discard
        friend class ProxySceneNode;
        friend class ProxyScenePart;

      public:
        /**
         * @brief ProxyScene constructor
         * @param name - Name of the ProxyScene.
         * @param root_frame - Default Frame to attach nodes to.
         */
        ProxyScene(std::string_view name, const kc::ks_ptr<kf::Frame> &root_frame);
        ~ProxyScene();

        /**
         * @brief Create a ProxyScene
         * @param name - Name of the ProxyScene.
         * @param root_frame - Default Frame to attach nodes to.
         * @return The created ProxyScene
         */
        static kc::ks_ptr<ProxyScene> create(std::string_view name,
                                             const kc::ks_ptr<kf::Frame> &root_frame);

        /**
         * @brief Update all Frame-attached nodes' transforms for all clients
         */
        void update();

        /**
         * @brief Update all Frame-attached nodes' transforms for a client
         * @param scene - The client Scene to update
         */
        void update(Scene &scene);

        /**
         * @brief Register a client Scene to be managed
         * @param scene - The client Scene
         * @param origin_frame - The Frame to center the client's origin at
         * @param layers - Bitmask for objects to implement
         */
        void registerClientScene(const kc::ks_ptr<Scene> &scene,
                                 const kc::ks_ptr<kf::Frame> &origin_frame,
                                 layer_t layers = LAYER_ALL);

        /**
         * @brief Unregister a client Scene to no longer be managed
         * @param scene - The client Scene.
         */
        void unregisterClientScene(Scene &scene);

        /**
         * @brief Get a list of all registered client Scenes
         *
         * @return The list of client Scenes
         */
        std::vector<kc::ks_ptr<Karana::Scene::Scene>> clientScenes() const;

        /**
         * @brief Get a registered GraphicalScene
         *
         * If there is more than one only the first one found
         * is returned.
         *
         * @return A GraphicalScene or nullptr
         */
        kc::ks_ptr<Karana::Scene::GraphicalScene> graphics() const;

        /**
         * @brief Get a registered CollisionScene
         *
         * If there is more than one only the first one found
         * is returned.
         *
         * @return A CollisionScene or nullptr
         */
        kc::ks_ptr<Karana::Scene::CollisionScene> collision() const;

        /**
         * @brief Lookup the ProxySceneNode managing the given implementation
         * @param impl - The SceneNode in a client Scene
         * @return The corresponding ProxySceneNode
         */
        const kc::ks_ptr<ProxySceneNode> &lookupProxyFromImpl(const SceneNode &impl);

        /**
         * @brief Get the Frame the client's origin is centered at
         * @param client_scene - The client Scene
         * @return The origin Frame for the given client Scene
         */
        const kc::ks_ptr<kf::Frame> &originFrame(const Scene &client_scene);

        /**
         * @brief Get the root frame.
         *
         * This is the frame that nodes are attached to by default.
         *
         * @return The root Frame.
         */
        const kc::ks_ptr<kf::Frame> &rootFrame();

        /**
         * @brief Retrieve all ProxySceneNodes attached to the provided frame.
         * @param frame - The frame to retrieve nodes from.
         * @returns - A vector of ProxySceneNodes attached to the provided frame.
         */
        std::vector<kc::ks_ptr<ProxySceneNode>>
        getNodesAttachedToFrame(const kc::ks_ptr<kf::Frame> &frame);

        /**
         * @brief Registry for callbacks that run during the scene update.
         *
         * These callbacks will run after the nodes are updated.
         */
        kc::CallbackRegistry<void> update_callbacks;

        /**
         * @brief Show the axes for a Frame
         *
         * @param frm the Frame to show axes for
         * @param size the size of the axes
         */
        void showAxes(kc::ks_ptr<kf::Frame> frm, float size = 1);

        /**
         * @brief Position the default camera relative to a Frame
         *
         * @param frm the Frame to view around
         * @param offset camera position relative to the Frame
         * @param at_offset camera target relative to the Frame
         * @param up camera up vector
         */
        void viewAroundFrame(kc::ks_ptr<kf::Frame> frm,
                             const km::Vec3 &offset,
                             const km::Vec3 &at_offset = {0, 0, 0},
                             const km::Vec3 &up = {0, 0, 1});

      protected:
        /**
         * @brief This does the work to discard the ProxyScene.
         * @param b - A pointer to the ProxyScene to discard.
         */
        virtual void _discard(kc::ks_ptr<Base> &b) override;

      private:
        virtual kc::ks_ptr<SceneNode> _createNodeBase(std::string_view name) override;
        virtual void _discardNodeBase(kc::ks_ptr<SceneNode> &node, bool recursive) override;

        virtual kc::ks_ptr<ScenePart> _createPartBase(std::string_view name,
                                                      const VarStaticGeometry &goemetry,
                                                      const VarMaterial &material,
                                                      layer_t layers) override;
        virtual void _discardPartBase(kc::ks_ptr<ScenePart> &part) override;

        kc::ks_ptr<kf::Frame> _root_frame;
        kc::ks_ptr<ClientRegistry> _client_registry;
        kc::ks_ptr<ImplDatabase> _impl_database;

        std::unordered_map<kc::id_t, kc::ks_ptr<ProxySceneNode>> _nodes;

        //! map to look up the ProxySceneNode id corresponding to a frame id
        std::unordered_map<kc::id_t, kc::id_t> _frame2node_map;
    };
} // namespace Karana::Scene