From 8ccb44b71eb8d910558ecd048dc311da9241ac19 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 9 Dec 2014 16:24:07 -0800 Subject: [PATCH] Bits of stack implementation. --- interface/src/MetavoxelSystem.cpp | 39 +++++++++++++++++++++++----- interface/src/MetavoxelSystem.h | 34 ++++++++++++------------ libraries/metavoxels/src/Spanner.cpp | 21 +++++++++++++++ libraries/metavoxels/src/Spanner.h | 11 ++++++++ 4 files changed, 82 insertions(+), 23 deletions(-) diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index 87060d7dfa..08a85df090 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -363,7 +363,7 @@ void MetavoxelSystem::render() { _baseVoxelProgram.bind(); - foreach (const VoxelBatch& batch, _voxelBaseBatches) { + foreach (const MetavoxelBatch& batch, _voxelBaseBatches) { batch.vertexBuffer->bind(); batch.indexBuffer->bind(); @@ -712,7 +712,7 @@ int BufferCursorRenderVisitor::visit(MetavoxelInfo& info) { } BufferData* buffer = info.inputValues.at(0).getInlineValue().data(); if (buffer) { - buffer->render(true); + buffer->render(glm::vec3(), glm::quat(), glm::vec3(1.0f, 1.0f, 1.0f), true); } return info.isLeaf ? STOP_RECURSION : DEFAULT_ORDER; } @@ -1163,7 +1163,7 @@ bool VoxelBuffer::findFirstRayIntersection(const glm::vec3& entry, const glm::ve return false; } -void VoxelBuffer::render(bool cursor) { +void VoxelBuffer::render(const glm::vec3& translation, const glm::quat& rotation, const glm::vec3& scale, bool cursor) { if (!_vertexBuffer.isCreated()) { _vertexBuffer.create(); _vertexBuffer.bind(); @@ -1203,7 +1203,10 @@ void VoxelBuffer::render(bool cursor) { return; } - VoxelBatch baseBatch; + MetavoxelBatch baseBatch; + baseBatch.translation = translation; + baseBatch.rotation = rotation; + baseBatch.scale = scale; baseBatch.vertexBuffer = &_vertexBuffer; baseBatch.indexBuffer = &_indexBuffer; baseBatch.vertexCount = _vertexCount; @@ -1212,6 +1215,9 @@ void VoxelBuffer::render(bool cursor) { if (!_materials.isEmpty()) { VoxelSplatBatch splatBatch; + splatBatch.translation = translation; + splatBatch.rotation = rotation; + splatBatch.scale = scale; splatBatch.vertexBuffer = &_vertexBuffer; splatBatch.indexBuffer = &_indexBuffer; splatBatch.vertexCount = _vertexCount; @@ -1948,7 +1954,7 @@ int BufferRenderVisitor::visit(MetavoxelInfo& info) { } BufferDataPointer buffer = info.inputValues.at(0).getInlineValue(); if (buffer) { - buffer->render(); + buffer->render(glm::vec3(), glm::quat(), glm::vec3(1.0f, 1.0f, 1.0f)); } return STOP_RECURSION; } @@ -2195,7 +2201,16 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - const QVector& heightContents = node->getHeight()->getContents(); + QVector heightContents = node->getHeight()->getContents(); + if (node->getStack()) { + // clear any height values covered by stacks + const QByteArray* src = node->getStack()->getContents().constData(); + for (quint16* dest = heightContents.data(), *end = dest + heightContents.size(); dest != end; dest++, src++) { + if (!src->isEmpty()) { + *dest = 0; + } + } + } glTexImage2D(GL_TEXTURE_2D, 0, GL_R16, width, height, 0, GL_RED, GL_UNSIGNED_SHORT, heightContents.constData()); @@ -2242,6 +2257,18 @@ void HeightfieldNodeRenderer::render(const HeightfieldNodePointer& node, const g } glBindTexture(GL_TEXTURE_2D, 0); } + if (!_voxels && node->getStack()) { + QVector vertices; + QVector indices; + QVector hermiteSegments; + QMultiHash quadIndices; + + _voxels = new VoxelBuffer(vertices, indices, hermiteSegments, quadIndices, width, node->getStack()->getMaterials()); + } + + if (_voxels) { + _voxels->render(translation, rotation, scale, cursor); + } if (cursor) { bufferPair.first.bind(); diff --git a/interface/src/MetavoxelSystem.h b/interface/src/MetavoxelSystem.h index 26f3bd68a3..c9a750ad3a 100644 --- a/interface/src/MetavoxelSystem.h +++ b/interface/src/MetavoxelSystem.h @@ -26,8 +26,8 @@ class HeightfieldBaseLayerBatch; class HeightfieldSplatBatch; class HermiteBatch; +class MetavoxelBatch; class Model; -class VoxelBatch; class VoxelSplatBatch; /// Renders a metavoxel tree. @@ -86,7 +86,7 @@ public: void addHeightfieldBaseBatch(const HeightfieldBaseLayerBatch& batch) { _heightfieldBaseBatches.append(batch); } void addHeightfieldSplatBatch(const HeightfieldSplatBatch& batch) { _heightfieldSplatBatches.append(batch); } - void addVoxelBaseBatch(const VoxelBatch& batch) { _voxelBaseBatches.append(batch); } + void addVoxelBaseBatch(const MetavoxelBatch& batch) { _voxelBaseBatches.append(batch); } void addVoxelSplatBatch(const VoxelSplatBatch& batch) { _voxelSplatBatches.append(batch); } void addHermiteBatch(const HermiteBatch& batch) { _hermiteBatches.append(batch); } @@ -123,7 +123,7 @@ private: QVector _heightfieldBaseBatches; QVector _heightfieldSplatBatches; - QVector _voxelBaseBatches; + QVector _voxelBaseBatches; QVector _voxelSplatBatches; QVector _hermiteBatches; @@ -166,8 +166,8 @@ private: static void loadSplatProgram(const char* type, ProgramObject& program, SplatLocations& locations); }; -/// Base class for heightfield batches. -class HeightfieldBatch { +/// Base class for all batches. +class MetavoxelBatch { public: QOpenGLBuffer* vertexBuffer; QOpenGLBuffer* indexBuffer; @@ -176,6 +176,11 @@ public: glm::vec3 scale; int vertexCount; int indexCount; +}; + +/// Base class for heightfield batches. +class HeightfieldBatch : public MetavoxelBatch { +public: GLuint heightTextureID; glm::vec4 heightScale; }; @@ -199,17 +204,8 @@ public: int materialIndex; }; -/// Base class for voxel batches. -class VoxelBatch { -public: - QOpenGLBuffer* vertexBuffer; - QOpenGLBuffer* indexBuffer; - int vertexCount; - int indexCount; -}; - /// A batch containing a voxel splat. -class VoxelSplatBatch : public VoxelBatch { +class VoxelSplatBatch : public MetavoxelBatch { public: int splatTextureIDs[4]; glm::vec4 splatTextureScalesS; @@ -295,7 +291,8 @@ public: virtual ~BufferData(); - virtual void render(bool cursor = false) = 0; + virtual void render(const glm::vec3& translation, const glm::quat& rotation, + const glm::vec3& scale, bool cursor = false) = 0; }; typedef QExplicitlySharedDataPointer BufferDataPointer; @@ -340,7 +337,8 @@ public: bool findFirstRayIntersection(const glm::vec3& entry, const glm::vec3& origin, const glm::vec3& direction, float& distance) const; - virtual void render(bool cursor = false); + virtual void render(const glm::vec3& translation, const glm::quat& rotation, + const glm::vec3& scale, bool cursor = false); private: @@ -460,6 +458,8 @@ private: GLuint _materialTextureID; QVector _networkTextures; + BufferDataPointer _voxels; + typedef QPair IntPair; typedef QPair BufferPair; static QHash _bufferPairs; diff --git a/libraries/metavoxels/src/Spanner.cpp b/libraries/metavoxels/src/Spanner.cpp index fa0f2590be..a976f56ae5 100644 --- a/libraries/metavoxels/src/Spanner.cpp +++ b/libraries/metavoxels/src/Spanner.cpp @@ -123,6 +123,11 @@ Spanner* Spanner::clearAndFetchHeight(const Box& bounds, SharedObjectPointer& he return this; } +Spanner* Spanner::sculptMaterial(const SharedObjectPointer& spanner, const SharedObjectPointer& material, + const QColor& color) { + return this; +} + bool Spanner::hasOwnColors() const { return false; } @@ -2239,6 +2244,11 @@ HeightfieldNode* HeightfieldNode::clearAndFetchHeight(const glm::vec3& translati return newNode; } +HeightfieldNode* HeightfieldNode::sculptMaterial(const SharedObjectPointer& spanner, const SharedObjectPointer& material, + const QColor& color) { + return this; +} + void HeightfieldNode::read(HeightfieldStreamState& state) { clearChildren(); @@ -2843,6 +2853,17 @@ Spanner* Heightfield::clearAndFetchHeight(const Box& bounds, SharedObjectPointer return newHeightfield; } +Spanner* Heightfield::sculptMaterial(const SharedObjectPointer& spanner, const SharedObjectPointer& material, + const QColor& color) { + HeightfieldNode* newRoot = _root->sculptMaterial(spanner, material, color); + if (_root == newRoot) { + return this; + } + Heightfield* newHeightfield = static_cast(clone(true)); + newHeightfield->setRoot(HeightfieldNodePointer(newRoot)); + return newHeightfield; +} + bool Heightfield::hasOwnColors() const { return _color; } diff --git a/libraries/metavoxels/src/Spanner.h b/libraries/metavoxels/src/Spanner.h index 6682f1e6dd..083dff3c5f 100644 --- a/libraries/metavoxels/src/Spanner.h +++ b/libraries/metavoxels/src/Spanner.h @@ -86,6 +86,11 @@ public: /// \return the modified spanner, or this if no modification was performed virtual Spanner* clearAndFetchHeight(const Box& bounds, SharedObjectPointer& heightfield); + /// Attempts to "sculpt" with the supplied spanner. + /// \return the modified spanner, or this if no modification was performed + virtual Spanner* sculptMaterial(const SharedObjectPointer& spanner, const SharedObjectPointer& material, + const QColor& color); + /// Checks whether this spanner has its own colors. virtual bool hasOwnColors() const; @@ -577,6 +582,9 @@ public: HeightfieldNode* clearAndFetchHeight(const glm::vec3& translation, const glm::quat& rotation, const glm::vec3& scale, const Box& bounds, SharedObjectPointer& heightfield); + + HeightfieldNode* sculptMaterial(const SharedObjectPointer& spanner, const SharedObjectPointer& material, + const QColor& color); void read(HeightfieldStreamState& state); void write(HeightfieldStreamState& state) const; @@ -671,6 +679,9 @@ public: virtual Spanner* clearAndFetchHeight(const Box& bounds, SharedObjectPointer& heightfield); + virtual Spanner* sculptMaterial(const SharedObjectPointer& spanner, const SharedObjectPointer& material, + const QColor& color); + virtual bool hasOwnColors() const; virtual bool hasOwnMaterials() const; virtual QRgb getColorAt(const glm::vec3& point);