| 1 | //************************************ bs::framework - Copyright 2018 Marko Pintera **************************************// | 
| 2 | //*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********// | 
| 3 | #pragma once | 
| 4 |  | 
| 5 | #include "BsCorePrerequisites.h" | 
| 6 | #include "Reflection/BsIReflectable.h" | 
| 7 | #include "CoreThread/BsCoreObject.h" | 
| 8 | #include "Resources/BsIResourceListener.h" | 
| 9 | #include "Math/BsBounds.h" | 
| 10 | #include "Math/BsAABox.h" | 
| 11 | #include "Scene/BsSceneActor.h" | 
| 12 |  | 
| 13 | namespace bs | 
| 14 | { | 
| 15 | 	struct EvaluatedAnimationData; | 
| 16 |  | 
| 17 | 	/** @addtogroup Implementation | 
| 18 | 	 *  @{ | 
| 19 | 	 */ | 
| 20 |  | 
| 21 | 	/** Type of animation that can be applied to a renderable object. */ | 
| 22 | 	enum class RenderableAnimType | 
| 23 | 	{ | 
| 24 | 		None, | 
| 25 | 		Skinned, | 
| 26 | 		Morph, | 
| 27 | 		SkinnedMorph, | 
| 28 | 		Count // Keep at end | 
| 29 | 	}; | 
| 30 |  | 
| 31 | 	/** | 
| 32 | 	 * Renderable represents any visible object in the scene. It has a mesh, bounds and a set of materials. Renderer will | 
| 33 | 	 * render any Renderable objects visible by a camera. | 
| 34 | 	 */ | 
| 35 | 	template<bool Core> | 
| 36 | 	class BS_CORE_EXPORT TRenderable : public SceneActor | 
| 37 | 	{ | 
| 38 | 		using MeshType = CoreVariantHandleType<Mesh, Core>; | 
| 39 | 		using MaterialType = CoreVariantHandleType<Material, Core>; | 
| 40 |  | 
| 41 | 	public: | 
| 42 | 		TRenderable(); | 
| 43 | 		virtual ~TRenderable() = default; | 
| 44 |  | 
| 45 | 		/** @copydoc bs::SceneActor::setTransform */ | 
| 46 | 		void setTransform(const Transform& transform) override; | 
| 47 |  | 
| 48 | 		/** | 
| 49 | 		 * Determines the mesh to render. All sub-meshes of the mesh will be rendered, and you may set individual materials | 
| 50 | 		 * for each sub-mesh. | 
| 51 | 		 */ | 
| 52 | 		void setMesh(const MeshType& mesh); | 
| 53 |  | 
| 54 | 		/** | 
| 55 | 		 * Sets a material that will be used for rendering a sub-mesh with the specified index. If a sub-mesh doesn't have | 
| 56 | 		 * a specific material set then the primary material will be used. | 
| 57 | 		 */ | 
| 58 | 		void setMaterial(UINT32 idx, const MaterialType& material); | 
| 59 |  | 
| 60 | 		/** | 
| 61 | 		 * Sets the primary material to use for rendering. Any sub-mesh that doesn't have an explicit material set will use | 
| 62 | 		 * this material. | 
| 63 | 		 * | 
| 64 | 		 * @note	This is equivalent to calling setMaterial(0, material). | 
| 65 | 		 */ | 
| 66 | 		void setMaterial(const MaterialType& material); | 
| 67 |  | 
| 68 | 		/** @copydoc setMaterials() */ | 
| 69 | 		const Vector<MaterialType>& getMaterials() { return mMaterials; } | 
| 70 |  | 
| 71 | 		/** | 
| 72 | 		 * Determines all materials used for rendering this renderable. Each of the materials is used for rendering a single | 
| 73 | 		 * sub-mesh. If number of materials is larger than number of sub-meshes, they will be ignored. If lower, the | 
| 74 | 		 * remaining materials will be removed. | 
| 75 | 		 */ | 
| 76 | 		void setMaterials(const Vector<MaterialType>& materials); | 
| 77 |  | 
| 78 | 		/** | 
| 79 | 		 * Determines the layer bitfield that controls whether a renderable is considered visible in a specific camera.  | 
| 80 | 		 * Renderable layer must match camera layer in order for the camera to render the component. | 
| 81 | 		 */ | 
| 82 | 		void setLayer(UINT64 layer); | 
| 83 |  | 
| 84 | 		/**  | 
| 85 | 		 * Sets bounds that will be used when determining if object is visible. Only relevant if setUseOverrideBounds() is | 
| 86 | 		 * set to true. | 
| 87 | 		 * | 
| 88 | 		 * @param[in]	bounds	Bounds in local space. | 
| 89 | 		 */ | 
| 90 | 		void setOverrideBounds(const AABox& bounds); | 
| 91 |  | 
| 92 | 		/** | 
| 93 | 		 * Enables or disables override bounds. When enabled the bounds provided to setOverrideBounds() will be used for | 
| 94 | 		 * determining object visibility, otherwise the bounds from the object's mesh will be used. Disabled by default. | 
| 95 | 		 */ | 
| 96 | 		void setUseOverrideBounds(bool enable); | 
| 97 |  | 
| 98 | 		/** Factor to be applied to the cull distance set in the camera's render settings.  */ | 
| 99 | 		void setCullDistanceFactor(float factor); | 
| 100 |  | 
| 101 | 		/** @copydoc setCullDistanceFactor() */ | 
| 102 | 		float getCullDistanceFactor() const { return mCullDistanceFactor; } | 
| 103 |  | 
| 104 | 		/** @copydoc setLayer() */ | 
| 105 | 		UINT64 getLayer() const { return mLayer; } | 
| 106 |  | 
| 107 | 		/**	@copydoc setMesh() */ | 
| 108 | 		MeshType getMesh() const { return mMesh; } | 
| 109 |  | 
| 110 | 		/**	Returns the material used for rendering a sub-mesh with the specified index. */ | 
| 111 | 		MaterialType getMaterial(UINT32 idx) const; | 
| 112 |  | 
| 113 | 		/**	Returns the transform matrix that is applied to the object when its being rendered. */ | 
| 114 | 		Matrix4 getMatrix() const { return mTfrmMatrix; } | 
| 115 |  | 
| 116 | 		/** | 
| 117 | 		 * Returns the transform matrix that is applied to the object when its being rendered. This transform matrix does  | 
| 118 | 		 * not include scale values. | 
| 119 | 		 */ | 
| 120 | 		Matrix4 getMatrixNoScale() const { return mTfrmMatrixNoScale; } | 
| 121 |  | 
| 122 | 	protected: | 
| 123 | 		/** | 
| 124 | 		 * Notifies the core object manager that this object is dependant on some other CoreObject(s), and the dependencies | 
| 125 | 		 * changed since the last call to this method. This will trigger a call to getCoreDependencies() to collect the  | 
| 126 | 		 * new dependencies. | 
| 127 | 		 */ | 
| 128 | 		virtual void _markDependenciesDirty() { } | 
| 129 |  | 
| 130 | 		/**	Marks the resource dependencies list as dirty and schedules it for rebuild. */ | 
| 131 | 		virtual void _markResourcesDirty() { } | 
| 132 |  | 
| 133 | 		/** Triggered whenever the renderable's mesh changes. */ | 
| 134 | 		virtual void onMeshChanged() { } | 
| 135 |  | 
| 136 | 		MeshType mMesh; | 
| 137 | 		Vector<MaterialType> mMaterials; | 
| 138 | 		UINT64 mLayer = 1; | 
| 139 | 		AABox mOverrideBounds; | 
| 140 | 		bool mUseOverrideBounds = false; | 
| 141 | 		float mCullDistanceFactor = 1.0f; | 
| 142 | 		Matrix4 mTfrmMatrix = BsIdentity; | 
| 143 | 		Matrix4 mTfrmMatrixNoScale = BsIdentity; | 
| 144 | 		RenderableAnimType mAnimType = RenderableAnimType::None; | 
| 145 | 	}; | 
| 146 |  | 
| 147 | 	/** @} */ | 
| 148 |  | 
| 149 | 	/** @addtogroup Renderer-Internal | 
| 150 | 	 *  @{ | 
| 151 | 	 */ | 
| 152 |  | 
| 153 | 	/** @copydoc TRenderable */ | 
| 154 | 	class BS_CORE_EXPORT Renderable : public IReflectable, public CoreObject, public TRenderable<false>, public IResourceListener | 
| 155 | 	{ | 
| 156 | 	public: | 
| 157 | 		/**	Gets world bounds of the mesh rendered by this object. */ | 
| 158 | 		Bounds getBounds() const; | 
| 159 |  | 
| 160 | 		/** Determines the animation that will be used for animating the attached mesh. */ | 
| 161 | 		void setAnimation(const SPtr<Animation>& animation); | 
| 162 |  | 
| 163 | 		/** @copydoc setAnimation */ | 
| 164 | 		const SPtr<Animation>& getAnimation() const { return mAnimation; } | 
| 165 |  | 
| 166 | 		/** Checks is the renderable animated or static. */ | 
| 167 | 		bool isAnimated() const { return mAnimation != nullptr; } | 
| 168 |  | 
| 169 | 		/**	Retrieves an implementation of a renderable handler usable only from the core thread. */ | 
| 170 | 		SPtr<ct::Renderable> getCore() const; | 
| 171 |  | 
| 172 | 		/**	Creates a new renderable handler instance. */ | 
| 173 | 		static SPtr<Renderable> create(); | 
| 174 |  | 
| 175 | 		/** | 
| 176 | 		 * @name Internal | 
| 177 | 		 * @{ | 
| 178 | 		 */ | 
| 179 |  | 
| 180 | 		/** @copydoc SceneActor::_updateState */ | 
| 181 | 		void _updateState(const SceneObject& so, bool force = false) override; | 
| 182 |  | 
| 183 | 		/** @copydoc CoreObject::initialize() */ | 
| 184 | 		void initialize() override; | 
| 185 |  | 
| 186 | 		/** @} */ | 
| 187 | 	protected: | 
| 188 | 		/** @copydoc CoreObject::createCore */ | 
| 189 | 		SPtr<ct::CoreObject> createCore() const override; | 
| 190 |  | 
| 191 | 		/** @copydoc TRenderable::onMeshChanged */ | 
| 192 | 		void onMeshChanged() override; | 
| 193 |  | 
| 194 | 		/** Updates animation properties depending on the current mesh. */ | 
| 195 | 		void refreshAnimation(); | 
| 196 |  | 
| 197 | 		/** @copydoc TRenderable::_markCoreDirty */ | 
| 198 | 		void _markCoreDirty(ActorDirtyFlag flag = ActorDirtyFlag::Everything) override; | 
| 199 |  | 
| 200 | 		/** @copydoc TRenderable::_markResourcesDirty */ | 
| 201 | 		void _markResourcesDirty() override; | 
| 202 |  | 
| 203 | 		/** @copydoc CoreObject::markDependenciesDirty */ | 
| 204 | 		void _markDependenciesDirty() override; | 
| 205 |  | 
| 206 | 		/** @copydoc CoreObject::syncToCore */ | 
| 207 | 		CoreSyncData syncToCore(FrameAlloc* allocator) override; | 
| 208 |  | 
| 209 | 		/** @copydoc CoreObject::getCoreDependencies */ | 
| 210 | 		void getCoreDependencies(Vector<CoreObject*>& dependencies) override; | 
| 211 |  | 
| 212 | 		/** @copydoc CoreObject::onDependencyDirty */ | 
| 213 | 		void onDependencyDirty(CoreObject* dependency, UINT32 dirtyFlags) override; | 
| 214 |  | 
| 215 | 		/** @copydoc IResourceListener::getListenerResources */ | 
| 216 | 		void getListenerResources(Vector<HResource>& resources) override; | 
| 217 |  | 
| 218 | 		/** @copydoc IResourceListener::notifyResourceLoaded */ | 
| 219 | 		void notifyResourceLoaded(const HResource& resource) override; | 
| 220 |  | 
| 221 | 		/** @copydoc IResourceListener::notifyResourceChanged */ | 
| 222 | 		void notifyResourceChanged(const HResource& resource) override; | 
| 223 |  | 
| 224 | 		/**	Creates a new renderable instance without initializing it. */ | 
| 225 | 		static SPtr<Renderable> createEmpty(); | 
| 226 |  | 
| 227 | 		SPtr<Animation> mAnimation; | 
| 228 |  | 
| 229 | 		/************************************************************************/ | 
| 230 | 		/* 								RTTI		                     		*/ | 
| 231 | 		/************************************************************************/ | 
| 232 | 	public: | 
| 233 | 		friend class RenderableRTTI; | 
| 234 | 		static RTTITypeBase* getRTTIStatic(); | 
| 235 | 		RTTITypeBase* getRTTI() const override; | 
| 236 | 	}; | 
| 237 |  | 
| 238 | 	namespace ct | 
| 239 | 	{ | 
| 240 | 	/** @copydoc TRenderable */ | 
| 241 | 	class BS_CORE_EXPORT Renderable : public CoreObject, public TRenderable<true> | 
| 242 | 	{ | 
| 243 | 	public: | 
| 244 | 		~Renderable(); | 
| 245 |  | 
| 246 | 		/**	Gets world bounds of the mesh rendered by this object. */ | 
| 247 | 		Bounds getBounds() const; | 
| 248 |  | 
| 249 | 		/**	Sets an ID that can be used for uniquely identifying this object by the renderer. */ | 
| 250 | 		void setRendererId(UINT32 id) { mRendererId = id; } | 
| 251 |  | 
| 252 | 		/**	Retrieves an ID that can be used for uniquely identifying this object by the renderer. */ | 
| 253 | 		UINT32 getRendererId() const { return mRendererId; } | 
| 254 |  | 
| 255 | 		/** Returns the type of animation influencing this renderable, if any. */ | 
| 256 | 		RenderableAnimType getAnimType() const { return mAnimType; } | 
| 257 |  | 
| 258 | 		/** Returns the identifier of the animation, if this object is animated using skeleton or blend shape animation. */ | 
| 259 | 		UINT64 getAnimationId() const { return mAnimationId; } | 
| 260 |  | 
| 261 | 		/**  | 
| 262 | 		 * Updates internal animation buffers from the contents of the provided animation data object. Does nothing if | 
| 263 | 		 * renderable is not affected by animation. | 
| 264 | 		 */ | 
| 265 | 		void updateAnimationBuffers(const EvaluatedAnimationData& animData); | 
| 266 |  | 
| 267 | 		/** Returns the GPU buffer containing element's bone matrices, if it has any. */ | 
| 268 | 		const SPtr<GpuBuffer>& getBoneMatrixBuffer() const { return mBoneMatrixBuffer; } | 
| 269 |  | 
| 270 | 		/** Returns the vertex buffer containing element's morph shape vertices, if it has any. */ | 
| 271 | 		const SPtr<VertexBuffer>& getMorphShapeBuffer() const { return mMorphShapeBuffer; } | 
| 272 |  | 
| 273 | 		/** Returns vertex declaration used for rendering meshes containing morph shape information. */ | 
| 274 | 		const SPtr<VertexDeclaration>& getMorphVertexDeclaration() const { return mMorphVertexDeclaration; } | 
| 275 |  | 
| 276 | 	protected: | 
| 277 | 		friend class bs::Renderable; | 
| 278 |  | 
| 279 | 		Renderable(); | 
| 280 |  | 
| 281 | 		/** @copydoc CoreObject::initialize */ | 
| 282 | 		void initialize() override; | 
| 283 |  | 
| 284 | 		/** @copydoc CoreObject::syncToCore */ | 
| 285 | 		void syncToCore(const CoreSyncData& data) override; | 
| 286 |  | 
| 287 | 		/** Creates any buffers required for renderable animation. Should be called whenever animation properties change. */ | 
| 288 | 		void createAnimationBuffers(); | 
| 289 |  | 
| 290 | 		UINT32 mRendererId; | 
| 291 | 		UINT64 mAnimationId; | 
| 292 | 		UINT32 mMorphShapeVersion; | 
| 293 |  | 
| 294 | 		SPtr<GpuBuffer> mBoneMatrixBuffer; | 
| 295 | 		SPtr<VertexBuffer> mMorphShapeBuffer; | 
| 296 | 		SPtr<VertexDeclaration> mMorphVertexDeclaration; | 
| 297 | 	}; | 
| 298 | 	} | 
| 299 |  | 
| 300 | 	/** @} */ | 
| 301 | } | 
| 302 |  |