1 /* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef API_3D_UTIL_SCENE_UTIL_H 17 #define API_3D_UTIL_SCENE_UTIL_H 18 19 #include <3d/ecs/components/material_component.h> 20 #include <3d/loaders/intf_scene_loader.h> 21 #include <3d/namespace.h> 22 #include <base/containers/string_view.h> 23 #include <base/math/quaternion.h> 24 #include <base/math/vector.h> 25 #include <core/ecs/entity.h> 26 #include <core/namespace.h> 27 #include <render/device/pipeline_state_desc.h> 28 #include <render/resource_handle.h> 29 30 CORE_BEGIN_NAMESPACE() 31 class IEcs; 32 CORE_END_NAMESPACE() 33 34 CORE3D_BEGIN_NAMESPACE() 35 class IAnimationPlayback; 36 struct LightComponent; 37 38 /** @ingroup group_util_isceneutil 39 * @{ 40 */ 41 /** Interface for helper class to create different ECS related objects. 42 */ 43 class ISceneUtil { 44 public: 45 /** Create camera. 46 * @param ecs Entity component system to contain the camera instance. 47 * @param position Position of the camera, defaults to origin. 48 * @param rotation Rotation of the camera, defaults to identity. 49 * @param zNear Near plane distance. 50 * @param zFar Far plane distance. 51 * @param fovDegrees FOV in degrees. 52 * @return Newly created camera entity. 53 */ 54 virtual CORE_NS::Entity CreateCamera(CORE_NS::IEcs& ecs, const BASE_NS::Math::Vec3& position, 55 const BASE_NS::Math::Quat& rotation, float zNear, float zFar, float fovDegrees) const = 0; 56 57 /** Update camera viewport and aspect ratio according to render resolution. 58 * @param ecs Entity component system to contain the camera instance. 59 * @param entity Camera entity. 60 * @param renderResolution Render resolution (width and height). 61 */ 62 virtual void UpdateCameraViewport( 63 CORE_NS::IEcs& ecs, CORE_NS::Entity entity, const BASE_NS::Math::UVec2& renderResolution) const = 0; 64 65 /** Update camera viewport according to render resolution, optionally also determines aspect ratio and proper FOV 66 * according to screen shape. 67 * Calculated values might change due to projection type. 68 * @param ecs Entity component system to contain the camera instance. 69 * @param entity Camera entity. 70 * @param renderResolution Render resolution (width and height). 71 * @param autoAspect If true, also calculates the aspect ratio. 72 * @param fovY Suggested y-fov in radians, in case the screen shape is portrait the x-fov is calculated and used. 73 * @param orthoScale Scale for ortho camera. 74 */ 75 virtual void UpdateCameraViewport(CORE_NS::IEcs& ecs, CORE_NS::Entity entity, 76 const BASE_NS::Math::UVec2& renderResolution, bool autoAspect, float fovY, float orthoScale) const = 0; 77 78 /** Update the transformation of the given entity such that it is located at 'eye', rotated towards 'target', and 79 * its up vector is 'up'. The up vector will only match 'up' if the direction from 'eye' to 'target' is 80 * perpendicular to 'up'. 81 * @param ecs Entity component system to contain the camera instance. 82 * @param entity Entity to modify. 83 * @param eye Final world space position of the entity. 84 * @param target World space position where the entity's z-axis will point to. 85 * @param up Desired up vector of the entity. 86 */ 87 virtual void CameraLookAt(CORE_NS::IEcs& ecs, CORE_NS::Entity entity, const BASE_NS::Math::Vec3& eye, 88 const BASE_NS::Math::Vec3& target, const BASE_NS::Math::Vec3& up) = 0; 89 90 /** Create a light. Creates a new ecs light based on inputs. 91 * For shadow lights a ecs camera is created and sane default values are calculated. 92 * @param ecs Entity component system to contain the light instance. 93 * @param lightComponent A filled up light component struct (will be attached to ECS internally. 94 * @param position Position of the light, defaults to origin. 95 * @param rotation Rotation of the light, defaults to identity. 96 * @return Newly created light entity. 97 */ 98 virtual CORE_NS::Entity CreateLight(CORE_NS::IEcs& ecs, const LightComponent& lightComponent, 99 const BASE_NS::Math::Vec3& position, const BASE_NS::Math::Quat& rotation) const = 0; 100 101 /** Create reflection plane component. Component is added to the given entity. For reflections to work the entity is 102 * expected to have a RenderMeshComponent. The method updates the material of the mesh for planar reflections. 103 * @param ecs Entity component system instance. 104 * @param nodeEntity Scene node entity where to attach. 105 */ 106 virtual void CreateReflectionPlaneComponent(CORE_NS::IEcs& ecs, const CORE_NS::Entity& nodeEntity) = 0; 107 108 /** Creates a new animation for targetEntity which animates the target's joints the same way as animationEntity 109 * animatest the joints of sourceEntity. 110 * @param ecs Entity component system instance. 111 * @param targetEntity Entity which will be the target of the new animation. 112 * @param sourceEntity Entity whos skin will be used for retargetting the animation to targetEntity. 113 * @param animationEntity Entity with a skinning animation. 114 * @return Newly created animation playback. 115 */ 116 virtual IAnimationPlayback* RetargetSkinAnimation(CORE_NS::IEcs& ecs, CORE_NS::Entity targetEntity, 117 CORE_NS::Entity sourceEntity, CORE_NS::Entity animationEntity) const = 0; 118 119 /** Material shader info for default material shader data fetching. 120 */ 121 struct MaterialShaderInfo { 122 /** Alpha blend mode */ 123 bool alphaBlend { false }; 124 /** Cull mode */ 125 RENDER_NS::CullModeFlags cullModeFlags { RENDER_NS::CullModeFlagBits::CORE_CULL_MODE_NONE }; 126 /** Front face */ 127 RENDER_NS::FrontFace frontFace { RENDER_NS::FrontFace::CORE_FRONT_FACE_COUNTER_CLOCKWISE }; 128 }; 129 130 /** Returns default material shader built-in data for material component usage 131 * @param ecs Entity component system instance. 132 * @param info Material shader info which is used to fetch default material handles and entities. 133 * @param materialShader Returns material shader with entity references. 134 * @param depthSahder Returns depth shader with entity references. 135 */ 136 virtual void GetDefaultMaterialShaderData(CORE_NS::IEcs& ecs, const MaterialShaderInfo& info, 137 MaterialComponent::Shader& materialShader, MaterialComponent::Shader& depthShader) const = 0; 138 139 /** Returns default material shader data based on render slot name. 140 * NOTE: Alpha blend does not affect this, i.e. we do not flip the flag in graphics state 141 * @param ecs Entity component system instance. 142 * @param info Material shader info which is used to fetch default material handles and entities. 143 * @param renderSlot Name of the render slot. 144 * @param shader Returns material shader with entity references. 145 */ 146 virtual void GetDefaultMaterialShaderData(CORE_NS::IEcs& ecs, const ISceneUtil::MaterialShaderInfo& info, 147 const BASE_NS::string_view renderSlot, MaterialComponent::Shader& shader) const = 0; 148 149 /** Share the sourceEntity's skin with the targetEntity. 150 * @param ecs Entity component system instance. 151 * @param targetEntity Entity whos skin will be modified to use the source joints. 152 * @param sourceEntity Entity whos joints will be applied to target. 153 */ 154 virtual void ShareSkin(CORE_NS::IEcs& ecs, CORE_NS::Entity targetEntity, CORE_NS::Entity sourceEntity) const = 0; 155 156 /** Register a new scene loader. Plugins implementing support for new scene file formats should register an instance 157 * so that it can be discovered with GetSceneLoader. 158 * @param loader Pointer to a new scene loader instance. 159 */ 160 virtual void RegisterSceneLoader(const ISceneLoader::Ptr& loader) = 0; 161 162 /** Unregister a previously registered scene loader. Loaders must be unregistered e.g. when the plugin offering the 163 * instance is unloaded. 164 * @param loader Pointer to a previously registered scene loader instance. 165 */ 166 virtual void UnregisterSceneLoader(const ISceneLoader::Ptr& loader) = 0; 167 168 /** Get a scene loader which can handle the given file. Selection is done based on file extensions. Actual loading 169 * might still fail with the returned loader. 170 * @param uri File URI. 171 * @return Pointer to a scene loader or null if none of the registered loaders are able to handle the file. 172 */ 173 virtual ISceneLoader::Ptr GetSceneLoader(BASE_NS::string_view uri) const = 0; 174 175 protected: 176 ISceneUtil() = default; 177 virtual ~ISceneUtil() = default; 178 }; 179 /** @} */ 180 CORE3D_END_NAMESPACE() 181 182 #endif // API_3D_UTIL_SCENE_UTIL_H 183