Basic metavoxel scripting bits.

This commit is contained in:
Andrzej Kapolka 2014-10-13 15:05:16 -07:00
parent d90d30ad9f
commit 60576bdcbd
10 changed files with 160 additions and 21 deletions

View file

@ -23,6 +23,7 @@
#include <SharedUtil.h>
#include <MetavoxelMessages.h>
#include <MetavoxelUtil.h>
#include <ScriptCache.h>
@ -454,6 +455,36 @@ float MetavoxelSystem::getHeightfieldHeight(const glm::vec3& location) {
return visitor.height;
}
void MetavoxelSystem::paintHeightfieldColor(const glm::vec3& position, float radius, const QColor& color) {
MetavoxelEditMessage edit = { QVariant::fromValue(PaintHeightfieldMaterialEdit(position, radius, SharedObjectPointer(), color)) };
applyEdit(edit, true);
}
void MetavoxelSystem::paintHeightfieldMaterial(const glm::vec3& position, float radius, const SharedObjectPointer& material) {
MetavoxelEditMessage edit = { QVariant::fromValue(PaintHeightfieldMaterialEdit(position, radius, material)) };
applyMaterialEdit(edit, true);
}
void MetavoxelSystem::paintVoxelColor(const glm::vec3& position, float radius, const QColor& color) {
MetavoxelEditMessage edit = { QVariant::fromValue(PaintVoxelMaterialEdit(position, radius, SharedObjectPointer(), color)) };
applyEdit(edit, true);
}
void MetavoxelSystem::paintVoxelMaterial(const glm::vec3& position, float radius, const SharedObjectPointer& material) {
MetavoxelEditMessage edit = { QVariant::fromValue(PaintVoxelMaterialEdit(position, radius, material)) };
applyMaterialEdit(edit, true);
}
void MetavoxelSystem::setVoxelColor(const SharedObjectPointer& spanner, const QColor& color) {
MetavoxelEditMessage edit = { QVariant::fromValue(VoxelMaterialSpannerEdit(spanner, SharedObjectPointer(), color)) };
applyEdit(edit, true);
}
void MetavoxelSystem::setVoxelMaterial(const SharedObjectPointer& spanner, const SharedObjectPointer& material) {
MetavoxelEditMessage edit = { QVariant::fromValue(VoxelMaterialSpannerEdit(spanner, material)) };
applyMaterialEdit(edit, true);
}
class CursorRenderVisitor : public MetavoxelVisitor {
public:
@ -563,6 +594,54 @@ void MetavoxelSystem::deleteTextures(int heightID, int colorID, int textureID) {
glDeleteTextures(1, (GLuint*)&textureID);
}
class MaterialEditApplier : public SignalHandler {
public:
MaterialEditApplier(const MetavoxelEditMessage& message, const QSharedPointer<NetworkTexture> texture);
virtual void handle();
protected:
MetavoxelEditMessage _message;
QSharedPointer<NetworkTexture> _texture;
};
MaterialEditApplier::MaterialEditApplier(const MetavoxelEditMessage& message, const QSharedPointer<NetworkTexture> texture) :
_message(message),
_texture(texture) {
}
void MaterialEditApplier::handle() {
static_cast<MaterialEdit*>(_message.edit.data())->averageColor = _texture->getAverageColor();
Application::getInstance()->getMetavoxels()->applyEdit(_message, true);
}
void MetavoxelSystem::applyMaterialEdit(const MetavoxelEditMessage& message, bool reliable) {
const MaterialEdit* edit = static_cast<const MaterialEdit*>(message.edit.constData());
MaterialObject* material = static_cast<MaterialObject*>(edit->material.data());
if (material && material->getDiffuse().isValid()) {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "applyMaterialEdit", Q_ARG(const MetavoxelEditMessage&, message),
Q_ARG(bool, reliable));
return;
}
QSharedPointer<NetworkTexture> texture = Application::getInstance()->getTextureCache()->getTexture(
material->getDiffuse(), SPLAT_TEXTURE);
if (texture->isLoaded()) {
MetavoxelEditMessage newMessage = message;
static_cast<MaterialEdit*>(newMessage.edit.data())->averageColor = texture->getAverageColor();
applyEdit(newMessage, true);
} else {
MaterialEditApplier* applier = new MaterialEditApplier(message, texture);
connect(texture.data(), &Resource::loaded, applier, &SignalHandler::handle);
}
} else {
applyEdit(message, true);
}
}
MetavoxelClient* MetavoxelSystem::createClient(const SharedNodePointer& node) {
return new MetavoxelSystemClient(node, _updater);
}

View file

@ -54,6 +54,18 @@ public:
Q_INVOKABLE float getHeightfieldHeight(const glm::vec3& location);
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);
Q_INVOKABLE void deleteTextures(int heightID, int colorID, int textureID);
signals:
@ -66,6 +78,8 @@ public slots:
protected:
Q_INVOKABLE void applyMaterialEdit(const MetavoxelEditMessage& message, bool reliable = false);
virtual MetavoxelClient* createClient(const SharedNodePointer& node);
private:
@ -81,6 +95,15 @@ private:
Frustum _frustum;
};
/// Generic abstract base class for objects that handle a signal.
class SignalHandler : public QObject {
Q_OBJECT
public slots:
virtual void handle() = 0;
};
/// Describes contents of a point in a point buffer.
class BufferPoint {
public:

View file

@ -1595,7 +1595,9 @@ QVariant VoxelMaterialBrushTool::createEdit(bool alternate) {
} else {
material = SharedObjectPointer();
}
return QVariant::fromValue(PaintVoxelMaterialEdit(_position, _radius->value(), material, _color->getColor()));
QColor color = _color->getColor();
color.setAlphaF(color.alphaF() > 0.5f ? 1.0f : 0.0f);
return QVariant::fromValue(PaintVoxelMaterialEdit(_position, _radius->value(), material, color));
}
}

View file

@ -74,6 +74,11 @@ void MetavoxelClientManager::setSpanner(const SharedObjectPointer& object, bool
applyEdit(edit, reliable);
}
void MetavoxelClientManager::paintHeightfieldHeight(const glm::vec3& position, float radius, float height) {
MetavoxelEditMessage edit = { QVariant::fromValue(PaintHeightfieldHeightEdit(position, radius, height)) };
applyEdit(edit, true);
}
void MetavoxelClientManager::applyEdit(const MetavoxelEditMessage& edit, bool reliable) {
QMetaObject::invokeMethod(_updater, "applyEdit", Q_ARG(const MetavoxelEditMessage&, edit), Q_ARG(bool, reliable));
}

View file

@ -41,6 +41,8 @@ public:
Q_INVOKABLE void setSpanner(const SharedObjectPointer& object, bool reliable = false);
Q_INVOKABLE void paintHeightfieldHeight(const glm::vec3& position, float radius, float height);
Q_INVOKABLE void applyEdit(const MetavoxelEditMessage& edit, bool reliable = false);
/// Returns the current LOD. This must be thread-safe, as it will be called from the updater thread.

View file

@ -18,6 +18,10 @@ void MetavoxelEditMessage::apply(MetavoxelData& data, const WeakSharedObjectHash
MetavoxelEdit::~MetavoxelEdit() {
}
void MetavoxelEdit::apply(MetavoxelData& data, const WeakSharedObjectHash& objects) const {
// nothing by default
}
BoxSetEdit::BoxSetEdit(const Box& region, float granularity, const OwnedAttributeValue& value) :
region(region), granularity(granularity), value(value) {
}
@ -408,6 +412,11 @@ void PaintHeightfieldHeightEdit::apply(MetavoxelData& data, const WeakSharedObje
data.guide(visitor);
}
MaterialEdit::MaterialEdit(const SharedObjectPointer& material, const QColor& averageColor) :
material(material),
averageColor(averageColor) {
}
class PaintHeightfieldMaterialEditVisitor : public MetavoxelVisitor {
public:
@ -595,10 +604,9 @@ int PaintHeightfieldMaterialEditVisitor::visit(MetavoxelInfo& info) {
PaintHeightfieldMaterialEdit::PaintHeightfieldMaterialEdit(const glm::vec3& position, float radius,
const SharedObjectPointer& material, const QColor& averageColor) :
MaterialEdit(material, averageColor),
position(position),
radius(radius),
material(material),
averageColor(averageColor) {
radius(radius) {
}
void PaintHeightfieldMaterialEdit::apply(MetavoxelData& data, const WeakSharedObjectHash& objects) const {
@ -613,9 +621,8 @@ const int VOXEL_BLOCK_VOLUME = VOXEL_BLOCK_AREA * VOXEL_BLOCK_SAMPLES;
VoxelMaterialSpannerEdit::VoxelMaterialSpannerEdit(const SharedObjectPointer& spanner,
const SharedObjectPointer& material, const QColor& averageColor) :
spanner(spanner),
material(material),
averageColor(averageColor) {
MaterialEdit(material, averageColor),
spanner(spanner) {
}
class VoxelMaterialSpannerEditVisitor : public MetavoxelVisitor {
@ -851,10 +858,9 @@ void VoxelMaterialSpannerEdit::apply(MetavoxelData& data, const WeakSharedObject
PaintVoxelMaterialEdit::PaintVoxelMaterialEdit(const glm::vec3& position, float radius,
const SharedObjectPointer& material, const QColor& averageColor) :
MaterialEdit(material, averageColor),
position(position),
radius(radius),
material(material),
averageColor(averageColor) {
radius(radius) {
}
class PaintVoxelMaterialEditVisitor : public MetavoxelVisitor {

View file

@ -91,7 +91,7 @@ public:
virtual ~MetavoxelEdit();
virtual void apply(MetavoxelData& data, const WeakSharedObjectHash& objects) const = 0;
virtual void apply(MetavoxelData& data, const WeakSharedObjectHash& objects) const;
};
/// An edit that sets the region within a box to a value.
@ -224,16 +224,28 @@ public:
DECLARE_STREAMABLE_METATYPE(PaintHeightfieldHeightEdit)
/// Base class for edits that have materials.
class MaterialEdit : public MetavoxelEdit {
STREAMABLE
public:
STREAM SharedObjectPointer material;
STREAM QColor averageColor;
MaterialEdit(const SharedObjectPointer& material = SharedObjectPointer(), const QColor& averageColor = QColor());
};
DECLARE_STREAMABLE_METATYPE(MaterialEdit)
/// An edit that sets a region of a heightfield material.
class PaintHeightfieldMaterialEdit : public MetavoxelEdit {
class PaintHeightfieldMaterialEdit : STREAM public MaterialEdit {
STREAMABLE
public:
STREAM glm::vec3 position;
STREAM float radius;
STREAM SharedObjectPointer material;
STREAM QColor averageColor;
PaintHeightfieldMaterialEdit(const glm::vec3& position = glm::vec3(), float radius = 0.0f,
const SharedObjectPointer& material = SharedObjectPointer(), const QColor& averageColor = QColor());
@ -244,14 +256,12 @@ public:
DECLARE_STREAMABLE_METATYPE(PaintHeightfieldMaterialEdit)
/// An edit that sets the materials of voxels within a spanner to a value.
class VoxelMaterialSpannerEdit : public MetavoxelEdit {
class VoxelMaterialSpannerEdit : STREAM public MaterialEdit {
STREAMABLE
public:
STREAM SharedObjectPointer spanner;
STREAM SharedObjectPointer material;
STREAM QColor averageColor;
VoxelMaterialSpannerEdit(const SharedObjectPointer& spanner = SharedObjectPointer(),
const SharedObjectPointer& material = SharedObjectPointer(), const QColor& averageColor = QColor());
@ -262,15 +272,13 @@ public:
DECLARE_STREAMABLE_METATYPE(VoxelMaterialSpannerEdit)
/// An edit that sets a region of a voxel material.
class PaintVoxelMaterialEdit : public MetavoxelEdit {
class PaintVoxelMaterialEdit : STREAM public MaterialEdit {
STREAMABLE
public:
STREAM glm::vec3 position;
STREAM float radius;
STREAM SharedObjectPointer material;
STREAM QColor averageColor;
PaintVoxelMaterialEdit(const glm::vec3& position = glm::vec3(), float radius = 0.0f,
const SharedObjectPointer& material = SharedObjectPointer(), const QColor& averageColor = QColor());

View file

@ -85,7 +85,7 @@ PacketVersion versionForPacketType(PacketType type) {
case PacketTypeAudioStreamStats:
return 1;
case PacketTypeMetavoxelData:
return 6;
return 7;
case PacketTypeVoxelData:
return VERSION_VOXELS_HAS_FILE_BREAKS;
default:

View file

@ -10,6 +10,7 @@
//
#include <QColor>
#include <QUrl>
#include <QUuid>
#include "RegisteredMetaTypes.h"
@ -29,6 +30,7 @@ void registerMetaTypes(QScriptEngine* engine) {
qScriptRegisterMetaType(engine, quatToScriptValue, quatFromScriptValue);
qScriptRegisterMetaType(engine, xColorToScriptValue, xColorFromScriptValue);
qScriptRegisterMetaType(engine, qColorToScriptValue, qColorFromScriptValue);
qScriptRegisterMetaType(engine, qURLToScriptValue, qURLFromScriptValue);
qScriptRegisterMetaType(engine, pickRayToScriptValue, pickRayFromScriptValue);
qScriptRegisterMetaType(engine, collisionToScriptValue, collisionFromScriptValue);
qScriptRegisterMetaType(engine, quuidToScriptValue, quuidFromScriptValue);
@ -129,6 +131,14 @@ void qColorFromScriptValue(const QScriptValue& object, QColor& color) {
}
}
QScriptValue qURLToScriptValue(QScriptEngine* engine, const QUrl& url) {
return url.toString();
}
void qURLFromScriptValue(const QScriptValue& object, QUrl& url) {
url = object.toString();
}
QScriptValue pickRayToScriptValue(QScriptEngine* engine, const PickRay& pickRay) {
QScriptValue obj = engine->newObject();
QScriptValue origin = vec3toScriptValue(engine, pickRay.origin);

View file

@ -20,6 +20,7 @@
#include "SharedUtil.h"
class QColor;
class QUrl;
Q_DECLARE_METATYPE(glm::vec4)
Q_DECLARE_METATYPE(glm::vec3)
@ -47,6 +48,9 @@ void xColorFromScriptValue(const QScriptValue &object, xColor& color);
QScriptValue qColorToScriptValue(QScriptEngine* engine, const QColor& color);
void qColorFromScriptValue(const QScriptValue& object, QColor& color);
QScriptValue qURLToScriptValue(QScriptEngine* engine, const QUrl& url);
void qURLFromScriptValue(const QScriptValue& object, QUrl& url);
class PickRay {
public:
PickRay() : origin(0), direction(0) { };