mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 12:04:18 +02:00
Sphere tools for voxel editing.
This commit is contained in:
parent
926f0d099c
commit
33faffd9d4
6 changed files with 490 additions and 0 deletions
|
@ -126,6 +126,8 @@ MetavoxelEditor::MetavoxelEditor() :
|
|||
addTool(new EraseHeightfieldTool(this));
|
||||
addTool(new VoxelColorBoxTool(this));
|
||||
addTool(new VoxelMaterialBoxTool(this));
|
||||
addTool(new VoxelColorSphereTool(this));
|
||||
addTool(new VoxelMaterialSphereTool(this));
|
||||
|
||||
updateAttributes();
|
||||
|
||||
|
@ -1282,3 +1284,110 @@ void VoxelMaterialBoxTool::updateTexture() {
|
|||
MaterialObject* material = static_cast<MaterialObject*>(_materialEditor->getObject().data());
|
||||
_texture = Application::getInstance()->getTextureCache()->getTexture(material->getDiffuse(), SPLAT_TEXTURE);
|
||||
}
|
||||
|
||||
SphereTool::SphereTool(MetavoxelEditor* editor, const QString& name) :
|
||||
MetavoxelTool(editor, name, false, true) {
|
||||
|
||||
QWidget* widget = new QWidget();
|
||||
widget->setLayout(_form = new QFormLayout());
|
||||
layout()->addWidget(widget);
|
||||
|
||||
_form->addRow("Radius:", _radius = new QDoubleSpinBox());
|
||||
_radius->setSingleStep(0.01);
|
||||
_radius->setMaximum(FLT_MAX);
|
||||
_radius->setValue(1.0);
|
||||
}
|
||||
|
||||
void SphereTool::render() {
|
||||
if (Application::getInstance()->isMouseHidden()) {
|
||||
return;
|
||||
}
|
||||
glm::quat rotation = _editor->getGridRotation();
|
||||
glm::quat inverseRotation = glm::inverse(rotation);
|
||||
glm::vec3 rayOrigin = inverseRotation * Application::getInstance()->getMouseRayOrigin();
|
||||
glm::vec3 rayDirection = inverseRotation * Application::getInstance()->getMouseRayDirection();
|
||||
float position = _editor->getGridPosition();
|
||||
if (glm::abs(rayDirection.z) < EPSILON) {
|
||||
return;
|
||||
}
|
||||
float distance = (position - rayOrigin.z) / rayDirection.z;
|
||||
_position = Application::getInstance()->getMouseRayOrigin() +
|
||||
Application::getInstance()->getMouseRayDirection() * distance;
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(_position.x, _position.y, _position.z);
|
||||
|
||||
const float CURSOR_ALPHA = 0.5f;
|
||||
QColor color = getColor();
|
||||
glColor4f(color.redF(), color.greenF(), color.blueF(), CURSOR_ALPHA);
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
glutSolidSphere(_radius->value(), 10, 10);
|
||||
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
bool SphereTool::eventFilter(QObject* watched, QEvent* event) {
|
||||
if (event->type() == QEvent::Wheel) {
|
||||
float angle = static_cast<QWheelEvent*>(event)->angleDelta().y();
|
||||
const float ANGLE_SCALE = 1.0f / 1000.0f;
|
||||
_radius->setValue(_radius->value() * glm::pow(2.0f, angle * ANGLE_SCALE));
|
||||
return true;
|
||||
|
||||
} else if (event->type() == QEvent::MouseButtonPress) {
|
||||
applyValue(_position, _radius->value());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
VoxelColorSphereTool::VoxelColorSphereTool(MetavoxelEditor* editor) :
|
||||
SphereTool(editor, "Set Voxel Color (Sphere)") {
|
||||
|
||||
_form->addRow("Color:", _color = new QColorEditor(this));
|
||||
}
|
||||
|
||||
bool VoxelColorSphereTool::appliesTo(const AttributePointer& attribute) const {
|
||||
return attribute->inherits("VoxelColorAttribute");
|
||||
}
|
||||
|
||||
QColor VoxelColorSphereTool::getColor() {
|
||||
return _color->getColor();
|
||||
}
|
||||
|
||||
void VoxelColorSphereTool::applyValue(const glm::vec3& position, float radius) {
|
||||
MetavoxelEditMessage message = { QVariant::fromValue(VoxelColorSphereEdit(position, radius,
|
||||
_editor->getGridSpacing(), _color->getColor())) };
|
||||
Application::getInstance()->getMetavoxels()->applyEdit(message, true);
|
||||
}
|
||||
|
||||
VoxelMaterialSphereTool::VoxelMaterialSphereTool(MetavoxelEditor* editor) :
|
||||
SphereTool(editor, "Set Voxel Material (Sphere)") {
|
||||
|
||||
_form->addRow(_materialEditor = new SharedObjectEditor(&MaterialObject::staticMetaObject, false));
|
||||
connect(_materialEditor, &SharedObjectEditor::objectChanged, this, &VoxelMaterialSphereTool::updateTexture);
|
||||
}
|
||||
|
||||
bool VoxelMaterialSphereTool::appliesTo(const AttributePointer& attribute) const {
|
||||
return attribute->inherits("VoxelColorAttribute");
|
||||
}
|
||||
|
||||
QColor VoxelMaterialSphereTool::getColor() {
|
||||
return _texture ? _texture->getAverageColor() : QColor();
|
||||
}
|
||||
|
||||
void VoxelMaterialSphereTool::applyValue(const glm::vec3& position, float radius) {
|
||||
SharedObjectPointer material = _materialEditor->getObject();
|
||||
_materialEditor->detachObject();
|
||||
MetavoxelEditMessage message = { QVariant::fromValue(VoxelMaterialSphereEdit(position, radius,
|
||||
_editor->getGridSpacing(), material, _texture ? _texture->getAverageColor() : QColor())) };
|
||||
Application::getInstance()->getMetavoxels()->applyEdit(message, true);
|
||||
}
|
||||
|
||||
void VoxelMaterialSphereTool::updateTexture() {
|
||||
MaterialObject* material = static_cast<MaterialObject*>(_materialEditor->getObject().data());
|
||||
_texture = Application::getInstance()->getTextureCache()->getTexture(material->getDiffuse(), SPLAT_TEXTURE);
|
||||
}
|
||||
|
|
|
@ -455,4 +455,75 @@ private:
|
|||
QSharedPointer<NetworkTexture> _texture;
|
||||
};
|
||||
|
||||
/// Base class for tools based on a sphere brush.
|
||||
class SphereTool : public MetavoxelTool {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
SphereTool(MetavoxelEditor* editor, const QString& name);
|
||||
|
||||
virtual void render();
|
||||
|
||||
virtual bool eventFilter(QObject* watched, QEvent* event);
|
||||
|
||||
protected:
|
||||
|
||||
virtual QColor getColor() = 0;
|
||||
|
||||
virtual void applyValue(const glm::vec3& position, float radius) = 0;
|
||||
|
||||
QFormLayout* _form;
|
||||
QDoubleSpinBox* _radius;
|
||||
|
||||
glm::vec3 _position;
|
||||
};
|
||||
|
||||
/// Allows setting voxel colors by moving a sphere around.
|
||||
class VoxelColorSphereTool : public SphereTool {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
VoxelColorSphereTool(MetavoxelEditor* editor);
|
||||
|
||||
virtual bool appliesTo(const AttributePointer& attribute) const;
|
||||
|
||||
protected:
|
||||
|
||||
virtual QColor getColor();
|
||||
|
||||
virtual void applyValue(const glm::vec3& position, float radius);
|
||||
|
||||
private:
|
||||
|
||||
QColorEditor* _color;
|
||||
};
|
||||
|
||||
/// Allows setting voxel materials by moving a sphere around.
|
||||
class VoxelMaterialSphereTool : public SphereTool {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
VoxelMaterialSphereTool(MetavoxelEditor* editor);
|
||||
|
||||
virtual bool appliesTo(const AttributePointer& attribute) const;
|
||||
|
||||
protected:
|
||||
|
||||
virtual QColor getColor();
|
||||
|
||||
virtual void applyValue(const glm::vec3& position, float radius);
|
||||
|
||||
private slots:
|
||||
|
||||
void updateTexture();
|
||||
|
||||
private:
|
||||
|
||||
SharedObjectEditor* _materialEditor;
|
||||
QSharedPointer<NetworkTexture> _texture;
|
||||
};
|
||||
|
||||
#endif // hifi_MetavoxelEditor_h
|
||||
|
|
|
@ -406,6 +406,10 @@ QRgb packNormal(const glm::vec3& normal) {
|
|||
return qRgb((char)(normal.x * CHAR_SCALE), (char)(normal.y * CHAR_SCALE), (char)(normal.z * CHAR_SCALE));
|
||||
}
|
||||
|
||||
QRgb packNormal(const glm::vec3& normal, int alpha) {
|
||||
return qRgba((char)(normal.x * CHAR_SCALE), (char)(normal.y * CHAR_SCALE), (char)(normal.z * CHAR_SCALE), alpha);
|
||||
}
|
||||
|
||||
glm::vec3 unpackNormal(QRgb value) {
|
||||
return glm::vec3((char)qRed(value) * INVERSE_CHAR_SCALE, (char)qGreen(value) * INVERSE_CHAR_SCALE,
|
||||
(char)qBlue(value) * INVERSE_CHAR_SCALE);
|
||||
|
|
|
@ -416,6 +416,9 @@ public:
|
|||
/// Packs a normal into an RGB value.
|
||||
QRgb packNormal(const glm::vec3& normal);
|
||||
|
||||
/// Packs a normal (plus extra alpha value) into an RGBA value.
|
||||
QRgb packNormal(const glm::vec3& normal, int alpha);
|
||||
|
||||
/// Unpacks a normal from an RGB value.
|
||||
glm::vec3 unpackNormal(QRgb value);
|
||||
|
||||
|
|
|
@ -814,3 +814,267 @@ void VoxelMaterialBoxEdit::apply(MetavoxelData& data, const WeakSharedObjectHash
|
|||
VoxelMaterialBoxEditVisitor visitor(region, granularity, material, averageColor);
|
||||
data.guide(visitor);
|
||||
}
|
||||
|
||||
VoxelColorSphereEdit::VoxelColorSphereEdit(const glm::vec3& center, float radius, float granularity, const QColor& color) :
|
||||
center(center),
|
||||
radius(radius),
|
||||
granularity(granularity),
|
||||
color(color) {
|
||||
}
|
||||
|
||||
class VoxelMaterialSphereEditVisitor : public MetavoxelVisitor {
|
||||
public:
|
||||
|
||||
VoxelMaterialSphereEditVisitor(const glm::vec3& center, float radius, const Box& bounds, float granularity,
|
||||
const SharedObjectPointer& material, const QColor& color);
|
||||
|
||||
virtual int visit(MetavoxelInfo& info);
|
||||
|
||||
private:
|
||||
|
||||
glm::vec3 _center;
|
||||
float _radius;
|
||||
Box _bounds;
|
||||
float _granularity;
|
||||
SharedObjectPointer _material;
|
||||
QColor _color;
|
||||
float _blockSize;
|
||||
};
|
||||
|
||||
VoxelMaterialSphereEditVisitor::VoxelMaterialSphereEditVisitor(const glm::vec3& center, float radius, const Box& bounds,
|
||||
float granularity, const SharedObjectPointer& material, const QColor& color) :
|
||||
MetavoxelVisitor(QVector<AttributePointer>() << AttributeRegistry::getInstance()->getVoxelColorAttribute() <<
|
||||
AttributeRegistry::getInstance()->getVoxelHermiteAttribute() <<
|
||||
AttributeRegistry::getInstance()->getVoxelMaterialAttribute(), QVector<AttributePointer>() <<
|
||||
AttributeRegistry::getInstance()->getVoxelColorAttribute() <<
|
||||
AttributeRegistry::getInstance()->getVoxelHermiteAttribute() <<
|
||||
AttributeRegistry::getInstance()->getVoxelMaterialAttribute()),
|
||||
_center(center),
|
||||
_radius(radius),
|
||||
_bounds(bounds),
|
||||
_granularity(granularity),
|
||||
_material(material),
|
||||
_color(color),
|
||||
_blockSize(granularity * VOXEL_BLOCK_SIZE) {
|
||||
}
|
||||
|
||||
int VoxelMaterialSphereEditVisitor::visit(MetavoxelInfo& info) {
|
||||
Box bounds = info.getBounds();
|
||||
if (!bounds.intersects(_bounds)) {
|
||||
return STOP_RECURSION;
|
||||
}
|
||||
if (info.size > _blockSize) {
|
||||
return DEFAULT_ORDER;
|
||||
}
|
||||
VoxelColorDataPointer colorPointer = info.inputValues.at(0).getInlineValue<VoxelColorDataPointer>();
|
||||
QVector<QRgb> colorContents = (colorPointer && colorPointer->getSize() == VOXEL_BLOCK_SAMPLES) ?
|
||||
colorPointer->getContents() : QVector<QRgb>(VOXEL_BLOCK_VOLUME);
|
||||
|
||||
Box overlap = info.getBounds().getIntersection(_bounds);
|
||||
float scale = VOXEL_BLOCK_SIZE / info.size;
|
||||
overlap.minimum = (overlap.minimum - info.minimum) * scale;
|
||||
overlap.maximum = (overlap.maximum - info.minimum) * scale;
|
||||
int minX = glm::ceil(overlap.minimum.x);
|
||||
int minY = glm::ceil(overlap.minimum.y);
|
||||
int minZ = glm::ceil(overlap.minimum.z);
|
||||
int sizeX = (int)overlap.maximum.x - minX + 1;
|
||||
int sizeY = (int)overlap.maximum.y - minY + 1;
|
||||
int sizeZ = (int)overlap.maximum.z - minZ + 1;
|
||||
|
||||
glm::vec3 relativeCenter = (_center - info.minimum) * scale;
|
||||
float relativeRadius = _radius * scale;
|
||||
float relativeRadiusSquared = relativeRadius * relativeRadius;
|
||||
|
||||
QRgb rgb = _color.rgba();
|
||||
glm::vec3 position(0.0f, 0.0f, minZ);
|
||||
for (QRgb* destZ = colorContents.data() + minZ * VOXEL_BLOCK_AREA + minY * VOXEL_BLOCK_SAMPLES + minX,
|
||||
*endZ = destZ + sizeZ * VOXEL_BLOCK_AREA; destZ != endZ; destZ += VOXEL_BLOCK_AREA, position.z++) {
|
||||
position.y = minY;
|
||||
for (QRgb* destY = destZ, *endY = destY + sizeY * VOXEL_BLOCK_SAMPLES; destY != endY;
|
||||
destY += VOXEL_BLOCK_SAMPLES, position.y++) {
|
||||
position.x = minX;
|
||||
for (QRgb* destX = destY, *endX = destX + sizeX; destX != endX; destX++, position.x++) {
|
||||
if (glm::distance(relativeCenter, position) <= relativeRadius) {
|
||||
*destX = rgb;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VoxelColorDataPointer newColorPointer(new VoxelColorData(colorContents, VOXEL_BLOCK_SAMPLES));
|
||||
info.outputValues[0] = AttributeValue(info.inputValues.at(0).getAttribute(),
|
||||
encodeInline<VoxelColorDataPointer>(newColorPointer));
|
||||
|
||||
VoxelHermiteDataPointer hermitePointer = info.inputValues.at(1).getInlineValue<VoxelHermiteDataPointer>();
|
||||
QVector<QRgb> hermiteContents = (hermitePointer && hermitePointer->getSize() == VOXEL_BLOCK_SAMPLES) ?
|
||||
hermitePointer->getContents() : QVector<QRgb>(VOXEL_BLOCK_VOLUME * VoxelHermiteData::EDGE_COUNT);
|
||||
int hermiteArea = VOXEL_BLOCK_AREA * VoxelHermiteData::EDGE_COUNT;
|
||||
int hermiteSamples = VOXEL_BLOCK_SAMPLES * VoxelHermiteData::EDGE_COUNT;
|
||||
|
||||
int hermiteMinX = minX, hermiteMinY = minY, hermiteMinZ = minZ;
|
||||
int hermiteSizeX = sizeX, hermiteSizeY = sizeY, hermiteSizeZ = sizeZ;
|
||||
if (minX > 0) {
|
||||
hermiteMinX--;
|
||||
hermiteSizeX++;
|
||||
}
|
||||
if (minY > 0) {
|
||||
hermiteMinY--;
|
||||
hermiteSizeY++;
|
||||
}
|
||||
if (minZ > 0) {
|
||||
hermiteMinZ--;
|
||||
hermiteSizeZ++;
|
||||
}
|
||||
QRgb* hermiteDestZ = hermiteContents.data() + hermiteMinZ * hermiteArea + hermiteMinY * hermiteSamples +
|
||||
hermiteMinX * VoxelHermiteData::EDGE_COUNT;
|
||||
for (int z = hermiteMinZ, hermiteMaxZ = z + hermiteSizeZ - 1; z <= hermiteMaxZ; z++, hermiteDestZ += hermiteArea) {
|
||||
QRgb* hermiteDestY = hermiteDestZ;
|
||||
for (int y = hermiteMinY, hermiteMaxY = y + hermiteSizeY - 1; y <= hermiteMaxY; y++, hermiteDestY += hermiteSamples) {
|
||||
QRgb* hermiteDestX = hermiteDestY;
|
||||
for (int x = hermiteMinX, hermiteMaxX = x + hermiteSizeX - 1; x <= hermiteMaxX; x++,
|
||||
hermiteDestX += VoxelHermiteData::EDGE_COUNT) {
|
||||
hermiteDestX[0] = 0x0;
|
||||
glm::vec3 offset(x - relativeCenter.x, y - relativeCenter.y, z - relativeCenter.z);
|
||||
if (x != VOXEL_BLOCK_SIZE) {
|
||||
const QRgb* color = colorContents.constData() + z * VOXEL_BLOCK_AREA + y * VOXEL_BLOCK_SAMPLES + x;
|
||||
int alpha0 = qAlpha(color[0]);
|
||||
if (alpha0 != qAlpha(color[1])) {
|
||||
float radicand = relativeRadiusSquared - offset.y * offset.y - offset.z * offset.z;
|
||||
float parameter = 0.5f;
|
||||
if (radicand >= 0.0f) {
|
||||
float root = glm::sqrt(radicand);
|
||||
parameter = -offset.x - root;
|
||||
if (parameter < 0.0f || parameter > 1.0f) {
|
||||
parameter = glm::clamp(-offset.x + root, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
glm::vec3 normal = offset + glm::vec3(parameter, 0.0f, 0.0f);
|
||||
float length = glm::length(normal);
|
||||
if (length > EPSILON) {
|
||||
normal /= length;
|
||||
} else {
|
||||
normal = glm::vec3(0.0f, 1.0f, 0.0f);
|
||||
}
|
||||
hermiteDestX[0] = packNormal(normal, parameter * EIGHT_BIT_MAXIMUM);
|
||||
}
|
||||
}
|
||||
hermiteDestX[1] = 0x0;
|
||||
if (y != VOXEL_BLOCK_SIZE) {
|
||||
const QRgb* color = colorContents.constData() + z * VOXEL_BLOCK_AREA + y * VOXEL_BLOCK_SAMPLES + x;
|
||||
int alpha0 = qAlpha(color[0]);
|
||||
if (alpha0 != qAlpha(color[VOXEL_BLOCK_SAMPLES])) {
|
||||
float radicand = relativeRadiusSquared - offset.x * offset.x - offset.z * offset.z;
|
||||
float parameter = 0.5f;
|
||||
if (radicand >= 0.0f) {
|
||||
float root = glm::sqrt(radicand);
|
||||
parameter = -offset.y - root;
|
||||
if (parameter < 0.0f || parameter > 1.0f) {
|
||||
parameter = glm::clamp(-offset.y + root, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
glm::vec3 normal = offset + glm::vec3(parameter, 0.0f, 0.0f);
|
||||
float length = glm::length(normal);
|
||||
if (length > EPSILON) {
|
||||
normal /= length;
|
||||
} else {
|
||||
normal = glm::vec3(1.0f, 0.0f, 0.0f);
|
||||
}
|
||||
hermiteDestX[1] = packNormal(normal, parameter * EIGHT_BIT_MAXIMUM);
|
||||
}
|
||||
}
|
||||
hermiteDestX[2] = 0x0;
|
||||
if (z != VOXEL_BLOCK_SIZE) {
|
||||
const QRgb* color = colorContents.constData() + z * VOXEL_BLOCK_AREA + y * VOXEL_BLOCK_SAMPLES + x;
|
||||
int alpha0 = qAlpha(color[0]);
|
||||
if (alpha0 != qAlpha(color[VOXEL_BLOCK_AREA])) {
|
||||
float radicand = relativeRadiusSquared - offset.x * offset.x - offset.y * offset.y;
|
||||
float parameter = 0.5f;
|
||||
if (radicand >= 0.0f) {
|
||||
float root = glm::sqrt(radicand);
|
||||
parameter = -offset.z - root;
|
||||
if (parameter < 0.0f || parameter > 1.0f) {
|
||||
parameter = glm::clamp(-offset.z + root, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
glm::vec3 normal = offset + glm::vec3(parameter, 0.0f, 0.0f);
|
||||
float length = glm::length(normal);
|
||||
if (length > EPSILON) {
|
||||
normal /= length;
|
||||
} else {
|
||||
normal = glm::vec3(1.0f, 0.0f, 0.0f);
|
||||
}
|
||||
hermiteDestX[2] = packNormal(normal, parameter * EIGHT_BIT_MAXIMUM);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VoxelHermiteDataPointer newHermitePointer(new VoxelHermiteData(hermiteContents, VOXEL_BLOCK_SAMPLES));
|
||||
info.outputValues[1] = AttributeValue(info.inputValues.at(1).getAttribute(),
|
||||
encodeInline<VoxelHermiteDataPointer>(newHermitePointer));
|
||||
|
||||
VoxelMaterialDataPointer materialPointer = info.inputValues.at(2).getInlineValue<VoxelMaterialDataPointer>();
|
||||
QByteArray materialContents;
|
||||
QVector<SharedObjectPointer> materials;
|
||||
if (materialPointer && materialPointer->getSize() == VOXEL_BLOCK_SAMPLES) {
|
||||
materialContents = materialPointer->getContents();
|
||||
materials = materialPointer->getMaterials();
|
||||
|
||||
} else {
|
||||
materialContents = QByteArray(VOXEL_BLOCK_VOLUME, 0);
|
||||
}
|
||||
|
||||
uchar materialIndex = getMaterialIndex(_material, materials, materialContents);
|
||||
position.z = minZ;
|
||||
for (uchar* destZ = (uchar*)materialContents.data() + minZ * VOXEL_BLOCK_AREA + minY * VOXEL_BLOCK_SAMPLES + minX,
|
||||
*endZ = destZ + sizeZ * VOXEL_BLOCK_AREA; destZ != endZ; destZ += VOXEL_BLOCK_AREA, position.z++) {
|
||||
position.y = minY;
|
||||
for (uchar* destY = destZ, *endY = destY + sizeY * VOXEL_BLOCK_SAMPLES; destY != endY;
|
||||
destY += VOXEL_BLOCK_SAMPLES, position.y++) {
|
||||
position.x = minX;
|
||||
for (uchar* destX = destY, *endX = destX + sizeX; destX != endX; destX++, position.x++) {
|
||||
if (glm::distance(relativeCenter, position) <= relativeRadius) {
|
||||
*destX = materialIndex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clearUnusedMaterials(materials, materialContents);
|
||||
VoxelMaterialDataPointer newMaterialPointer(new VoxelMaterialData(materialContents, VOXEL_BLOCK_SAMPLES, materials));
|
||||
info.outputValues[2] = AttributeValue(_inputs.at(2), encodeInline<VoxelMaterialDataPointer>(newMaterialPointer));
|
||||
|
||||
return STOP_RECURSION;
|
||||
}
|
||||
|
||||
void VoxelColorSphereEdit::apply(MetavoxelData& data, const WeakSharedObjectHash& objects) const {
|
||||
// expand to fit the entire edit
|
||||
glm::vec3 extents(radius, radius, radius);
|
||||
Box bounds(center - extents, center + extents);
|
||||
while (!data.getBounds().contains(bounds)) {
|
||||
data.expand();
|
||||
}
|
||||
VoxelMaterialSphereEditVisitor visitor(center, radius, bounds, granularity, SharedObjectPointer(), color);
|
||||
data.guide(visitor);
|
||||
}
|
||||
|
||||
VoxelMaterialSphereEdit::VoxelMaterialSphereEdit(const glm::vec3& center, float radius, float granularity,
|
||||
const SharedObjectPointer& material, const QColor& averageColor) :
|
||||
center(center),
|
||||
radius(radius),
|
||||
granularity(granularity),
|
||||
material(material),
|
||||
averageColor(averageColor) {
|
||||
}
|
||||
|
||||
void VoxelMaterialSphereEdit::apply(MetavoxelData& data, const WeakSharedObjectHash& objects) const {
|
||||
// expand to fit the entire edit
|
||||
glm::vec3 extents(radius, radius, radius);
|
||||
Box bounds(center - extents, center + extents);
|
||||
while (!data.getBounds().contains(bounds)) {
|
||||
data.expand();
|
||||
}
|
||||
VoxelMaterialSphereEditVisitor visitor(center, radius, bounds, granularity, material, averageColor);
|
||||
data.guide(visitor);
|
||||
}
|
||||
|
|
|
@ -296,4 +296,43 @@ public:
|
|||
|
||||
DECLARE_STREAMABLE_METATYPE(VoxelMaterialBoxEdit)
|
||||
|
||||
/// An edit that sets the color of voxels within a sphere to a value.
|
||||
class VoxelColorSphereEdit : public MetavoxelEdit {
|
||||
STREAMABLE
|
||||
|
||||
public:
|
||||
|
||||
STREAM glm::vec3 center;
|
||||
STREAM float radius;
|
||||
STREAM float granularity;
|
||||
STREAM QColor color;
|
||||
|
||||
VoxelColorSphereEdit(const glm::vec3& center = glm::vec3(), float radius = 0.0f,
|
||||
float granularity = 0.0f, const QColor& color = QColor());
|
||||
|
||||
virtual void apply(MetavoxelData& data, const WeakSharedObjectHash& objects) const;
|
||||
};
|
||||
|
||||
DECLARE_STREAMABLE_METATYPE(VoxelColorSphereEdit)
|
||||
|
||||
/// An edit that sets the materials of voxels within a sphere to a value.
|
||||
class VoxelMaterialSphereEdit : public MetavoxelEdit {
|
||||
STREAMABLE
|
||||
|
||||
public:
|
||||
|
||||
STREAM glm::vec3 center;
|
||||
STREAM float radius;
|
||||
STREAM float granularity;
|
||||
STREAM SharedObjectPointer material;
|
||||
STREAM QColor averageColor;
|
||||
|
||||
VoxelMaterialSphereEdit(const glm::vec3& center = glm::vec3(), float radius = 0.0f, float granularity = 0.0f,
|
||||
const SharedObjectPointer& material = SharedObjectPointer(), const QColor& averageColor = QColor());
|
||||
|
||||
virtual void apply(MetavoxelData& data, const WeakSharedObjectHash& objects) const;
|
||||
};
|
||||
|
||||
DECLARE_STREAMABLE_METATYPE(VoxelMaterialSphereEdit)
|
||||
|
||||
#endif // hifi_MetavoxelMessages_h
|
||||
|
|
Loading…
Reference in a new issue