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