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 "Math/BsVector2.h"
9#include "Scene/BsSceneActor.h"
10#include "Math/BsBounds.h"
11
12namespace bs
13{
14 /** @addtogroup Implementation
15 * @{
16 */
17
18 /** Base class for both core and sim thread implementations of Decal. */
19 class BS_CORE_EXPORT DecalBase : public SceneActor
20 {
21 public:
22 DecalBase();
23 DecalBase(const Vector2& size, float maxDistance);
24 virtual ~DecalBase() = default;
25
26 /** Size of the decal in world space units. */
27 void setSize(const Vector2& size) { mSize = size; _markCoreDirty(); updateBounds(); }
28
29 /** @copydoc setSize */
30 Vector2 getSize() const
31 {
32 return Vector2(mSize.x * mTransform.getScale().x, mSize.y * mTransform.getScale().y);
33 }
34
35 /** Determines the maximum distance (from its origin) at which the decal is displayed. */
36 void setMaxDistance(float distance) { mMaxDistance = distance; _markCoreDirty(); updateBounds(); }
37
38 /** @copydoc getSize */
39 float getMaxDistance() const { return mMaxDistance * mTransform.getScale().z; }
40
41 /**
42 * Bitfield that allows you to mask on which objects will the decal be projected onto. Only objects with the
43 * matching layers will be projected onto. Note that decal layer mask only supports 32-bits and objects with
44 * layers in bits >= 32 will always be projected onto.
45 */
46 void setLayerMask(UINT32 mask) { mLayerMask = mask; _markCoreDirty(); }
47
48 /** @copydoc setLayerMask */
49 UINT32 getLayerMask() const { return mLayerMask; }
50
51 /**
52 * Determines the layer that controls whether a system is considered visible in a specific camera. Layer must match
53 * camera layer bitfield in order for the camera to render the decal.
54 */
55 void setLayer(UINT64 layer);
56
57 /** @copydoc setLayer() */
58 UINT64 getLayer() const { return mLayer; }
59
60 /** Gets world bounds of this object. */
61 Bounds getBounds() const { return mBounds; }
62
63 /** Returns the transform matrix that is applied to the object when its being rendered. */
64 Matrix4 getMatrix() const { return mTfrmMatrix; }
65
66 /**
67 * Returns the transform matrix that is applied to the object when its being rendered. This transform matrix does
68 * not include scale values.
69 */
70 Matrix4 getMatrixNoScale() const { return mTfrmMatrixNoScale; }
71
72 /** @copydoc SceneActor::setTransform */
73 void setTransform(const Transform& transform) override;
74 protected:
75 /** Updates the internal bounds for the decal. Call this whenever a property affecting the bounds changes. */
76 void updateBounds();
77
78 Vector2 mSize = Vector2::ONE;
79 float mMaxDistance = 10.0f;
80 UINT64 mLayer = 1;
81 UINT32 mLayerMask = 0xFFFFFFFF;
82 Matrix4 mTfrmMatrix = BsIdentity;
83 Matrix4 mTfrmMatrixNoScale = BsIdentity;
84
85 Bounds mBounds;
86 };
87
88 /** Templated base class for both core and sim thread implementations of Decal. */
89 template<bool Core>
90 class BS_CORE_EXPORT TDecal : public DecalBase
91 {
92 public:
93 using MaterialType = CoreVariantHandleType<Material, Core>;
94
95 TDecal() = default;
96 TDecal(const MaterialType& material, const Vector2& size, float maxDistance)
97 :DecalBase(size, maxDistance), mMaterial(material)
98 { }
99 virtual ~TDecal() = default;
100
101 /** Determines the material to use when rendering the decal. */
102 void setMaterial(const MaterialType& material) { mMaterial = material; _markCoreDirty(); }
103
104 /** @copydoc setMaterial */
105 const MaterialType& getMaterial() const { return mMaterial; }
106
107 /** Enumerates all the fields in the type and executes the specified processor action for each field. */
108 template<class P>
109 void rttiEnumFields(P p);
110
111 protected:
112 MaterialType mMaterial;
113 };
114
115 /** @} */
116 /** @addtogroup Renderer-Internal
117 * @{
118 */
119
120 namespace ct { class Decal; }
121
122 /**
123 * Specifies a decal that will be projected onto scene geometry. User can set the material to use when rendering
124 * the decal, as well as control decal orientation and size.
125 */
126 class BS_CORE_EXPORT Decal : public IReflectable, public CoreObject, public TDecal<false>
127 {
128 public:
129 /** Retrieves an implementation of the decal usable only from the core thread. */
130 SPtr<ct::Decal> getCore() const;
131
132 /**
133 * Creates a new decal.
134 *
135 * @param[in] material Material to use when rendering the decal.
136 * @param[in] size Size of the decal in world units.
137 * @param[in] maxDistance Maximum distance at which will the decal be visible (from the current decal origin,
138 * along the negative Z axis).
139 * @returns New decal object.
140 */
141 static SPtr<Decal> create(const HMaterial& material, const Vector2& size = Vector2::ONE, float maxDistance = 10.0f);
142
143 protected:
144 Decal(const HMaterial& material, const Vector2& size, float maxDistance);
145
146 /** @copydoc CoreObject::createCore */
147 SPtr<ct::CoreObject> createCore() const override;
148
149 /** @copydoc CoreObject::getCoreDependencies */
150 void getCoreDependencies(Vector<CoreObject*>& dependencies) override;
151
152 /** @copydoc DecalBase::_markCoreDirty */
153 void _markCoreDirty(ActorDirtyFlag flags = ActorDirtyFlag::Everything) override;
154
155 /** @copydoc CoreObject::syncToCore */
156 CoreSyncData syncToCore(FrameAlloc* allocator) override;
157
158 /** Creates the object with without initializing it. Used for serialization. */
159 static SPtr<Decal> createEmpty();
160
161 /************************************************************************/
162 /* RTTI */
163 /************************************************************************/
164 public:
165 friend class DecalRTTI;
166 static RTTITypeBase* getRTTIStatic();
167 RTTITypeBase* getRTTI() const override;
168
169 protected:
170 Decal() = default; // Serialization only
171 };
172
173 namespace ct
174 {
175 /** Core thread version of a bs::Decal */
176 class BS_CORE_EXPORT Decal : public CoreObject, public TDecal<true>
177 {
178 public:
179 ~Decal();
180
181 /** Sets an ID that can be used for uniquely identifying this object by the renderer. */
182 void setRendererId(UINT32 id) { mRendererId = id; }
183
184 /** Retrieves an ID that can be used for uniquely identifying this object by the renderer. */
185 UINT32 getRendererId() const { return mRendererId; }
186
187 protected:
188 friend class bs::Decal;
189
190 Decal(const SPtr<Material>& material, const Vector2& size, float maxDistance);
191
192 /** @copydoc CoreObject::initialize */
193 void initialize() override;
194
195 /** @copydoc CoreObject::syncToCore */
196 void syncToCore(const CoreSyncData& data) override;
197
198 UINT32 mRendererId = 0;
199 };
200 }
201
202 /** @} */
203}
204