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