Overte C++ Documentation
RenderableEntityItem.h
1 //
2 // RenderableEntityItem.h
3 // interface/src
4 //
5 // Created by Brad Hefta-Gaub on 12/6/13.
6 // Copyright 2013 High Fidelity, Inc.
7 // Copyright 2024 Overte e.V.
8 //
9 // Distributed under the Apache License, Version 2.0.
10 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
11 //
12 
13 #ifndef hifi_RenderableEntityItem_h
14 #define hifi_RenderableEntityItem_h
15 
16 #include <render/Scene.h>
17 #include <render/HighlightStyle.h>
18 
19 #include <EntityItem.h>
20 #include <Sound.h>
21 #include "AbstractViewStateInterface.h"
22 #include "EntitiesRendererLogging.h"
23 #include <graphics-scripting/Forward.h>
24 #include <RenderHifi.h>
25 #include "EntityTreeRenderer.h"
26 
27 class EntityTreeRenderer;
28 
29 namespace render { namespace entities {
30 
31 // Base class for all renderable entities
32 class EntityRenderer : public QObject, public std::enable_shared_from_this<EntityRenderer>, public PayloadProxyInterface, protected ReadWriteLockable, public scriptable::ModelProvider {
33  Q_OBJECT
34 
35  using Pointer = std::shared_ptr<EntityRenderer>;
36 
37 public:
38  static void initEntityRenderers();
39  static Pointer addToScene(EntityTreeRenderer& renderer, const EntityItemPointer& entity, const ScenePointer& scene, Transaction& transaction);
40 
41  // Allow classes to override this to interact with the user
42  virtual bool wantsHandControllerPointerEvents() const { return false; }
43  virtual bool wantsKeyboardFocus() const { return false; }
44  virtual void setProxyWindow(QWindow* proxyWindow) {}
45  virtual QObject* getEventHandler() { return nullptr; }
46  virtual void emitScriptEvent(const QVariant& message) {}
47  const EntityItemPointer& getEntity() const { return _entity; }
48  const ItemID& getRenderItemID() const { return _renderItemID; }
49 
50  const SharedSoundPointer& getCollisionSound() { return _collisionSound; }
51  void setCollisionSound(const SharedSoundPointer& sound) { _collisionSound = sound; }
52 
53  // Handlers for rendering events... executed on the main thread, only called by EntityTreeRenderer,
54  // cannot be overridden or accessed by subclasses
55  virtual void updateInScene(const ScenePointer& scene, Transaction& transaction) final;
56  virtual bool addToScene(const ScenePointer& scene, Transaction& transaction) final;
57  virtual void removeFromScene(const ScenePointer& scene, Transaction& transaction);
58 
59  const uint64_t& getUpdateTime() const { return _updateTime; }
60 
61  enum class Pipeline {
62  SIMPLE,
63  MATERIAL,
64  PROCEDURAL
65  };
66  virtual void addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName);
67  virtual void removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName);
68  virtual graphics::MaterialPointer getTopMaterial();
69  static Pipeline getPipelineType(const graphics::MultiMaterial& materials);
70  virtual gpu::TexturePointer getTexture() { return nullptr; }
71 
72  virtual scriptable::ScriptableModelBase getScriptableModel() override { return scriptable::ScriptableModelBase(); }
73 
74  static glm::vec4 calculatePulseColor(const glm::vec4& color, const PulsePropertyGroup& pulseProperties, quint64 start);
75  static glm::vec3 calculatePulseColor(const glm::vec3& color, const PulsePropertyGroup& pulseProperties, quint64 start);
76 
77  virtual uint32_t metaFetchMetaSubItems(ItemIDs& subItems) const override;
78  virtual Item::Bound getBound(RenderArgs* args) override;
79  bool passesZoneOcclusionTest(const std::unordered_set<QUuid>& containingZones) const override;
80  virtual HighlightStyle getOutlineStyle(const ViewFrustum& viewFrustum, const size_t height) const override;
81 
82 protected:
83  virtual bool needsRenderUpdateFromEntity() const final { return needsRenderUpdateFromEntity(_entity); }
84  virtual void onAddToScene(const EntityItemPointer& entity);
85  virtual void onRemoveFromScene(const EntityItemPointer& entity);
86 
87  EntityRenderer(const EntityItemPointer& entity);
88  ~EntityRenderer();
89 
90  // Implementing the PayloadProxyInterface methods
91  virtual ItemKey getKey() override;
92  virtual ShapeKey getShapeKey() override;
93  virtual void render(RenderArgs* args) override final;
94  virtual render::hifi::Tag getTagMask() const;
95  virtual render::hifi::Layer getHifiRenderLayer() const;
96 
97  // Returns true if the item in question needs to have updateInScene called because of internal rendering state changes
98  virtual bool needsRenderUpdate() const;
99 
100  // Returns true if the item in question needs to have updateInScene called because of changes in the entity
101  virtual bool needsRenderUpdateFromEntity(const EntityItemPointer& entity) const;
102 
103  // Will be called on the main thread from updateInScene. This can be used to fetch things like
104  // network textures or model geometry from resource caches
105  virtual void doRenderUpdateSynchronous(const ScenePointer& scene, Transaction& transaction, const EntityItemPointer& entity);
106 
107  // Will be called by the lambda posted to the scene in updateInScene.
108  // This function will execute on the rendering thread, so you cannot use network caches to fetch
109  // data in this method if using multi-threaded rendering
110  virtual void doRenderUpdateAsynchronous(const EntityItemPointer& entity);
111 
112  // Called by the `render` method after `needsRenderUpdate`
113  virtual void doRender(RenderArgs* args) = 0;
114 
115  virtual bool isFading() const { return _isFading; }
116  virtual void updateModelTransformAndBound(const EntityItemPointer& entity);
117  virtual bool isTransparent() const { return _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) < 1.0f : false; }
118  inline bool isValidRenderItem() const { return _renderItemID != Item::INVALID_ITEM_ID; }
119 
120  virtual void setIsVisibleInSecondaryCamera(bool value) { _isVisibleInSecondaryCamera = value; }
121  virtual void setRenderLayer(RenderLayer value) { _renderLayer = value; }
122  virtual void setCullWithParent(bool value) { _cullWithParent = value; }
123 
124  template<typename T>
125  std::shared_ptr<T> asTypedEntity() { return std::static_pointer_cast<T>(_entity); }
126 
127  static void makeStatusGetters(const EntityItemPointer& entity, Item::Status::Getters& statusGetters);
128  const Transform& getModelTransform() const;
129 
130  Transform getTransformToCenterWithMaybeOnlyLocalRotation(const EntityItemPointer& entity, bool& success) const;
131 
132  // Shared methods for entities that support materials
133  using MaterialMap = std::unordered_map<std::string, graphics::MultiMaterial>;
134  bool needsRenderUpdateFromMaterials() const;
135  void updateMaterials(bool baseMaterialChanged = false);
136  bool materialsTransparent() const;
137  Item::Bound getMaterialBound(RenderArgs* args);
138  void updateItemKeyBuilderFromMaterials(ItemKey::Builder& builder);
139  void updateShapeKeyBuilderFromMaterials(ShapeKey::Builder& builder);
140 
141  Item::Bound _bound;
142  SharedSoundPointer _collisionSound;
143  QUuid _changeHandlerId;
144  ItemID _renderItemID{ Item::INVALID_ITEM_ID };
145  uint64_t _fadeStartTime{ usecTimestampNow() };
146  uint64_t _updateTime{ usecTimestampNow() }; // used when sorting/throttling render updates
147  bool _isFading { EntityTreeRenderer::getEntitiesShouldFadeFunction()() };
148  bool _prevIsTransparent { false };
149  bool _visible { false };
150  bool _isVisibleInSecondaryCamera { false };
151  bool _canCastShadow { false };
152  bool _cullWithParent { false };
153  RenderLayer _renderLayer { RenderLayer::WORLD };
154  PrimitiveMode _primitiveMode { PrimitiveMode::SOLID };
155  QVector<QUuid> _renderWithZones;
156  BillboardMode _billboardMode { BillboardMode::NONE };
157  bool _cauterized { false };
158  bool _moving { false };
159  Transform _renderTransform;
160 
161  MaterialMap _materials;
162  mutable std::mutex _materialsLock;
163 
164  quint64 _created;
165 
166  // The base class relies on comparing the model transform to the entity transform in order
167  // to trigger an update, so the member must not be visible to derived classes as a modifiable
168  // transform
169  Transform _modelTransform;
170  // The rendering code only gets access to the entity in very specific circumstances
171  // i.e. to see if the rendering code needs to update because of a change in state of the
172  // entity. This forces all the rendering code itself to be independent of the entity
173  const EntityItemPointer _entity;
174 
175  QUuid _entityID;
176 
177 signals:
178  void requestRenderUpdate();
179 };
180 
181 template <typename T>
182 class TypedEntityRenderer : public EntityRenderer {
183  using Parent = EntityRenderer;
184 
185 public:
186  TypedEntityRenderer(const EntityItemPointer& entity) : Parent(entity), _typedEntity(asTypedEntity<T>()) {}
187 
188 protected:
189  using TypedEntityPointer = std::shared_ptr<T>;
190 
191  virtual void onAddToScene(const EntityItemPointer& entity) override final {
192  Parent::onAddToScene(entity);
193  onAddToSceneTyped(_typedEntity);
194  }
195 
196  virtual void onRemoveFromScene(const EntityItemPointer& entity) override final {
197  Parent::onRemoveFromScene(entity);
198  onRemoveFromSceneTyped(_typedEntity);
199  }
200 
201  using Parent::needsRenderUpdateFromEntity;
202  // Returns true if the item in question needs to have updateInScene called because of changes in the entity
203  virtual bool needsRenderUpdateFromEntity(const EntityItemPointer& entity) const override final {
204  return Parent::needsRenderUpdateFromEntity(entity) || needsRenderUpdateFromTypedEntity(_typedEntity);
205  }
206 
207  virtual void doRenderUpdateSynchronous(const ScenePointer& scene, Transaction& transaction, const EntityItemPointer& entity) override final {
208  Parent::doRenderUpdateSynchronous(scene, transaction, entity);
209  doRenderUpdateSynchronousTyped(scene, transaction, _typedEntity);
210  }
211 
212  virtual void doRenderUpdateAsynchronous(const EntityItemPointer& entity) override final {
213  Parent::doRenderUpdateAsynchronous(entity);
214  doRenderUpdateAsynchronousTyped(_typedEntity);
215  }
216 
217  virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { return false; }
218  virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { }
219  virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { }
220  virtual void onAddToSceneTyped(const TypedEntityPointer& entity) { }
221  virtual void onRemoveFromSceneTyped(const TypedEntityPointer& entity) { }
222 
223 private:
224  const TypedEntityPointer _typedEntity;
225 };
226 
227 } } // namespace render::entities
228 
229 #endif // hifi_RenderableEntityItem_h