//// MetavoxelSystem.h// interface/src//// Created by Andrzej Kapolka on 12/10/13.// Copyright 2013 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// #ifndef hifi_MetavoxelSystem_h#define hifi_MetavoxelSystem_h #include <QList>#include <QOpenGLBuffer>#include <QReadWriteLock>#include <QVector> #include <glm/glm.hpp> #include <MetavoxelClientManager.h> #include "renderer/ProgramObject.h" class HeightfieldBaseLayerBatch;class HeightfieldSplatBatch;class HermiteBatch;class Model;class VoxelBatch;class VoxelSplatBatch; /// Renders a metavoxel tree.class MetavoxelSystem : public MetavoxelClientManager { Q_OBJECT public: class NetworkSimulation { public: float dropRate; float repeatRate; int minimumDelay; int maximumDelay; int bandwidthLimit; NetworkSimulation(float dropRate = 0.0f, float repeatRate = 0.0f, int minimumDelay = 0, int maximumDelay = 0, int bandwidthLimit = 0); }; virtual ~MetavoxelSystem(); virtual void init(); virtual MetavoxelLOD getLOD(); const Frustum& getFrustum() const { return _frustum; } void setNetworkSimulation(const NetworkSimulation& simulation); NetworkSimulation getNetworkSimulation(); const AttributePointer& getHeightfieldBufferAttribute() { return _heightfieldBufferAttribute; } const AttributePointer& getVoxelBufferAttribute() { return _voxelBufferAttribute; } void simulate(float deltaTime); void render(); void renderHeightfieldCursor(const glm::vec3& position, float radius); void renderVoxelCursor(const glm::vec3& position, float radius); bool findFirstRayVoxelIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance); Q_INVOKABLE void paintHeightfieldColor(const glm::vec3& position, float radius, const QColor& color); Q_INVOKABLE void paintHeightfieldMaterial(const glm::vec3& position, float radius, const SharedObjectPointer& material); Q_INVOKABLE void paintVoxelColor(const glm::vec3& position, float radius, const QColor& color); Q_INVOKABLE void paintVoxelMaterial(const glm::vec3& position, float radius, const SharedObjectPointer& material); Q_INVOKABLE void setVoxelColor(const SharedObjectPointer& spanner, const QColor& color); Q_INVOKABLE void setVoxelMaterial(const SharedObjectPointer& spanner, const SharedObjectPointer& material); 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 addVoxelSplatBatch(const VoxelSplatBatch& batch) { _voxelSplatBatches.append(batch); } void addHermiteBatch(const HermiteBatch& batch) { _hermiteBatches.append(batch); } Q_INVOKABLE void deleteTextures(int heightTextureID, int colorTextureID, int materialTextureID) const; signals: void rendering(); public slots: void refreshVoxelData(); protected: Q_INVOKABLE void applyMaterialEdit(const MetavoxelEditMessage& message, bool reliable = false); virtual MetavoxelClient* createClient(const SharedNodePointer& node); private: void guideToAugmented(MetavoxelVisitor& visitor, bool render = false); AttributePointer _heightfieldBufferAttribute; AttributePointer _voxelBufferAttribute; MetavoxelLOD _lod; QReadWriteLock _lodLock; Frustum _frustum; NetworkSimulation _networkSimulation; QReadWriteLock _networkSimulationLock; QVector<HeightfieldBaseLayerBatch> _heightfieldBaseBatches; QVector<HeightfieldSplatBatch> _heightfieldSplatBatches; QVector<VoxelBatch> _voxelBaseBatches; QVector<VoxelSplatBatch> _voxelSplatBatches; QVector<HermiteBatch> _hermiteBatches; ProgramObject _baseHeightfieldProgram; int _baseHeightScaleLocation; int _baseColorScaleLocation; class SplatLocations { public: int heightScale; int textureScale; int splatTextureOffset; int splatTextureScalesS; int splatTextureScalesT; int textureValueMinima; int textureValueMaxima; int materials; int materialWeights; }; ProgramObject _splatHeightfieldProgram; SplatLocations _splatHeightfieldLocations; int _splatHeightScaleLocation; int _splatTextureScaleLocation; int _splatTextureOffsetLocation; int _splatTextureScalesSLocation; int _splatTextureScalesTLocation; int _splatTextureValueMinimaLocation; int _splatTextureValueMaximaLocation; ProgramObject _heightfieldCursorProgram; ProgramObject _baseVoxelProgram; ProgramObject _splatVoxelProgram; SplatLocations _splatVoxelLocations; ProgramObject _voxelCursorProgram; static void loadSplatProgram(const char* type, ProgramObject& program, SplatLocations& locations);}; /// Base class for heightfield batches.class HeightfieldBatch {public: QOpenGLBuffer* vertexBuffer; QOpenGLBuffer* indexBuffer; glm::vec3 translation; glm::quat rotation; glm::vec3 scale; int vertexCount; int indexCount; GLuint heightTextureID; glm::vec4 heightScale;}; /// A batch containing a heightfield base layer. class HeightfieldBaseLayerBatch : public HeightfieldBatch {public: GLuint colorTextureID; glm::vec2 colorScale;}; /// A batch containing a heightfield splat.class HeightfieldSplatBatch : public HeightfieldBatch {public: GLuint materialTextureID; glm::vec2 textureScale; glm::vec2 splatTextureOffset; int splatTextureIDs[4]; glm::vec4 splatTextureScalesS; glm::vec4 splatTextureScalesT; 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 {public: int splatTextureIDs[4]; glm::vec4 splatTextureScalesS; glm::vec4 splatTextureScalesT; int materialIndex;}; /// A batch containing Hermite data for debugging.class HermiteBatch {public: QOpenGLBuffer* vertexBuffer; int vertexCount;}; /// Generic abstract base class for objects that handle a signal.class SignalHandler : public QObject { Q_OBJECT public slots: virtual void handle() = 0;}; /// Simple throttle for limiting bandwidth on a per-second basis.class Throttle {public: Throttle(); /// Sets the per-second limit. void setLimit(int limit) { _limit = limit; } /// Determines whether the message with the given size should be throttled (discarded). If not, registers the message /// as having been processed (i.e., contributing to later throttling). bool shouldThrottle(int bytes); private: int _limit; int _total; typedef QPair<qint64, int> Bucket; QList<Bucket> _buckets;}; /// A client session associated with a single server.class MetavoxelSystemClient : public MetavoxelClient { Q_OBJECT public: MetavoxelSystemClient(const SharedNodePointer& node, MetavoxelUpdater* updater); Q_INVOKABLE void setAugmentedData(const MetavoxelData& data); /// Returns a copy of the augmented data. This function is thread-safe. MetavoxelData getAugmentedData(); void setRenderedAugmentedData(const MetavoxelData& data) { _renderedAugmentedData = data; } virtual int parseData(const QByteArray& packet); Q_INVOKABLE void refreshVoxelData(); protected: virtual void dataChanged(const MetavoxelData& oldData); virtual void sendDatagram(const QByteArray& data); private: MetavoxelData _augmentedData; MetavoxelData _renderedAugmentedData; QReadWriteLock _augmentedDataLock; Throttle _sendThrottle; Throttle _receiveThrottle;}; /// Base class for cached static buffers.class BufferData : public QSharedData {public: virtual ~BufferData(); virtual void render(bool cursor = false) = 0;}; typedef QExplicitlySharedDataPointer<BufferData> BufferDataPointer; /// Describes contents of a vertex in a voxel buffer.class VoxelPoint {public: glm::vec3 vertex; quint8 color[3]; char normal[3]; quint8 materials[4]; quint8 materialWeights[4]; void setNormal(const glm::vec3& normal);}; /// A container for a coordinate within a voxel block.class VoxelCoord {public: QRgb encoded; VoxelCoord(QRgb encoded) : encoded(encoded) { } bool operator==(const VoxelCoord& other) const { return encoded == other.encoded; }}; inline uint qHash(const VoxelCoord& coord, uint seed) { // multiply by prime numbers greater than the possible size return qHash(qRed(coord.encoded) + 257 * (qGreen(coord.encoded) + 263 * qBlue(coord.encoded)), seed);} /// Contains the information necessary to render a voxel block.class VoxelBuffer : public BufferData {public: VoxelBuffer(const QVector<VoxelPoint>& vertices, const QVector<int>& indices, const QVector<glm::vec3>& hermite, const QMultiHash<VoxelCoord, int>& quadIndices, int size, const QVector<SharedObjectPointer>& materials = QVector<SharedObjectPointer>()); /// Finds the first intersection between the described ray and the voxel data. /// \param entry the entry point of the ray in relative coordinates, from (0, 0, 0) to (1, 1, 1) bool findFirstRayIntersection(const glm::vec3& entry, const glm::vec3& origin, const glm::vec3& direction, float& distance) const; virtual void render(bool cursor = false); private: QVector<VoxelPoint> _vertices; QVector<int> _indices; QVector<glm::vec3> _hermite; QMultiHash<VoxelCoord, int> _quadIndices; int _size; int _vertexCount; int _indexCount; int _hermiteCount; QOpenGLBuffer _vertexBuffer; QOpenGLBuffer _indexBuffer; QOpenGLBuffer _hermiteBuffer; QVector<SharedObjectPointer> _materials; QVector<NetworkTexturePointer> _networkTextures;}; /// A client-side attribute that stores renderable buffers.class BufferDataAttribute : public InlineAttribute<BufferDataPointer> { Q_OBJECT public: Q_INVOKABLE BufferDataAttribute(const QString& name = QString()); virtual bool merge(void*& parent, void* children[], bool postRead = false) const; virtual AttributeValue inherit(const AttributeValue& parentValue) const;}; /// Renders metavoxels as points.class DefaultMetavoxelRendererImplementation : public MetavoxelRendererImplementation { Q_OBJECT public: 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);}; /// Renders spheres.class SphereRenderer : public SpannerRenderer { Q_OBJECT public: Q_INVOKABLE SphereRenderer(); virtual void render(const MetavoxelLOD& lod = MetavoxelLOD(), bool contained = false, bool cursor = false);}; /// Renders cuboids.class CuboidRenderer : public SpannerRenderer { Q_OBJECT public: Q_INVOKABLE CuboidRenderer(); virtual void render(const MetavoxelLOD& lod = MetavoxelLOD(), bool contained = false, bool cursor = false);}; /// Renders static models.class StaticModelRenderer : public SpannerRenderer { Q_OBJECT public: Q_INVOKABLE StaticModelRenderer(); virtual void init(Spanner* spanner); virtual void simulate(float deltaTime); virtual void render(const MetavoxelLOD& lod = MetavoxelLOD(), bool contained = false, bool cursor = false); virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const; private slots: void applyTranslation(const glm::vec3& translation); void applyRotation(const glm::quat& rotation); void applyScale(float scale); void applyURL(const QUrl& url); private: Model* _model;}; /// Renders heightfields.class HeightfieldRenderer : public SpannerRenderer { Q_OBJECT public: Q_INVOKABLE HeightfieldRenderer(); virtual void render(const MetavoxelLOD& lod = MetavoxelLOD(), bool contained = false, bool cursor = false);}; /// Renders a single quadtree node.class HeightfieldNodeRenderer : public AbstractHeightfieldNodeRenderer {public: HeightfieldNodeRenderer(); virtual ~HeightfieldNodeRenderer(); void render(const HeightfieldNodePointer& node, const glm::vec3& translation, const glm::quat& rotation, const glm::vec3& scale, bool cursor); private: GLuint _heightTextureID; GLuint _colorTextureID; GLuint _materialTextureID; QVector<NetworkTexturePointer> _networkTextures; typedef QPair<int, int> IntPair; typedef QPair<QOpenGLBuffer, QOpenGLBuffer> BufferPair; static QHash<IntPair, BufferPair> _bufferPairs;}; #endif // hifi_MetavoxelSystem_h
//
// MetavoxelSystem.h
// interface/src
//
// Created by Andrzej Kapolka on 12/10/13.
// Copyright 2013 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
//
#ifndef hifi_MetavoxelSystem_h
#define hifi_MetavoxelSystem_h
#include <QList>
#include <QOpenGLBuffer>
#include <QReadWriteLock>
#include <QVector>
#include <glm/glm.hpp>
#include <MetavoxelClientManager.h>
#include "renderer/ProgramObject.h"
class HeightfieldBaseLayerBatch;
class HeightfieldSplatBatch;
class HermiteBatch;
class Model;
class VoxelBatch;
class VoxelSplatBatch;
/// Renders a metavoxel tree.
class MetavoxelSystem : public MetavoxelClientManager {
Q_OBJECT
public:
class NetworkSimulation {
public:
float dropRate;
float repeatRate;
int minimumDelay;
int maximumDelay;
int bandwidthLimit;
NetworkSimulation(float dropRate = 0.0f, float repeatRate = 0.0f, int minimumDelay = 0,
int maximumDelay = 0, int bandwidthLimit = 0);
};
virtual ~MetavoxelSystem();
virtual void init();
virtual MetavoxelLOD getLOD();
const Frustum& getFrustum() const { return _frustum; }
void setNetworkSimulation(const NetworkSimulation& simulation);
NetworkSimulation getNetworkSimulation();
const AttributePointer& getHeightfieldBufferAttribute() { return _heightfieldBufferAttribute; }
const AttributePointer& getVoxelBufferAttribute() { return _voxelBufferAttribute; }
void simulate(float deltaTime);
void render();
void renderHeightfieldCursor(const glm::vec3& position, float radius);
void renderVoxelCursor(const glm::vec3& position, float radius);
bool findFirstRayVoxelIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance);
Q_INVOKABLE void paintHeightfieldColor(const glm::vec3& position, float radius, const QColor& color);
Q_INVOKABLE void paintHeightfieldMaterial(const glm::vec3& position, float radius, const SharedObjectPointer& material);
Q_INVOKABLE void paintVoxelColor(const glm::vec3& position, float radius, const QColor& color);
Q_INVOKABLE void paintVoxelMaterial(const glm::vec3& position, float radius, const SharedObjectPointer& material);
Q_INVOKABLE void setVoxelColor(const SharedObjectPointer& spanner, const QColor& color);
Q_INVOKABLE void setVoxelMaterial(const SharedObjectPointer& spanner, const SharedObjectPointer& material);
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 addVoxelSplatBatch(const VoxelSplatBatch& batch) { _voxelSplatBatches.append(batch); }
void addHermiteBatch(const HermiteBatch& batch) { _hermiteBatches.append(batch); }
Q_INVOKABLE void deleteTextures(int heightTextureID, int colorTextureID, int materialTextureID) const;
signals:
void rendering();
public slots:
void refreshVoxelData();
protected:
Q_INVOKABLE void applyMaterialEdit(const MetavoxelEditMessage& message, bool reliable = false);
virtual MetavoxelClient* createClient(const SharedNodePointer& node);
private:
void guideToAugmented(MetavoxelVisitor& visitor, bool render = false);
AttributePointer _heightfieldBufferAttribute;
AttributePointer _voxelBufferAttribute;
MetavoxelLOD _lod;
QReadWriteLock _lodLock;
Frustum _frustum;
NetworkSimulation _networkSimulation;
QReadWriteLock _networkSimulationLock;
QVector<HeightfieldBaseLayerBatch> _heightfieldBaseBatches;
QVector<HeightfieldSplatBatch> _heightfieldSplatBatches;
QVector<VoxelBatch> _voxelBaseBatches;
QVector<VoxelSplatBatch> _voxelSplatBatches;
QVector<HermiteBatch> _hermiteBatches;
ProgramObject _baseHeightfieldProgram;
int _baseHeightScaleLocation;
int _baseColorScaleLocation;
class SplatLocations {
public:
int heightScale;
int textureScale;
int splatTextureOffset;
int splatTextureScalesS;
int splatTextureScalesT;
int textureValueMinima;
int textureValueMaxima;
int materials;
int materialWeights;
};
ProgramObject _splatHeightfieldProgram;
SplatLocations _splatHeightfieldLocations;
int _splatHeightScaleLocation;
int _splatTextureScaleLocation;
int _splatTextureOffsetLocation;
int _splatTextureScalesSLocation;
int _splatTextureScalesTLocation;
int _splatTextureValueMinimaLocation;
int _splatTextureValueMaximaLocation;
ProgramObject _heightfieldCursorProgram;
ProgramObject _baseVoxelProgram;
ProgramObject _splatVoxelProgram;
SplatLocations _splatVoxelLocations;
ProgramObject _voxelCursorProgram;
static void loadSplatProgram(const char* type, ProgramObject& program, SplatLocations& locations);
};
/// Base class for heightfield batches.
class HeightfieldBatch {
public:
QOpenGLBuffer* vertexBuffer;
QOpenGLBuffer* indexBuffer;
glm::vec3 translation;
glm::quat rotation;
glm::vec3 scale;
int vertexCount;
int indexCount;
GLuint heightTextureID;
glm::vec4 heightScale;
};
/// A batch containing a heightfield base layer.
class HeightfieldBaseLayerBatch : public HeightfieldBatch {
public:
GLuint colorTextureID;
glm::vec2 colorScale;
};
/// A batch containing a heightfield splat.
class HeightfieldSplatBatch : public HeightfieldBatch {
public:
GLuint materialTextureID;
glm::vec2 textureScale;
glm::vec2 splatTextureOffset;
int splatTextureIDs[4];
glm::vec4 splatTextureScalesS;
glm::vec4 splatTextureScalesT;
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 {
public:
int splatTextureIDs[4];
glm::vec4 splatTextureScalesS;
glm::vec4 splatTextureScalesT;
int materialIndex;
};
/// A batch containing Hermite data for debugging.
class HermiteBatch {
public:
QOpenGLBuffer* vertexBuffer;
int vertexCount;
};
/// Generic abstract base class for objects that handle a signal.
class SignalHandler : public QObject {
Q_OBJECT
public slots:
virtual void handle() = 0;
};
/// Simple throttle for limiting bandwidth on a per-second basis.
class Throttle {
public:
Throttle();
/// Sets the per-second limit.
void setLimit(int limit) { _limit = limit; }
/// Determines whether the message with the given size should be throttled (discarded). If not, registers the message
/// as having been processed (i.e., contributing to later throttling).
bool shouldThrottle(int bytes);
private:
int _limit;
int _total;
typedef QPair<qint64, int> Bucket;
QList<Bucket> _buckets;
};
/// A client session associated with a single server.
class MetavoxelSystemClient : public MetavoxelClient {
Q_OBJECT
public:
MetavoxelSystemClient(const SharedNodePointer& node, MetavoxelUpdater* updater);
Q_INVOKABLE void setAugmentedData(const MetavoxelData& data);
/// Returns a copy of the augmented data. This function is thread-safe.
MetavoxelData getAugmentedData();
void setRenderedAugmentedData(const MetavoxelData& data) { _renderedAugmentedData = data; }
virtual int parseData(const QByteArray& packet);
Q_INVOKABLE void refreshVoxelData();
protected:
virtual void dataChanged(const MetavoxelData& oldData);
virtual void sendDatagram(const QByteArray& data);
private:
MetavoxelData _augmentedData;
MetavoxelData _renderedAugmentedData;
QReadWriteLock _augmentedDataLock;
Throttle _sendThrottle;
Throttle _receiveThrottle;
};
/// Base class for cached static buffers.
class BufferData : public QSharedData {
public:
virtual ~BufferData();
virtual void render(bool cursor = false) = 0;
};
typedef QExplicitlySharedDataPointer<BufferData> BufferDataPointer;
/// Describes contents of a vertex in a voxel buffer.
class VoxelPoint {
public:
glm::vec3 vertex;
quint8 color[3];
char normal[3];
quint8 materials[4];
quint8 materialWeights[4];
void setNormal(const glm::vec3& normal);
};
/// A container for a coordinate within a voxel block.
class VoxelCoord {
public:
QRgb encoded;
VoxelCoord(QRgb encoded) : encoded(encoded) { }
bool operator==(const VoxelCoord& other) const { return encoded == other.encoded; }
};
inline uint qHash(const VoxelCoord& coord, uint seed) {
// multiply by prime numbers greater than the possible size
return qHash(qRed(coord.encoded) + 257 * (qGreen(coord.encoded) + 263 * qBlue(coord.encoded)), seed);
}
/// Contains the information necessary to render a voxel block.
class VoxelBuffer : public BufferData {
public:
VoxelBuffer(const QVector<VoxelPoint>& vertices, const QVector<int>& indices, const QVector<glm::vec3>& hermite,
const QMultiHash<VoxelCoord, int>& quadIndices, int size, const QVector<SharedObjectPointer>& materials =
QVector<SharedObjectPointer>());
/// Finds the first intersection between the described ray and the voxel data.
/// \param entry the entry point of the ray in relative coordinates, from (0, 0, 0) to (1, 1, 1)
bool findFirstRayIntersection(const glm::vec3& entry, const glm::vec3& origin,
const glm::vec3& direction, float& distance) const;
virtual void render(bool cursor = false);
private:
QVector<VoxelPoint> _vertices;
QVector<int> _indices;
QVector<glm::vec3> _hermite;
QMultiHash<VoxelCoord, int> _quadIndices;
int _size;
int _vertexCount;
int _indexCount;
int _hermiteCount;
QOpenGLBuffer _vertexBuffer;
QOpenGLBuffer _indexBuffer;
QOpenGLBuffer _hermiteBuffer;
QVector<SharedObjectPointer> _materials;
QVector<NetworkTexturePointer> _networkTextures;
};
/// A client-side attribute that stores renderable buffers.
class BufferDataAttribute : public InlineAttribute<BufferDataPointer> {
Q_OBJECT
public:
Q_INVOKABLE BufferDataAttribute(const QString& name = QString());
virtual bool merge(void*& parent, void* children[], bool postRead = false) const;
virtual AttributeValue inherit(const AttributeValue& parentValue) const;
};
/// Renders metavoxels as points.
class DefaultMetavoxelRendererImplementation : public MetavoxelRendererImplementation {
Q_OBJECT
public:
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);
};
/// Renders spheres.
class SphereRenderer : public SpannerRenderer {
Q_OBJECT
public:
Q_INVOKABLE SphereRenderer();
virtual void render(const MetavoxelLOD& lod = MetavoxelLOD(), bool contained = false, bool cursor = false);
};
/// Renders cuboids.
class CuboidRenderer : public SpannerRenderer {
Q_OBJECT
public:
Q_INVOKABLE CuboidRenderer();
virtual void render(const MetavoxelLOD& lod = MetavoxelLOD(), bool contained = false, bool cursor = false);
};
/// Renders static models.
class StaticModelRenderer : public SpannerRenderer {
Q_OBJECT
public:
Q_INVOKABLE StaticModelRenderer();
virtual void init(Spanner* spanner);
virtual void simulate(float deltaTime);
virtual void render(const MetavoxelLOD& lod = MetavoxelLOD(), bool contained = false, bool cursor = false);
virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const;
private slots:
void applyTranslation(const glm::vec3& translation);
void applyRotation(const glm::quat& rotation);
void applyScale(float scale);
void applyURL(const QUrl& url);
private:
Model* _model;
};
/// Renders heightfields.
class HeightfieldRenderer : public SpannerRenderer {
Q_OBJECT
public:
Q_INVOKABLE HeightfieldRenderer();
virtual void render(const MetavoxelLOD& lod = MetavoxelLOD(), bool contained = false, bool cursor = false);
};
/// Renders a single quadtree node.
class HeightfieldNodeRenderer : public AbstractHeightfieldNodeRenderer {
public:
HeightfieldNodeRenderer();
virtual ~HeightfieldNodeRenderer();
void render(const HeightfieldNodePointer& node, const glm::vec3& translation,
const glm::quat& rotation, const glm::vec3& scale, bool cursor);
private:
GLuint _heightTextureID;
GLuint _colorTextureID;
GLuint _materialTextureID;
QVector<NetworkTexturePointer> _networkTextures;
typedef QPair<int, int> IntPair;
typedef QPair<QOpenGLBuffer, QOpenGLBuffer> BufferPair;
static QHash<IntPair, BufferPair> _bufferPairs;
};
#endif // hifi_MetavoxelSystem_h