From aeee3692868aabc99b39e68f635d957032d69794 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 28 Jul 2014 19:10:59 -0700 Subject: [PATCH] Working on heightfield implementation. --- .../shaders/metavoxel_heightfield.frag | 16 ++ .../shaders/metavoxel_heightfield.vert | 16 ++ interface/src/MetavoxelSystem.cpp | 250 ++++++++++++------ interface/src/MetavoxelSystem.h | 53 +++- .../metavoxels/src/AttributeRegistry.cpp | 28 +- libraries/metavoxels/src/AttributeRegistry.h | 45 ++++ libraries/metavoxels/src/MetavoxelData.cpp | 15 +- libraries/metavoxels/src/MetavoxelData.h | 7 +- 8 files changed, 337 insertions(+), 93 deletions(-) create mode 100644 interface/resources/shaders/metavoxel_heightfield.frag create mode 100644 interface/resources/shaders/metavoxel_heightfield.vert diff --git a/interface/resources/shaders/metavoxel_heightfield.frag b/interface/resources/shaders/metavoxel_heightfield.frag new file mode 100644 index 0000000000..de520d57ac --- /dev/null +++ b/interface/resources/shaders/metavoxel_heightfield.frag @@ -0,0 +1,16 @@ +#version 120 + +// +// metavoxel_heightfield.frag +// fragment shader +// +// Created by Andrzej Kapolka on 7/28/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +void main(void) { + gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); +} diff --git a/interface/resources/shaders/metavoxel_heightfield.vert b/interface/resources/shaders/metavoxel_heightfield.vert new file mode 100644 index 0000000000..6b90bdc44d --- /dev/null +++ b/interface/resources/shaders/metavoxel_heightfield.vert @@ -0,0 +1,16 @@ +#version 120 + +// +// metavoxel_heighfield.vert +// vertex shader +// +// Created by Andrzej Kapolka on 7/28/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +void main(void) { + gl_Position = ftransform(); +} diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index 00d69c8c25..318bf65614 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -25,7 +25,7 @@ #include "MetavoxelSystem.h" #include "renderer/Model.h" -REGISTER_META_OBJECT(PointMetavoxelRendererImplementation) +REGISTER_META_OBJECT(DefaultMetavoxelRendererImplementation) REGISTER_META_OBJECT(SphereRenderer) REGISTER_META_OBJECT(StaticModelRenderer) @@ -33,8 +33,10 @@ static int bufferPointVectorMetaTypeId = qRegisterMetaType(); void MetavoxelSystem::init() { MetavoxelClientManager::init(); - PointMetavoxelRendererImplementation::init(); - _pointBufferAttribute = AttributeRegistry::getInstance()->registerAttribute(new PointBufferAttribute()); + DefaultMetavoxelRendererImplementation::init(); + _pointBufferAttribute = AttributeRegistry::getInstance()->registerAttribute(new BufferDataAttribute("pointBuffer")); + _heightfieldBufferAttribute = AttributeRegistry::getInstance()->registerAttribute( + new BufferDataAttribute("heightfieldBuffer")); } MetavoxelLOD MetavoxelSystem::getLOD() { @@ -42,28 +44,31 @@ MetavoxelLOD MetavoxelSystem::getLOD() { return _lod; } -class SpannerSimulateVisitor : public SpannerVisitor { +class SimulateVisitor : public MetavoxelVisitor { public: - SpannerSimulateVisitor(float deltaTime); + SimulateVisitor(float deltaTime, const MetavoxelLOD& lod); - virtual bool visit(Spanner* spanner, const glm::vec3& clipMinimum, float clipSize); + virtual int visit(MetavoxelInfo& info); private: float _deltaTime; }; -SpannerSimulateVisitor::SpannerSimulateVisitor(float deltaTime) : - SpannerVisitor(QVector() << AttributeRegistry::getInstance()->getSpannersAttribute(), - QVector(), QVector(), QVector(), - Application::getInstance()->getMetavoxels()->getLOD()), +SimulateVisitor::SimulateVisitor(float deltaTime, const MetavoxelLOD& lod) : + MetavoxelVisitor(QVector() << AttributeRegistry::getInstance()->getRendererAttribute(), + QVector(), lod), _deltaTime(deltaTime) { } -bool SpannerSimulateVisitor::visit(Spanner* spanner, const glm::vec3& clipMinimum, float clipSize) { - spanner->getRenderer()->simulate(_deltaTime); - return true; +int SimulateVisitor::visit(MetavoxelInfo& info) { + if (!info.isLeaf) { + return DEFAULT_ORDER; + } + static_cast(info.inputValues.at(0).getInlineValue< + SharedObjectPointer>().data())->getImplementation()->simulate(*_data, _deltaTime, info, _lod); + return STOP_RECURSION; } void MetavoxelSystem::simulate(float deltaTime) { @@ -76,28 +81,8 @@ void MetavoxelSystem::simulate(float deltaTime) { BASE_LOD_THRESHOLD * Menu::getInstance()->getAvatarLODDistanceMultiplier()); } - SpannerSimulateVisitor spannerSimulateVisitor(deltaTime); - guide(spannerSimulateVisitor); -} - -class SpannerRenderVisitor : public SpannerVisitor { -public: - - SpannerRenderVisitor(); - - virtual bool visit(Spanner* spanner, const glm::vec3& clipMinimum, float clipSize); -}; - -SpannerRenderVisitor::SpannerRenderVisitor() : - SpannerVisitor(QVector() << AttributeRegistry::getInstance()->getSpannersAttribute(), - QVector(), QVector(), QVector(), - Application::getInstance()->getMetavoxels()->getLOD(), - encodeOrder(Application::getInstance()->getViewFrustum()->getDirection())) { -} - -bool SpannerRenderVisitor::visit(Spanner* spanner, const glm::vec3& clipMinimum, float clipSize) { - spanner->getRenderer()->render(1.0f, SpannerRenderer::DEFAULT_MODE, clipMinimum, clipSize); - return true; + SimulateVisitor simulateVisitor(deltaTime, getLOD()); + guideToAugmented(simulateVisitor); } class RenderVisitor : public MetavoxelVisitor { @@ -125,9 +110,6 @@ int RenderVisitor::visit(MetavoxelInfo& info) { void MetavoxelSystem::render() { RenderVisitor renderVisitor(getLOD()); guideToAugmented(renderVisitor); - - SpannerRenderVisitor spannerRenderVisitor; - guide(spannerRenderVisitor); } MetavoxelClient* MetavoxelSystem::createClient(const SharedNodePointer& node) { @@ -239,6 +221,9 @@ void MetavoxelSystemClient::sendDatagram(const QByteArray& data) { Application::getInstance()->getBandwidthMeter()->outputStream(BandwidthMeter::METAVOXELS).updateValue(data.size()); } +BufferData::~BufferData() { +} + PointBuffer::PointBuffer(const BufferPointVector& points) : _points(points) { } @@ -269,34 +254,76 @@ void PointBuffer::render() { _buffer.release(); } -PointBufferAttribute::PointBufferAttribute() : - InlineAttribute("pointBuffer") { +HeightfieldBuffer::HeightfieldBuffer(const QByteArray& height, const QByteArray& color, const QByteArray& normal) : + _height(height), + _color(color), + _normal(normal), + _heightTexture(QOpenGLTexture::Target2D), + _colorTexture(QOpenGLTexture::Target2D), + _normalTexture(QOpenGLTexture::Target2D) { } -bool PointBufferAttribute::merge(void*& parent, void* children[], bool postRead) const { - PointBufferPointer firstChild = decodeInline(children[0]); +void HeightfieldBuffer::render() { + // initialize textures, etc. on first render + if (!_heightTexture.isCreated()) { + int heightSize = glm::sqrt(_height.size()); + _heightTexture.setSize(heightSize, heightSize); + _heightTexture.setFormat(QOpenGLTexture::LuminanceFormat); + _heightTexture.allocateStorage(); + _heightTexture.setData(QOpenGLTexture::Luminance, QOpenGLTexture::UInt8, _height.data()); + _height.clear(); + + int colorSize = glm::sqrt(_color.size() / 3); + _colorTexture.setSize(colorSize, colorSize); + _colorTexture.setFormat(QOpenGLTexture::RGBFormat); + _colorTexture.allocateStorage(); + _colorTexture.setData(QOpenGLTexture::BGR, QOpenGLTexture::UInt8, _color.data()); + _color.clear(); + + int normalSize = glm::sqrt(_normal.size() / 3); + _normalTexture.setSize(normalSize, normalSize); + _normalTexture.setFormat(QOpenGLTexture::RGBFormat); + _normalTexture.allocateStorage(); + _normalTexture.setData(QOpenGLTexture::BGR, QOpenGLTexture::UInt8, _normal.data()); + _normal.clear(); + } + +} + +BufferDataAttribute::BufferDataAttribute(const QString& name) : + InlineAttribute(name) { +} + +bool BufferDataAttribute::merge(void*& parent, void* children[], bool postRead) const { + BufferDataPointer firstChild = decodeInline(children[0]); for (int i = 1; i < MERGE_COUNT; i++) { - if (firstChild != decodeInline(children[i])) { - *(PointBufferPointer*)&parent = _defaultValue; + if (firstChild != decodeInline(children[i])) { + *(BufferDataPointer*)&parent = _defaultValue; return false; } } - *(PointBufferPointer*)&parent = firstChild; + *(BufferDataPointer*)&parent = firstChild; return true; } -void PointMetavoxelRendererImplementation::init() { - if (!_program.isLinked()) { - _program.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/metavoxel_point.vert"); - _program.link(); +void DefaultMetavoxelRendererImplementation::init() { + if (!_pointProgram.isLinked()) { + _pointProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + "shaders/metavoxel_point.vert"); + _pointProgram.link(); - _program.bind(); - _pointScaleLocation = _program.uniformLocation("pointScale"); - _program.release(); + _pointProgram.bind(); + _pointScaleLocation = _pointProgram.uniformLocation("pointScale"); + _pointProgram.release(); + + _heightfieldProgram.addShaderFromSourceFile(QGLShader::Vertex, Application::resourcesPath() + + "shaders/metavoxel_heightfield.vert"); + _heightfieldProgram.addShaderFromSourceFile(QGLShader::Fragment, Application::resourcesPath() + + "shaders/metavoxel_heightfield.frag"); + _heightfieldProgram.link(); } } -PointMetavoxelRendererImplementation::PointMetavoxelRendererImplementation() { +DefaultMetavoxelRendererImplementation::DefaultMetavoxelRendererImplementation() { } class PointAugmentVisitor : public MetavoxelVisitor { @@ -344,7 +371,7 @@ int PointAugmentVisitor::visit(MetavoxelInfo& info) { if (info.size >= _pointLeafSize) { BufferPointVector swapPoints; _points.swap(swapPoints); - info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(PointBufferPointer( + info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer( new PointBuffer(swapPoints)))); } return STOP_RECURSION; @@ -356,12 +383,30 @@ bool PointAugmentVisitor::postVisit(MetavoxelInfo& info) { } BufferPointVector swapPoints; _points.swap(swapPoints); - info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(PointBufferPointer( + info.outputValues[0] = AttributeValue(_outputs.at(0), encodeInline(BufferDataPointer( new PointBuffer(swapPoints)))); return true; } -void PointMetavoxelRendererImplementation::augment(MetavoxelData& data, const MetavoxelData& previous, +class HeightfieldAugmentVisitor : public MetavoxelVisitor { +public: + + HeightfieldAugmentVisitor(const MetavoxelLOD& lod); + + virtual int visit(MetavoxelInfo& info); +}; + +HeightfieldAugmentVisitor::HeightfieldAugmentVisitor(const MetavoxelLOD& lod) : + MetavoxelVisitor(QVector() << AttributeRegistry::getInstance()->getHeightfieldAttribute() << + AttributeRegistry::getInstance()->getHeightfieldColorAttribute(), QVector() << + Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), lod) { +} + +int HeightfieldAugmentVisitor::visit(MetavoxelInfo& info) { + return STOP_RECURSION; +} + +void DefaultMetavoxelRendererImplementation::augment(MetavoxelData& data, const MetavoxelData& previous, MetavoxelInfo& info, const MetavoxelLOD& lod) { // copy the previous buffers MetavoxelData expandedPrevious = previous; @@ -377,12 +422,62 @@ void PointMetavoxelRendererImplementation::augment(MetavoxelData& data, const Me PointAugmentVisitor visitor(lod); data.guideToDifferent(expandedPrevious, visitor); + + } -class PointRenderVisitor : public MetavoxelVisitor { +class SpannerSimulateVisitor : public SpannerVisitor { public: - PointRenderVisitor(const MetavoxelLOD& lod); + SpannerSimulateVisitor(float deltaTime, const MetavoxelLOD& lod); + + virtual bool visit(Spanner* spanner, const glm::vec3& clipMinimum, float clipSize); + +private: + + float _deltaTime; +}; + +SpannerSimulateVisitor::SpannerSimulateVisitor(float deltaTime, const MetavoxelLOD& lod) : + SpannerVisitor(QVector() << AttributeRegistry::getInstance()->getSpannersAttribute(), + QVector(), QVector(), QVector(), lod), + _deltaTime(deltaTime) { +} + +bool SpannerSimulateVisitor::visit(Spanner* spanner, const glm::vec3& clipMinimum, float clipSize) { + spanner->getRenderer()->simulate(_deltaTime); + return true; +} + +void DefaultMetavoxelRendererImplementation::simulate(MetavoxelData& data, float deltaTime, + MetavoxelInfo& info, const MetavoxelLOD& lod) { + SpannerSimulateVisitor spannerSimulateVisitor(deltaTime, lod); + data.guide(spannerSimulateVisitor); +} + +class SpannerRenderVisitor : public SpannerVisitor { +public: + + SpannerRenderVisitor(const MetavoxelLOD& lod); + + virtual bool visit(Spanner* spanner, const glm::vec3& clipMinimum, float clipSize); +}; + +SpannerRenderVisitor::SpannerRenderVisitor(const MetavoxelLOD& lod) : + SpannerVisitor(QVector() << AttributeRegistry::getInstance()->getSpannersAttribute(), + QVector(), QVector(), QVector(), + lod, encodeOrder(Application::getInstance()->getViewFrustum()->getDirection())) { +} + +bool SpannerRenderVisitor::visit(Spanner* spanner, const glm::vec3& clipMinimum, float clipSize) { + spanner->getRenderer()->render(1.0f, SpannerRenderer::DEFAULT_MODE, clipMinimum, clipSize); + return true; +} + +class BufferRenderVisitor : public MetavoxelVisitor { +public: + + BufferRenderVisitor(const AttributePointer& attribute, const MetavoxelLOD& lod); virtual int visit(MetavoxelInfo& info); @@ -391,21 +486,23 @@ private: int _order; }; -PointRenderVisitor::PointRenderVisitor(const MetavoxelLOD& lod) : - MetavoxelVisitor(QVector() << Application::getInstance()->getMetavoxels()->getPointBufferAttribute(), - QVector(), lod), +BufferRenderVisitor::BufferRenderVisitor(const AttributePointer& attribute, const MetavoxelLOD& lod) : + MetavoxelVisitor(QVector() << attribute, QVector(), lod), _order(encodeOrder(Application::getInstance()->getViewFrustum()->getDirection())) { } -int PointRenderVisitor::visit(MetavoxelInfo& info) { - PointBufferPointer buffer = info.inputValues.at(0).getInlineValue(); +int BufferRenderVisitor::visit(MetavoxelInfo& info) { + BufferDataPointer buffer = info.inputValues.at(0).getInlineValue(); if (buffer) { buffer->render(); } return info.isLeaf ? STOP_RECURSION : _order; } -void PointMetavoxelRendererImplementation::render(MetavoxelData& data, MetavoxelInfo& info, const MetavoxelLOD& lod) { +void DefaultMetavoxelRendererImplementation::render(MetavoxelData& data, MetavoxelInfo& info, const MetavoxelLOD& lod) { + SpannerRenderVisitor spannerRenderVisitor(lod); + data.guide(spannerRenderVisitor); + int viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); const int VIEWPORT_WIDTH_INDEX = 2; @@ -416,8 +513,8 @@ void PointMetavoxelRendererImplementation::render(MetavoxelData& data, Metavoxel float worldDiagonal = glm::distance(Application::getInstance()->getViewFrustum()->getNearBottomLeft(), Application::getInstance()->getViewFrustum()->getNearTopRight()); - _program.bind(); - _program.setUniformValue(_pointScaleLocation, viewportDiagonal * + _pointProgram.bind(); + _pointProgram.setUniformValue(_pointScaleLocation, viewportDiagonal * Application::getInstance()->getViewFrustum()->getNearClip() / worldDiagonal); glEnableClientState(GL_VERTEX_ARRAY); @@ -428,10 +525,8 @@ void PointMetavoxelRendererImplementation::render(MetavoxelData& data, Metavoxel glDisable(GL_BLEND); - PointRenderVisitor visitor(lod); - data.guide(visitor); - - glEnable(GL_BLEND); + BufferRenderVisitor pointRenderVisitor(Application::getInstance()->getMetavoxels()->getPointBufferAttribute(), lod); + data.guide(pointRenderVisitor); glDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB); @@ -439,11 +534,18 @@ void PointMetavoxelRendererImplementation::render(MetavoxelData& data, Metavoxel glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); - _program.release(); + _pointProgram.release(); + + BufferRenderVisitor heightfieldRenderVisitor(Application::getInstance()->getMetavoxels()->getHeightfieldBufferAttribute(), + lod); + data.guide(heightfieldRenderVisitor); + + glEnable(GL_BLEND); } - -ProgramObject PointMetavoxelRendererImplementation::_program; -int PointMetavoxelRendererImplementation::_pointScaleLocation; + +ProgramObject DefaultMetavoxelRendererImplementation::_pointProgram; +int DefaultMetavoxelRendererImplementation::_pointScaleLocation; +ProgramObject DefaultMetavoxelRendererImplementation::_heightfieldProgram; static void enableClipPlane(GLenum plane, float x, float y, float z, float w) { GLdouble coefficients[] = { x, y, z, w }; diff --git a/interface/src/MetavoxelSystem.h b/interface/src/MetavoxelSystem.h index 4a5b99aa47..be1a02643f 100644 --- a/interface/src/MetavoxelSystem.h +++ b/interface/src/MetavoxelSystem.h @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -36,6 +37,7 @@ public: virtual MetavoxelLOD getLOD(); const AttributePointer& getPointBufferAttribute() { return _pointBufferAttribute; } + const AttributePointer& getHeightfieldBufferAttribute() { return _heightfieldBufferAttribute; } void simulate(float deltaTime); void render(); @@ -49,6 +51,7 @@ private: void guideToAugmented(MetavoxelVisitor& visitor); AttributePointer _pointBufferAttribute; + AttributePointer _heightfieldBufferAttribute; MetavoxelLOD _lod; QReadWriteLock _lodLock; @@ -92,13 +95,24 @@ private: QReadWriteLock _augmentedDataLock; }; +/// Base class for cached static buffers. +class BufferData : public QSharedData { +public: + + virtual ~BufferData(); + + virtual void render() = 0; +}; + +typedef QExplicitlySharedDataPointer BufferDataPointer; + /// Contains the information necessary to render a group of points. -class PointBuffer : public QSharedData { +class PointBuffer : public BufferData { public: PointBuffer(const BufferPointVector& points); - void render(); + virtual void render(); private: @@ -107,36 +121,55 @@ private: int _pointCount; }; -typedef QExplicitlySharedDataPointer PointBufferPointer; +/// Contains the information necessary to render a heightfield block. +class HeightfieldBuffer : public BufferData { +public: + + HeightfieldBuffer(const QByteArray& height, const QByteArray& color, const QByteArray& normal); + + virtual void render(); -/// A client-side attribute that stores point buffers. -class PointBufferAttribute : public InlineAttribute { +private: + + QByteArray _height; + QByteArray _color; + QByteArray _normal; + QOpenGLTexture _heightTexture; + QOpenGLTexture _colorTexture; + QOpenGLTexture _normalTexture; +}; + +/// A client-side attribute that stores renderable buffers. +class BufferDataAttribute : public InlineAttribute { Q_OBJECT public: - Q_INVOKABLE PointBufferAttribute(); + Q_INVOKABLE BufferDataAttribute(const QString& name = QString()); virtual bool merge(void*& parent, void* children[], bool postRead = false) const; }; /// Renders metavoxels as points. -class PointMetavoxelRendererImplementation : public MetavoxelRendererImplementation { +class DefaultMetavoxelRendererImplementation : public MetavoxelRendererImplementation { Q_OBJECT public: static void init(); - Q_INVOKABLE PointMetavoxelRendererImplementation(); + Q_INVOKABLE DefaultMetavoxelRendererImplementation(); virtual void augment(MetavoxelData& data, const MetavoxelData& previous, MetavoxelInfo& info, const MetavoxelLOD& lod); + virtual void simulate(MetavoxelData& data, float deltaTime, MetavoxelInfo& info, const MetavoxelLOD& lod); virtual void render(MetavoxelData& data, MetavoxelInfo& info, const MetavoxelLOD& lod); private: - static ProgramObject _program; - static int _pointScaleLocation; + static ProgramObject _pointProgram; + static int _pointScaleLocation; + + static ProgramObject _heightfieldProgram; }; /// Base class for spanner renderers; provides clipping. diff --git a/libraries/metavoxels/src/AttributeRegistry.cpp b/libraries/metavoxels/src/AttributeRegistry.cpp index 7c7ded0fb7..4f4da7adf2 100644 --- a/libraries/metavoxels/src/AttributeRegistry.cpp +++ b/libraries/metavoxels/src/AttributeRegistry.cpp @@ -21,6 +21,8 @@ REGISTER_META_OBJECT(QRgbAttribute) REGISTER_META_OBJECT(PackedNormalAttribute) REGISTER_META_OBJECT(SpannerQRgbAttribute) REGISTER_META_OBJECT(SpannerPackedNormalAttribute) +REGISTER_META_OBJECT(HeightfieldAttribute) +REGISTER_META_OBJECT(HeightfieldColorAttribute) REGISTER_META_OBJECT(SharedObjectAttribute) REGISTER_META_OBJECT(SharedObjectSetAttribute) REGISTER_META_OBJECT(SpannerSetAttribute) @@ -37,13 +39,15 @@ AttributeRegistry::AttributeRegistry() : _guideAttribute(registerAttribute(new SharedObjectAttribute("guide", &MetavoxelGuide::staticMetaObject, new DefaultMetavoxelGuide()))), _rendererAttribute(registerAttribute(new SharedObjectAttribute("renderer", &MetavoxelRenderer::staticMetaObject, - new PointMetavoxelRenderer()))), + new DefaultMetavoxelRenderer()))), _spannersAttribute(registerAttribute(new SpannerSetAttribute("spanners", &Spanner::staticMetaObject))), _colorAttribute(registerAttribute(new QRgbAttribute("color"))), _normalAttribute(registerAttribute(new PackedNormalAttribute("normal"))), _spannerColorAttribute(registerAttribute(new SpannerQRgbAttribute("spannerColor"))), _spannerNormalAttribute(registerAttribute(new SpannerPackedNormalAttribute("spannerNormal"))), - _spannerMaskAttribute(registerAttribute(new FloatAttribute("spannerMask"))) { + _spannerMaskAttribute(registerAttribute(new FloatAttribute("spannerMask"))), + _heightfieldAttribute(registerAttribute(new HeightfieldAttribute("heightfield"))), + _heightfieldColorAttribute(registerAttribute(new HeightfieldColorAttribute("heightfieldColor"))) { // our baseline LOD threshold is for voxels; spanners are a different story const float SPANNER_LOD_THRESHOLD_MULTIPLIER = 8.0f; @@ -451,6 +455,26 @@ AttributeValue SpannerPackedNormalAttribute::inherit(const AttributeValue& paren return AttributeValue(parentValue.getAttribute()); } +HeightfieldData::HeightfieldData(const QByteArray& contents) : + _contents(contents) { +} + +HeightfieldAttribute::HeightfieldAttribute(const QString& name) : + InlineAttribute(name) { +} + +bool HeightfieldAttribute::merge(void*& parent, void* children[], bool postRead) const { + return false; +} + +HeightfieldColorAttribute::HeightfieldColorAttribute(const QString& name) : + InlineAttribute(name) { +} + +bool HeightfieldColorAttribute::merge(void*& parent, void* children[], bool postRead) const { + return false; +} + SharedObjectAttribute::SharedObjectAttribute(const QString& name, const QMetaObject* metaObject, const SharedObjectPointer& defaultValue) : InlineAttribute(name, defaultValue), diff --git a/libraries/metavoxels/src/AttributeRegistry.h b/libraries/metavoxels/src/AttributeRegistry.h index d07503335f..262ef89462 100644 --- a/libraries/metavoxels/src/AttributeRegistry.h +++ b/libraries/metavoxels/src/AttributeRegistry.h @@ -94,6 +94,12 @@ public: /// Returns a reference to the standard "spannerMask" attribute. const AttributePointer& getSpannerMaskAttribute() const { return _spannerMaskAttribute; } + /// Returns a reference to the standard HeightfieldPointer "heightfield" attribute. + const AttributePointer& getHeightfieldAttribute() const { return _heightfieldAttribute; } + + /// Returns a reference to the standard HeightfieldColorPointer "heightfieldColor" attribute. + const AttributePointer& getHeightfieldColorAttribute() const { return _heightfieldColorAttribute; } + private: static QScriptValue getAttribute(QScriptContext* context, QScriptEngine* engine); @@ -109,6 +115,8 @@ private: AttributePointer _spannerColorAttribute; AttributePointer _spannerNormalAttribute; AttributePointer _spannerMaskAttribute; + AttributePointer _heightfieldAttribute; + AttributePointer _heightfieldColorAttribute; }; /// Converts a value to a void pointer. @@ -408,6 +416,43 @@ public: virtual AttributeValue inherit(const AttributeValue& parentValue) const; }; +/// Contains a block of heightfield data. +class HeightfieldData : public QSharedData { +public: + + HeightfieldData(const QByteArray& contents); + + const QByteArray& getContents() const { return _contents; } + +private: + + QByteArray _contents; +}; + +typedef QExplicitlySharedDataPointer HeightfieldDataPointer; + +/// An attribute that stores heightfield data. +class HeightfieldAttribute : public InlineAttribute { + Q_OBJECT + +public: + + Q_INVOKABLE HeightfieldAttribute(const QString& name = QString()); + + virtual bool merge(void*& parent, void* children[], bool postRead = false) const; +}; + +/// An attribute that stores heightfield colors. +class HeightfieldColorAttribute : public InlineAttribute { + Q_OBJECT + +public: + + Q_INVOKABLE HeightfieldColorAttribute(const QString& name = QString()); + + virtual bool merge(void*& parent, void* children[], bool postRead = false) const; +}; + /// An attribute that takes the form of QObjects of a given meta-type (a subclass of SharedObject). class SharedObjectAttribute : public InlineAttribute { Q_OBJECT diff --git a/libraries/metavoxels/src/MetavoxelData.cpp b/libraries/metavoxels/src/MetavoxelData.cpp index 3bf43ef8d4..29f18f5cc1 100644 --- a/libraries/metavoxels/src/MetavoxelData.cpp +++ b/libraries/metavoxels/src/MetavoxelData.cpp @@ -26,7 +26,7 @@ REGISTER_META_OBJECT(DefaultMetavoxelGuide) REGISTER_META_OBJECT(ScriptedMetavoxelGuide) REGISTER_META_OBJECT(ThrobbingMetavoxelGuide) REGISTER_META_OBJECT(MetavoxelRenderer) -REGISTER_META_OBJECT(PointMetavoxelRenderer) +REGISTER_META_OBJECT(DefaultMetavoxelRenderer) REGISTER_META_OBJECT(Spanner) REGISTER_META_OBJECT(Sphere) REGISTER_META_OBJECT(StaticModel) @@ -1879,20 +1879,27 @@ void MetavoxelRendererImplementation::init(MetavoxelRenderer* renderer) { void MetavoxelRendererImplementation::augment(MetavoxelData& data, const MetavoxelData& previous, MetavoxelInfo& info, const MetavoxelLOD& lod) { + // nothing by default +} + +void MetavoxelRendererImplementation::simulate(MetavoxelData& data, float deltaTime, + MetavoxelInfo& info, const MetavoxelLOD& lod) { + // nothing by default } void MetavoxelRendererImplementation::render(MetavoxelData& data, MetavoxelInfo& info, const MetavoxelLOD& lod) { + // nothing by default } QByteArray MetavoxelRenderer::getImplementationClassName() const { return "MetavoxelRendererImplementation"; } -PointMetavoxelRenderer::PointMetavoxelRenderer() { +DefaultMetavoxelRenderer::DefaultMetavoxelRenderer() { } -QByteArray PointMetavoxelRenderer::getImplementationClassName() const { - return "PointMetavoxelRendererImplementation"; +QByteArray DefaultMetavoxelRenderer::getImplementationClassName() const { + return "DefaultMetavoxelRendererImplementation"; } const float DEFAULT_PLACEMENT_GRANULARITY = 0.01f; diff --git a/libraries/metavoxels/src/MetavoxelData.h b/libraries/metavoxels/src/MetavoxelData.h index 2dc778cf71..46376601c1 100644 --- a/libraries/metavoxels/src/MetavoxelData.h +++ b/libraries/metavoxels/src/MetavoxelData.h @@ -555,6 +555,7 @@ public: virtual void init(MetavoxelRenderer* renderer); virtual void augment(MetavoxelData& data, const MetavoxelData& previous, MetavoxelInfo& info, const MetavoxelLOD& lod); + virtual void simulate(MetavoxelData& data, float deltaTime, MetavoxelInfo& info, const MetavoxelLOD& lod); virtual void render(MetavoxelData& data, MetavoxelInfo& info, const MetavoxelLOD& lod); protected: @@ -562,13 +563,13 @@ protected: MetavoxelRenderer* _renderer; }; -/// Renders metavoxels as points. -class PointMetavoxelRenderer : public MetavoxelRenderer { +/// The standard, usual renderer. +class DefaultMetavoxelRenderer : public MetavoxelRenderer { Q_OBJECT public: - Q_INVOKABLE PointMetavoxelRenderer(); + Q_INVOKABLE DefaultMetavoxelRenderer(); virtual QByteArray getImplementationClassName() const; };