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
13namespace 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