Overte C++ Documentation
RenderablePolyVoxEntityItem.h
1 //
2 // RenderablePolyVoxEntityItem.h
3 // libraries/entities-renderer/src/
4 //
5 // Created by Seth Alves on 5/19/15.
6 // Copyright 2015 High Fidelity, Inc.
7 //
8 // Distributed under the Apache License, Version 2.0.
9 // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
10 //
11 
12 #ifndef hifi_RenderablePolyVoxEntityItem_h
13 #define hifi_RenderablePolyVoxEntityItem_h
14 
15 #include <atomic>
16 
17 #include <QSemaphore>
18 
19 #include <gpu/Forward.h>
20 #include <gpu/Context.h>
21 #include <graphics/Forward.h>
22 #include <graphics/Geometry.h>
23 #include <TextureCache.h>
24 #include <PolyVoxEntityItem.h>
25 
26 #include "RenderableEntityItem.h"
27 
28 namespace render { namespace entities {
29 class PolyVoxEntityRenderer;
30 }} // namespace render::entities
31 
32 class VoxelVolume;
33 
34 enum class PolyVoxState
35 {
36  Ready,
37  Uncompressing,
38  UncompressingFinished,
39  BakingMesh,
40  BakingMeshFinished,
41  BakingMeshNoCompress,
42  BakingMeshNoCompressFinished,
43  Compressing,
44  CompressingFinished,
45  BakingShape,
46  BakingShapeFinished
47 };
48 
49 QDebug operator<<(QDebug debug, PolyVoxState state);
50 
51 class RenderablePolyVoxEntityItem : public PolyVoxEntityItem, public scriptable::ModelProvider {
52  friend class render::entities::PolyVoxEntityRenderer;
53 
54 public:
55  static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
56  RenderablePolyVoxEntityItem(const EntityItemID& entityItemID);
57 
58  virtual ~RenderablePolyVoxEntityItem();
59 
60  void initializePolyVox();
61 
62  using PolyVoxEntityItem::getVoxel;
63  virtual uint8_t getVoxel(const ivec3& v) const override;
64 
65  using PolyVoxEntityItem::setVoxel;
66  virtual bool setVoxel(const ivec3& v, uint8_t toValue) override;
67 
68  int getOnCount() const override { return _onCount; }
69 
70  virtual bool supportsDetailedIntersection() const override { return true; }
71  virtual bool findDetailedRayIntersection(const glm::vec3& origin,
72  const glm::vec3& direction,
73  const glm::vec3& viewFrustumPos,
74  OctreeElementPointer& element,
75  float& distance,
76  BoxFace& face,
77  glm::vec3& surfaceNormal,
78  QVariantMap& extraInfo,
79  bool precisionPicking) const override;
80  virtual bool findDetailedParabolaIntersection(const glm::vec3& origin,
81  const glm::vec3& velocity,
82  const vec3& accleration,
83  const glm::vec3& viewFrustumPos,
84  OctreeElementPointer& element,
85  float& parabolicDistance,
86  BoxFace& face,
87  glm::vec3& surfaceNormal,
88  QVariantMap& extraInfo,
89  bool precisionPicking) const override;
90 
91  virtual void setVoxelData(const QByteArray& voxelData) override;
92  virtual void setVoxelVolumeSize(const glm::vec3& voxelVolumeSize) override;
93  virtual void setVoxelSurfaceStyle(uint16_t voxelSurfaceStyle) override;
94 
95  virtual ShapeType getShapeType() const override;
96  virtual bool isReadyToComputeShape() const override;
97  virtual void computeShapeInfo(ShapeInfo& info) override;
98 
99  // coords are in voxel-volume space
100  virtual bool setSphereInVolume(const vec3& center, float radius, uint8_t toValue) override;
101  virtual bool setVoxelInVolume(const vec3& position, uint8_t toValue) override;
102 
103  // coords are in world-space
104  virtual bool setSphere(const vec3& center, float radius, uint8_t toValue) override;
105  virtual bool setCapsule(const vec3& startWorldCoords,
106  const vec3& endWorldCoords,
107  float radiusWorldCoords,
108  uint8_t toValue) override;
109  virtual bool setAll(uint8_t toValue) override;
110  virtual bool setCuboid(const vec3& lowPosition, const vec3& cuboidSize, int toValue) override;
111 
112  virtual void setXNNeighborID(const EntityItemID& xNNeighborID) override;
113  virtual void setYNNeighborID(const EntityItemID& yNNeighborID) override;
114  virtual void setZNNeighborID(const EntityItemID& zNNeighborID) override;
115 
116  virtual void setXPNeighborID(const EntityItemID& xPNeighborID) override;
117  virtual void setYPNeighborID(const EntityItemID& yPNeighborID) override;
118  virtual void setZPNeighborID(const EntityItemID& zPNeighborID) override;
119 
120  std::shared_ptr<RenderablePolyVoxEntityItem> getXNNeighbor();
121  std::shared_ptr<RenderablePolyVoxEntityItem> getYNNeighbor();
122  std::shared_ptr<RenderablePolyVoxEntityItem> getZNNeighbor();
123  std::shared_ptr<RenderablePolyVoxEntityItem> getXPNeighbor();
124  std::shared_ptr<RenderablePolyVoxEntityItem> getYPNeighbor();
125  std::shared_ptr<RenderablePolyVoxEntityItem> getZPNeighbor();
126 
127  virtual void setRegistrationPoint(const glm::vec3& value) override;
128 
129  void setVoxelsFromData(QByteArray uncompressedData, quint16 voxelXSize, quint16 voxelYSize, quint16 voxelZSize);
130  void forEachVoxelValue(const ivec3& voxelSize, std::function<void(const ivec3&, uint8_t)> thunk);
131  QByteArray volDataToArray(quint16 voxelXSize, quint16 voxelYSize, quint16 voxelZSize) const;
132 
133  void setMesh(graphics::MeshPointer mesh);
134  void setCollisionPoints(ShapeInfo::PointCollection points, AABox box);
135 
136  uint8_t getVoxelInternal(const ivec3& v) const;
137  bool setVoxelInternal(const ivec3& v, uint8_t toValue);
138  void setVoxelMarkNeighbors(int x, int y, int z, uint8_t toValue);
139 
140  void compressVolumeDataFinished(const QByteArray& voxelData);
141  void neighborXEdgeChanged() {
142  withWriteLock([&] { _updateFromNeighborXEdge = true; });
143  startUpdates();
144  }
145  void neighborYEdgeChanged() {
146  withWriteLock([&] { _updateFromNeighborYEdge = true; });
147  startUpdates();
148  }
149  void neighborZEdgeChanged() {
150  withWriteLock([&] { _updateFromNeighborZEdge = true; });
151  startUpdates();
152  }
153 
154  bool getMeshes(MeshProxyList& result) override; // deprecated
155  virtual scriptable::ScriptableModelBase getScriptableModel() override;
156 
157  virtual void update(const quint64& now) override;
158  bool needsToCallUpdate() const override { return _updateNeeded; }
159 
160 private:
161  bool updateOnCount(const ivec3& v, uint8_t toValue);
162 
163  void changeUpdates(bool value);
164  void startUpdates();
165  void stopUpdates();
166 
167  void recomputeMesh();
168  void cacheNeighbors();
169  void copyUpperEdgesFromNeighbors();
170  void tellNeighborsToRecopyEdges(bool force);
171  bool updateDependents();
172 
173  // these are run off the main thread
174  void uncompressVolumeData();
175  void compressVolumeDataAndSendEditPacket();
176  void computeShapeInfoWorker();
177 
178  // The PolyVoxEntityItem class has _voxelData which contains dimensions and compressed voxel data. The dimensions
179  // may not match _voxelVolumeSize.
180  bool _meshReady{ false }; // do we have something to give scripts that ask for the mesh?
181  bool _voxelDataDirty{ false }; // do we need to uncompress data and expand it into _volData?
182  bool _volDataDirty{ false }; // does recomputeMesh need to be called?
183  bool _shapeReady{ false }; // are we ready to tell bullet our shape?
184  PolyVoxState _state{ PolyVoxState::Ready };
185  bool _updateNeeded{ true };
186 
187  graphics::MeshPointer _mesh;
188 
189  ShapeInfo _shapeInfo;
190 
191  std::shared_ptr<VoxelVolume> _volData;
192  int _onCount; // how many non-zero voxels are in _volData
193 
194  bool _neighborXNeedsUpdate{ false };
195  bool _neighborYNeedsUpdate{ false };
196  bool _neighborZNeedsUpdate{ false };
197 
198  bool _updateFromNeighborXEdge{ false };
199  bool _updateFromNeighborYEdge{ false };
200  bool _updateFromNeighborZEdge{ false };
201 
202  // these are cached lookups of _xNNeighborID, _yNNeighborID, _zNNeighborID, _xPNeighborID, _yPNeighborID, _zPNeighborID
203  EntityItemWeakPointer _xNNeighbor; // neighbor found by going along negative X axis
204  EntityItemWeakPointer _yNNeighbor;
205  EntityItemWeakPointer _zNNeighbor;
206  EntityItemWeakPointer _xPNeighbor; // neighbor found by going along positive X axis
207  EntityItemWeakPointer _yPNeighbor;
208  EntityItemWeakPointer _zPNeighbor;
209 };
210 
211 namespace render { namespace entities {
212 
213 class PolyVoxEntityRenderer : public TypedEntityRenderer<RenderablePolyVoxEntityItem> {
214  using Parent = TypedEntityRenderer<RenderablePolyVoxEntityItem>;
215  friend class EntityRenderer;
216 
217 public:
218  PolyVoxEntityRenderer(const EntityItemPointer& entity);
219 
220  virtual scriptable::ScriptableModelBase getScriptableModel() override;
221 
222 protected:
223  virtual ShapeKey getShapeKey() override;
224  virtual bool isTransparent() const override;
225  virtual Item::Bound getBound(RenderArgs* args) override;
226  virtual bool needsRenderUpdate() const override;
227  virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override;
228  virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override;
229  virtual void doRender(RenderArgs* args) override;
230 
231 private:
232  graphics::MeshPointer _mesh;
233  gpu::BufferPointer _params;
234  std::array<NetworkTexturePointer, 3> _xyzTextures;
235  glm::vec3 _lastVoxelVolumeSize;
236  glm::mat4 _lastVoxelToLocalMatrix;
237  glm::vec3 _position;
238  glm::quat _orientation;
239  PolyVoxEntityItem::PolyVoxSurfaceStyle _lastSurfaceStyle{ PolyVoxEntityItem::SURFACE_MARCHING_CUBES };
240  std::array<QString, 3> _xyzTextureUrls;
241 
242  gpu::BufferPointer _colorBuffer{ std::make_shared<gpu::Buffer>(gpu::Buffer::VertexBuffer) };
243 };
244 
245 }} // namespace render::entities
246 
247 #endif // hifi_RenderablePolyVoxEntityItem_h
Abstract ID for editing model items. Used in EntityItem JS API.
Definition: EntityItemID.h:28
Definition: RenderablePolyVoxEntityItem.cpp:185
Definition: Args.h:100