mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +02:00
Merge pull request #3591 from ey6es/metavoxels
Basic metavoxel scripting commands.
This commit is contained in:
commit
240280b9ac
11 changed files with 210 additions and 29 deletions
41
examples/metavoxels.js
Normal file
41
examples/metavoxels.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// metavoxels.js
|
||||
// examples
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
||||
Script.setInterval(function() {
|
||||
var spanner;
|
||||
if (Math.random() < 0.5) {
|
||||
spanner = new Sphere();
|
||||
} else {
|
||||
spanner = new Cuboid();
|
||||
spanner.aspectX = 0.1 + Math.random() * 1.9;
|
||||
spanner.aspectY = 0.1 + Math.random() * 1.9;
|
||||
}
|
||||
spanner.scale = 0.1 + Math.random() * 1.9;
|
||||
spanner.rotation = Quat.fromPitchYawRollDegrees(Math.random() * 360.0, Math.random() * 360.0, Math.random() * 360.0);
|
||||
spanner.translation = { x: 10.0 + Math.random() * 10.0, y: 10.0 + Math.random() * 10.0, z: 10.0 + Math.random() * 10.0 };
|
||||
|
||||
if (Math.random() < 0.5) {
|
||||
var material = new MaterialObject();
|
||||
if (Math.random() < 0.5) {
|
||||
material.diffuse = "http://www.fungibleinsight.com/faces/grass.jpg";
|
||||
} else {
|
||||
material.diffuse = "http://www.fungibleinsight.com/faces/soil.jpg";
|
||||
}
|
||||
Metavoxels.setVoxelMaterial(spanner, material);
|
||||
|
||||
} else if (Math.random() < 0.5) {
|
||||
Metavoxels.setVoxelColor(spanner, { red: Math.random() * 255.0, green: Math.random() * 255.0,
|
||||
blue: Math.random() * 255.0 });
|
||||
|
||||
} else {
|
||||
Metavoxels.setVoxelColor(spanner, { red: 0, green: 0, blue: 0, alpha: 0 });
|
||||
}
|
||||
}, 1000);
|
||||
|
|
@ -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,55 @@ 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);
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -1392,16 +1392,14 @@ void VoxelMaterialBoxTool::applyValue(const glm::vec3& minimum, const glm::vec3&
|
|||
} else {
|
||||
material = SharedObjectPointer();
|
||||
}
|
||||
QColor color = _color->getColor();
|
||||
color.setAlphaF(color.alphaF() > 0.5f ? 1.0f : 0.0f);
|
||||
|
||||
Cuboid* cuboid = new Cuboid();
|
||||
cuboid->setTranslation((maximum + minimum) * 0.5f);
|
||||
glm::vec3 vector = (maximum - minimum) * 0.5f;
|
||||
cuboid->setScale(vector.x);
|
||||
cuboid->setAspectY(vector.y / vector.x);
|
||||
cuboid->setAspectZ(vector.z / vector.x);
|
||||
MetavoxelEditMessage message = { QVariant::fromValue(VoxelMaterialSpannerEdit(SharedObjectPointer(cuboid), material, color)) };
|
||||
MetavoxelEditMessage message = { QVariant::fromValue(VoxelMaterialSpannerEdit(SharedObjectPointer(cuboid),
|
||||
material, _color->getColor())) };
|
||||
Application::getInstance()->getMetavoxels()->applyEdit(message, true);
|
||||
}
|
||||
|
||||
|
@ -1489,9 +1487,7 @@ void VoxelMaterialSpannerTool::applyEdit(const AttributePointer& attribute, cons
|
|||
} else {
|
||||
material = SharedObjectPointer();
|
||||
}
|
||||
QColor color = _color->getColor();
|
||||
color.setAlphaF(color.alphaF() > 0.5f ? 1.0f : 0.0f);
|
||||
MetavoxelEditMessage message = { QVariant::fromValue(VoxelMaterialSpannerEdit(spanner, material, color)) };
|
||||
MetavoxelEditMessage message = { QVariant::fromValue(VoxelMaterialSpannerEdit(spanner, material, _color->getColor())) };
|
||||
Application::getInstance()->getMetavoxels()->applyEdit(message, true);
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 {
|
||||
|
@ -845,16 +852,18 @@ void VoxelMaterialSpannerEdit::apply(MetavoxelData& data, const WeakSharedObject
|
|||
while (!data.getBounds().contains(spanner->getBounds())) {
|
||||
data.expand();
|
||||
}
|
||||
VoxelMaterialSpannerEditVisitor visitor(spanner, material, averageColor);
|
||||
// make sure it's either 100% transparent or 100% opaque
|
||||
QColor color = averageColor;
|
||||
color.setAlphaF(color.alphaF() > 0.5f ? 1.0f : 0.0f);
|
||||
VoxelMaterialSpannerEditVisitor visitor(spanner, material, color);
|
||||
data.guide(visitor);
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -950,6 +959,9 @@ int PaintVoxelMaterialEditVisitor::visit(MetavoxelInfo& info) {
|
|||
}
|
||||
|
||||
void PaintVoxelMaterialEdit::apply(MetavoxelData& data, const WeakSharedObjectHash& objects) const {
|
||||
PaintVoxelMaterialEditVisitor visitor(position, radius, material, averageColor);
|
||||
// make sure it's 100% opaque
|
||||
QColor color = averageColor;
|
||||
color.setAlphaF(1.0f);
|
||||
PaintVoxelMaterialEditVisitor visitor(position, radius, material, color);
|
||||
data.guide(visitor);
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) { };
|
||||
|
|
Loading…
Reference in a new issue