mirror of
https://github.com/overte-org/overte.git
synced 2025-04-09 15:22:27 +02:00
Merge pull request #2614 from Atlante45/undo_redo_system
Undo redo system
This commit is contained in:
commit
8e097be28d
9 changed files with 274 additions and 51 deletions
|
@ -921,7 +921,6 @@ function mousePressEvent(event) {
|
|||
}
|
||||
|
||||
voxelDetails = calculateVoxelFromIntersection(intersection,"add");
|
||||
Voxels.eraseVoxel(voxelDetails.x, voxelDetails.y, voxelDetails.z, voxelDetails.s);
|
||||
Voxels.setVoxel(voxelDetails.x, voxelDetails.y, voxelDetails.z, voxelDetails.s,
|
||||
newColor.red, newColor.green, newColor.blue);
|
||||
lastVoxelPosition = { x: voxelDetails.x, y: voxelDetails.y, z: voxelDetails.z };
|
||||
|
|
|
@ -3280,6 +3280,7 @@ void Application::loadScript(const QString& scriptName) {
|
|||
// we can use the same ones from the application.
|
||||
scriptEngine->getVoxelsScriptingInterface()->setPacketSender(&_voxelEditSender);
|
||||
scriptEngine->getVoxelsScriptingInterface()->setVoxelTree(_voxels.getTree());
|
||||
scriptEngine->getVoxelsScriptingInterface()->setUndoStack(&_undoStack);
|
||||
scriptEngine->getParticlesScriptingInterface()->setPacketSender(&_particleEditSender);
|
||||
scriptEngine->getParticlesScriptingInterface()->setParticleTree(_particles.getTree());
|
||||
|
||||
|
|
|
@ -14,14 +14,15 @@
|
|||
|
||||
#include <QApplication>
|
||||
#include <QAction>
|
||||
#include <QImage>
|
||||
#include <QSettings>
|
||||
#include <QTouchEvent>
|
||||
#include <QList>
|
||||
#include <QSet>
|
||||
#include <QStringList>
|
||||
#include <QPointer>
|
||||
#include <QHash>
|
||||
#include <QImage>
|
||||
#include <QList>
|
||||
#include <QPointer>
|
||||
#include <QSet>
|
||||
#include <QSettings>
|
||||
#include <QStringList>
|
||||
#include <QTouchEvent>
|
||||
#include <QUndoStack>
|
||||
|
||||
#include <NetworkPacket.h>
|
||||
#include <NodeList.h>
|
||||
|
@ -176,6 +177,7 @@ public:
|
|||
Visage* getVisage() { return &_visage; }
|
||||
SixenseManager* getSixenseManager() { return &_sixenseManager; }
|
||||
BandwidthMeter* getBandwidthMeter() { return &_bandwidthMeter; }
|
||||
QUndoStack* getUndoStack() { return &_undoStack; }
|
||||
|
||||
/// if you need to access the application settings, use lockSettings()/unlockSettings()
|
||||
QSettings* lockSettings() { _settingsMutex.lock(); return _settings; }
|
||||
|
@ -366,6 +368,8 @@ private:
|
|||
QMutex _settingsMutex;
|
||||
QSettings* _settings;
|
||||
|
||||
QUndoStack _undoStack;
|
||||
|
||||
glm::vec3 _gravity;
|
||||
|
||||
// Frame Rate Measurement
|
||||
|
|
|
@ -161,6 +161,15 @@ Menu::Menu() :
|
|||
|
||||
|
||||
QMenu* editMenu = addMenu("Edit");
|
||||
|
||||
QUndoStack* undoStack = Application::getInstance()->getUndoStack();
|
||||
QAction* undoAction = undoStack->createUndoAction(editMenu);
|
||||
undoAction->setShortcut(Qt::CTRL | Qt::Key_Z);
|
||||
addActionToQMenuAndActionHash(editMenu, undoAction);
|
||||
|
||||
QAction* redoAction = undoStack->createRedoAction(editMenu);
|
||||
redoAction->setShortcut(Qt::CTRL | Qt::SHIFT | Qt::Key_Z);
|
||||
addActionToQMenuAndActionHash(editMenu, redoAction);
|
||||
|
||||
addActionToQMenuAndActionHash(editMenu,
|
||||
MenuOption::Preferences,
|
||||
|
@ -620,6 +629,41 @@ QAction* Menu::addActionToQMenuAndActionHash(QMenu* destinationMenu,
|
|||
return action;
|
||||
}
|
||||
|
||||
QAction* Menu::addActionToQMenuAndActionHash(QMenu* destinationMenu,
|
||||
QAction* action,
|
||||
const QString& actionName,
|
||||
const QKeySequence& shortcut,
|
||||
QAction::MenuRole role,
|
||||
int menuItemLocation) {
|
||||
QAction* actionBefore = NULL;
|
||||
|
||||
if (menuItemLocation >= 0 && destinationMenu->actions().size() > menuItemLocation) {
|
||||
actionBefore = destinationMenu->actions()[menuItemLocation];
|
||||
}
|
||||
|
||||
if (!actionName.isEmpty()) {
|
||||
action->setText(actionName);
|
||||
}
|
||||
|
||||
if (shortcut != 0) {
|
||||
action->setShortcut(shortcut);
|
||||
}
|
||||
|
||||
if (role != QAction::NoRole) {
|
||||
action->setMenuRole(role);
|
||||
}
|
||||
|
||||
if (!actionBefore) {
|
||||
destinationMenu->addAction(action);
|
||||
} else {
|
||||
destinationMenu->insertAction(actionBefore, action);
|
||||
}
|
||||
|
||||
_actionHash.insert(action->text(), action);
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
QAction* Menu::addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu,
|
||||
const QString& actionName,
|
||||
const QKeySequence& shortcut,
|
||||
|
|
|
@ -102,7 +102,13 @@ public:
|
|||
const char* member = NULL,
|
||||
QAction::MenuRole role = QAction::NoRole,
|
||||
int menuItemLocation = UNSPECIFIED_POSITION);
|
||||
|
||||
QAction* addActionToQMenuAndActionHash(QMenu* destinationMenu,
|
||||
QAction* action,
|
||||
const QString& actionName = QString(),
|
||||
const QKeySequence& shortcut = 0,
|
||||
QAction::MenuRole role = QAction::NoRole,
|
||||
int menuItemLocation = UNSPECIFIED_POSITION);
|
||||
|
||||
void removeAction(QMenu* menu, const QString& actionName);
|
||||
|
||||
bool goToDestination(QString destination);
|
||||
|
@ -219,65 +225,65 @@ private:
|
|||
namespace MenuOption {
|
||||
const QString AboutApp = "About Interface";
|
||||
const QString AmbientOcclusion = "Ambient Occlusion";
|
||||
const QString Avatars = "Avatars";
|
||||
const QString Atmosphere = "Atmosphere";
|
||||
const QString DisableAutoAdjustLOD = "Disable Automatically Adjusting LOD";
|
||||
const QString AudioNoiseReduction = "Audio Noise Reduction";
|
||||
const QString AudioToneInjection = "Inject Test Tone";
|
||||
const QString Avatars = "Avatars";
|
||||
const QString Bandwidth = "Bandwidth Display";
|
||||
const QString BandwidthDetails = "Bandwidth Details";
|
||||
const QString BuckyBalls = "Bucky Balls";
|
||||
const QString Chat = "Chat...";
|
||||
const QString ChatCircling = "Chat Circling";
|
||||
const QString Collisions = "Collisions";
|
||||
const QString CollideWithAvatars = "Collide With Avatars";
|
||||
const QString CollideWithEnvironment = "Collide With World Boundaries";
|
||||
const QString CollideWithParticles = "Collide With Particles";
|
||||
const QString CollideWithVoxels = "Collide With Voxels";
|
||||
const QString CollideWithEnvironment = "Collide With World Boundaries";
|
||||
const QString Collisions = "Collisions";
|
||||
const QString CullSharedFaces = "Cull Shared Voxel Faces";
|
||||
const QString DecreaseAvatarSize = "Decrease Avatar Size";
|
||||
const QString DecreaseVoxelSize = "Decrease Voxel Size";
|
||||
const QString DisableAutoAdjustLOD = "Disable Automatically Adjusting LOD";
|
||||
const QString DisplayFrustum = "Display Frustum";
|
||||
const QString DisplayHands = "Display Hands";
|
||||
const QString DisplayHandTargets = "Display Hand Targets";
|
||||
const QString FilterSixense = "Smooth Sixense Movement";
|
||||
const QString Enable3DTVMode = "Enable 3DTV Mode";
|
||||
const QString AudioNoiseReduction = "Audio Noise Reduction";
|
||||
const QString AudioToneInjection = "Inject Test Tone";
|
||||
const QString EchoServerAudio = "Echo Server Audio";
|
||||
const QString EchoLocalAudio = "Echo Local Audio";
|
||||
const QString MuteAudio = "Mute Microphone";
|
||||
const QString DontFadeOnVoxelServerChanges = "Don't Fade In/Out on Voxel Server Changes";
|
||||
const QString HeadMouse = "Head Mouse";
|
||||
const QString HandsCollideWithSelf = "Collide With Self";
|
||||
const QString EchoLocalAudio = "Echo Local Audio";
|
||||
const QString EchoServerAudio = "Echo Server Audio";
|
||||
const QString Enable3DTVMode = "Enable 3DTV Mode";
|
||||
const QString Faceshift = "Faceshift";
|
||||
const QString FilterSixense = "Smooth Sixense Movement";
|
||||
const QString FirstPerson = "First Person";
|
||||
const QString FrameTimer = "Show Timer";
|
||||
const QString FrustumRenderMode = "Render Mode";
|
||||
const QString Fullscreen = "Fullscreen";
|
||||
const QString FullscreenMirror = "Fullscreen Mirror";
|
||||
const QString GlowMode = "Cycle Glow Mode";
|
||||
const QString GoHome = "Go Home";
|
||||
const QString GoTo = "Go To...";
|
||||
const QString GoToDomain = "Go To Domain...";
|
||||
const QString GoToLocation = "Go To Location...";
|
||||
const QString NameLocation = "Name this location";
|
||||
const QString GoTo = "Go To...";
|
||||
const QString Gravity = "Use Gravity";
|
||||
const QString HandsCollideWithSelf = "Collide With Self";
|
||||
const QString HeadMouse = "Head Mouse";
|
||||
const QString IncreaseAvatarSize = "Increase Avatar Size";
|
||||
const QString IncreaseVoxelSize = "Increase Voxel Size";
|
||||
const QString GoHome = "Go Home";
|
||||
const QString Gravity = "Use Gravity";
|
||||
const QString LoadScript = "Open and Run Script File...";
|
||||
const QString LoadScriptURL = "Open and Run Script from URL...";
|
||||
const QString LodTools = "LOD Tools";
|
||||
const QString Log = "Log";
|
||||
const QString Login = "Login";
|
||||
const QString Logout = "Logout";
|
||||
const QString LookAtVectors = "Look-at Vectors";
|
||||
const QString MetavoxelEditor = "Metavoxel Editor...";
|
||||
const QString Chat = "Chat...";
|
||||
const QString Metavoxels = "Metavoxels";
|
||||
const QString Mirror = "Mirror";
|
||||
const QString MoveWithLean = "Move with Lean";
|
||||
const QString MuteAudio = "Mute Microphone";
|
||||
const QString NameLocation = "Name this location";
|
||||
const QString NewVoxelCullingMode = "New Voxel Culling Mode";
|
||||
const QString OctreeStats = "Voxel and Particle Statistics";
|
||||
const QString OffAxisProjection = "Off-Axis Projection";
|
||||
const QString OldVoxelCullingMode = "Old Voxel Culling Mode";
|
||||
const QString TurnWithHead = "Turn using Head";
|
||||
const QString LoadScript = "Open and Run Script File...";
|
||||
const QString LoadScriptURL = "Open and Run Script from URL...";
|
||||
const QString Oscilloscope = "Audio Oscilloscope";
|
||||
const QString Pair = "Pair";
|
||||
const QString Particles = "Particles";
|
||||
|
@ -285,30 +291,30 @@ namespace MenuOption {
|
|||
const QString PipelineWarnings = "Show Render Pipeline Warnings";
|
||||
const QString PlaySlaps = "Play Slaps";
|
||||
const QString Preferences = "Preferences...";
|
||||
const QString Quit = "Quit";
|
||||
const QString ReloadAllScripts = "Reload All Scripts";
|
||||
const QString RenderSkeletonCollisionShapes = "Skeleton Collision Shapes";
|
||||
const QString RenderHeadCollisionShapes = "Head Collision Shapes";
|
||||
const QString RenderBoundingCollisionShapes = "Bounding Collision Shapes";
|
||||
const QString RenderHeadCollisionShapes = "Head Collision Shapes";
|
||||
const QString RenderSkeletonCollisionShapes = "Skeleton Collision Shapes";
|
||||
const QString ResetAvatarSize = "Reset Avatar Size";
|
||||
const QString RunningScripts = "Running Scripts";
|
||||
const QString RunTimingTests = "Run Timing Tests";
|
||||
const QString SettingsExport = "Export Settings";
|
||||
const QString SettingsImport = "Import Settings";
|
||||
const QString Shadows = "Shadows";
|
||||
const QString SettingsExport = "Export Settings";
|
||||
const QString ShowCulledSharedFaces = "Show Culled Shared Voxel Faces";
|
||||
const QString SuppressShortTimings = "Suppress Timings Less than 10ms";
|
||||
const QString Stars = "Stars";
|
||||
const QString Stats = "Stats";
|
||||
const QString StopAllScripts = "Stop All Scripts";
|
||||
const QString SuppressShortTimings = "Suppress Timings Less than 10ms";
|
||||
const QString TestPing = "Test Ping";
|
||||
const QString TransmitterDrive = "Transmitter Drive";
|
||||
const QString TurnWithHead = "Turn using Head";
|
||||
const QString UploadHead = "Upload Head Model";
|
||||
const QString UploadSkeleton = "Upload Skeleton Model";
|
||||
const QString Visage = "Visage";
|
||||
const QString Quit = "Quit";
|
||||
const QString Voxels = "Voxels";
|
||||
const QString VoxelMode = "Cycle Voxel Mode";
|
||||
const QString OctreeStats = "Voxel and Particle Statistics";
|
||||
const QString Voxels = "Voxels";
|
||||
const QString VoxelTextures = "Voxel Textures";
|
||||
}
|
||||
|
||||
|
|
64
libraries/voxels/src/VoxelTreeCommands.cpp
Normal file
64
libraries/voxels/src/VoxelTreeCommands.cpp
Normal file
|
@ -0,0 +1,64 @@
|
|||
//
|
||||
// VoxelTreeCommands.cpp
|
||||
// hifi
|
||||
//
|
||||
// Created by Clement on 4/4/14.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
//
|
||||
|
||||
#include "VoxelTree.h"
|
||||
|
||||
#include "VoxelTreeCommands.h"
|
||||
|
||||
AddVoxelCommand::AddVoxelCommand(VoxelTree* tree, VoxelDetail& voxel, VoxelEditPacketSender* packetSender, QUndoCommand* parent) :
|
||||
QUndoCommand("Add Voxel", parent),
|
||||
_tree(tree),
|
||||
_packetSender(packetSender),
|
||||
_voxel(voxel)
|
||||
{
|
||||
}
|
||||
|
||||
void AddVoxelCommand::redo() {
|
||||
if (_tree) {
|
||||
_tree->createVoxel(_voxel.x, _voxel.y, _voxel.z, _voxel.s, _voxel.red, _voxel.green, _voxel.blue);
|
||||
}
|
||||
if (_packetSender) {
|
||||
_packetSender->queueVoxelEditMessages(PacketTypeVoxelSet, 1, &_voxel);
|
||||
}
|
||||
}
|
||||
|
||||
void AddVoxelCommand::undo() {
|
||||
if (_tree) {
|
||||
_tree->deleteVoxelAt(_voxel.x, _voxel.y, _voxel.z, _voxel.s);
|
||||
}
|
||||
if (_packetSender) {
|
||||
_packetSender->queueVoxelEditMessages(PacketTypeVoxelErase, 1, &_voxel);
|
||||
}
|
||||
}
|
||||
|
||||
DeleteVoxelCommand::DeleteVoxelCommand(VoxelTree* tree, VoxelDetail& voxel, VoxelEditPacketSender* packetSender, QUndoCommand* parent) :
|
||||
QUndoCommand("Delete Voxel", parent),
|
||||
_tree(tree),
|
||||
_packetSender(packetSender),
|
||||
_voxel(voxel)
|
||||
{
|
||||
}
|
||||
|
||||
void DeleteVoxelCommand::redo() {
|
||||
if (_tree) {
|
||||
_tree->deleteVoxelAt(_voxel.x, _voxel.y, _voxel.z, _voxel.s);
|
||||
}
|
||||
if (_packetSender) {
|
||||
_packetSender->queueVoxelEditMessages(PacketTypeVoxelErase, 1, &_voxel);
|
||||
}
|
||||
}
|
||||
|
||||
void DeleteVoxelCommand::undo() {
|
||||
if (_tree) {
|
||||
_tree->createVoxel(_voxel.x, _voxel.y, _voxel.z, _voxel.s, _voxel.red, _voxel.green, _voxel.blue);
|
||||
}
|
||||
if (_packetSender) {
|
||||
_packetSender->queueVoxelEditMessages(PacketTypeVoxelSet, 1, &_voxel);
|
||||
}
|
||||
}
|
46
libraries/voxels/src/VoxelTreeCommands.h
Normal file
46
libraries/voxels/src/VoxelTreeCommands.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// VoxelTreeCommands.h
|
||||
// hifi
|
||||
//
|
||||
// Created by Clement on 4/4/14.
|
||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __hifi__VoxelTreeCommands__
|
||||
#define __hifi__VoxelTreeCommands__
|
||||
|
||||
#include <QRgb>
|
||||
#include <QUndoCommand>
|
||||
|
||||
#include "VoxelDetail.h"
|
||||
#include "VoxelEditPacketSender.h"
|
||||
|
||||
class VoxelTree;
|
||||
|
||||
class AddVoxelCommand : public QUndoCommand {
|
||||
public:
|
||||
AddVoxelCommand(VoxelTree* tree, VoxelDetail& voxel, VoxelEditPacketSender* packetSender = NULL, QUndoCommand* parent = NULL);
|
||||
|
||||
virtual void redo();
|
||||
virtual void undo();
|
||||
|
||||
private:
|
||||
VoxelTree* _tree;
|
||||
VoxelEditPacketSender* _packetSender;
|
||||
VoxelDetail _voxel;
|
||||
};
|
||||
|
||||
class DeleteVoxelCommand : public QUndoCommand {
|
||||
public:
|
||||
DeleteVoxelCommand(VoxelTree* tree, VoxelDetail& voxel, VoxelEditPacketSender* packetSender = NULL, QUndoCommand* parent = NULL);
|
||||
|
||||
virtual void redo();
|
||||
virtual void undo();
|
||||
|
||||
private:
|
||||
VoxelTree* _tree;
|
||||
VoxelEditPacketSender* _packetSender;
|
||||
VoxelDetail _voxel;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__VoxelTreeCommands__) */
|
|
@ -6,6 +6,8 @@
|
|||
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#include "VoxelTreeCommands.h"
|
||||
|
||||
#include "VoxelsScriptingInterface.h"
|
||||
|
||||
void VoxelsScriptingInterface::queueVoxelAdd(PacketType addPacketType, VoxelDetail& addVoxelDetails) {
|
||||
|
@ -37,17 +39,26 @@ VoxelDetail VoxelsScriptingInterface::getVoxelAt(float x, float y, float z, floa
|
|||
}
|
||||
|
||||
void VoxelsScriptingInterface::setVoxelNonDestructive(float x, float y, float z, float scale,
|
||||
uchar red, uchar green, uchar blue) {
|
||||
uchar red, uchar green, uchar blue) {
|
||||
// setup a VoxelDetail struct with the data
|
||||
VoxelDetail addVoxelDetail = {x / (float)TREE_SCALE, y / (float)TREE_SCALE, z / (float)TREE_SCALE,
|
||||
VoxelDetail addVoxelDetail = {x / (float)TREE_SCALE, y / (float)TREE_SCALE, z / (float)TREE_SCALE,
|
||||
scale / (float)TREE_SCALE, red, green, blue};
|
||||
|
||||
// queue the add packet
|
||||
queueVoxelAdd(PacketTypeVoxelSet, addVoxelDetail);
|
||||
|
||||
// handle the local tree also...
|
||||
if (_tree) {
|
||||
_tree->createVoxel(addVoxelDetail.x, addVoxelDetail.y, addVoxelDetail.z, addVoxelDetail.s, red, green, blue, false);
|
||||
if (_undoStack) {
|
||||
AddVoxelCommand* command = new AddVoxelCommand(_tree,
|
||||
addVoxelDetail,
|
||||
getVoxelPacketSender());
|
||||
|
||||
// As QUndoStack automatically executes redo() on push, we don't need to execute the command ourselves.
|
||||
_undoStack->push(command);
|
||||
} else {
|
||||
// queue the add packet
|
||||
queueVoxelAdd(PacketTypeVoxelSet, addVoxelDetail);
|
||||
_tree->createVoxel(addVoxelDetail.x, addVoxelDetail.y, addVoxelDetail.z, addVoxelDetail.s, red, green, blue, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,26 +68,70 @@ void VoxelsScriptingInterface::setVoxel(float x, float y, float z, float scale,
|
|||
VoxelDetail addVoxelDetail = {x / (float)TREE_SCALE, y / (float)TREE_SCALE, z / (float)TREE_SCALE,
|
||||
scale / (float)TREE_SCALE, red, green, blue};
|
||||
|
||||
// queue the destructive add
|
||||
queueVoxelAdd(PacketTypeVoxelSetDestructive, addVoxelDetail);
|
||||
|
||||
// handle the local tree also...
|
||||
if (_tree) {
|
||||
_tree->createVoxel(addVoxelDetail.x, addVoxelDetail.y, addVoxelDetail.z, addVoxelDetail.s, red, green, blue, true);
|
||||
if (_undoStack) {
|
||||
AddVoxelCommand* addCommand = new AddVoxelCommand(_tree,
|
||||
addVoxelDetail,
|
||||
getVoxelPacketSender());
|
||||
|
||||
VoxelTreeElement* deleteVoxelElement = _tree->getVoxelAt(addVoxelDetail.x, addVoxelDetail.y, addVoxelDetail.z, addVoxelDetail.s);
|
||||
if (deleteVoxelElement) {
|
||||
nodeColor color;
|
||||
memcpy(&color, &deleteVoxelElement->getColor(), sizeof(nodeColor));
|
||||
VoxelDetail deleteVoxelDetail = {addVoxelDetail.x,
|
||||
addVoxelDetail.y,
|
||||
addVoxelDetail.z,
|
||||
addVoxelDetail.s,
|
||||
color[0],
|
||||
color[1],
|
||||
color[2]};
|
||||
DeleteVoxelCommand* delCommand = new DeleteVoxelCommand(_tree,
|
||||
deleteVoxelDetail,
|
||||
getVoxelPacketSender());
|
||||
_undoStack->beginMacro(addCommand->text());
|
||||
// As QUndoStack automatically executes redo() on push, we don't need to execute the command ourselves.
|
||||
_undoStack->push(delCommand);
|
||||
_undoStack->push(addCommand);
|
||||
_undoStack->endMacro();
|
||||
} else {
|
||||
// As QUndoStack automatically executes redo() on push, we don't need to execute the command ourselves.
|
||||
_undoStack->push(addCommand);
|
||||
}
|
||||
} else {
|
||||
// queue the destructive add
|
||||
queueVoxelAdd(PacketTypeVoxelSetDestructive, addVoxelDetail);
|
||||
_tree->createVoxel(addVoxelDetail.x, addVoxelDetail.y, addVoxelDetail.z, addVoxelDetail.s, red, green, blue, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VoxelsScriptingInterface::eraseVoxel(float x, float y, float z, float scale) {
|
||||
|
||||
// setup a VoxelDetail struct with data
|
||||
VoxelDetail deleteVoxelDetail = {x / (float)TREE_SCALE, y / (float)TREE_SCALE, z / (float)TREE_SCALE,
|
||||
scale / (float)TREE_SCALE, 0, 0, 0};
|
||||
VoxelDetail deleteVoxelDetail = {x / (float)TREE_SCALE, y / (float)TREE_SCALE, z / (float)TREE_SCALE,
|
||||
scale / (float)TREE_SCALE};
|
||||
|
||||
getVoxelPacketSender()->queueVoxelEditMessages(PacketTypeVoxelErase, 1, &deleteVoxelDetail);
|
||||
|
||||
// handle the local tree also...
|
||||
if (_tree) {
|
||||
_tree->deleteVoxelAt(deleteVoxelDetail.x, deleteVoxelDetail.y, deleteVoxelDetail.z, deleteVoxelDetail.s);
|
||||
VoxelTreeElement* deleteVoxelElement = _tree->getVoxelAt(deleteVoxelDetail.x, deleteVoxelDetail.y, deleteVoxelDetail.z, deleteVoxelDetail.s);
|
||||
if (deleteVoxelElement) {
|
||||
deleteVoxelDetail.red = deleteVoxelElement->getColor()[0];
|
||||
deleteVoxelDetail.green = deleteVoxelElement->getColor()[1];
|
||||
deleteVoxelDetail.blue = deleteVoxelElement->getColor()[2];
|
||||
}
|
||||
|
||||
if (_undoStack) {
|
||||
DeleteVoxelCommand* command = new DeleteVoxelCommand(_tree,
|
||||
deleteVoxelDetail,
|
||||
getVoxelPacketSender());
|
||||
// As QUndoStack automatically executes redo() on push, we don't need to execute the command ourselves.
|
||||
_undoStack->push(command);
|
||||
} else {
|
||||
getVoxelPacketSender()->queueVoxelEditMessages(PacketTypeVoxelErase, 1, &deleteVoxelDetail);
|
||||
_tree->deleteVoxelAt(deleteVoxelDetail.x, deleteVoxelDetail.y, deleteVoxelDetail.z, deleteVoxelDetail.s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,16 +18,19 @@
|
|||
#include "VoxelEditPacketSender.h"
|
||||
#include "VoxelTree.h"
|
||||
|
||||
class QUndoStack;
|
||||
|
||||
/// handles scripting of voxel commands from JS passed to assigned clients
|
||||
class VoxelsScriptingInterface : public OctreeScriptingInterface {
|
||||
Q_OBJECT
|
||||
public:
|
||||
VoxelsScriptingInterface() : _tree(NULL) {};
|
||||
VoxelsScriptingInterface() : _tree(NULL), _undoStack(NULL) {};
|
||||
VoxelEditPacketSender* getVoxelPacketSender() { return (VoxelEditPacketSender*)getPacketSender(); }
|
||||
|
||||
virtual NodeType_t getServerNodeType() const { return NodeType::VoxelServer; }
|
||||
virtual OctreeEditPacketSender* createPacketSender() { return new VoxelEditPacketSender(); }
|
||||
void setVoxelTree(VoxelTree* tree) { _tree = tree; }
|
||||
void setUndoStack(QUndoStack* undoStack) { _undoStack = undoStack; }
|
||||
|
||||
public slots:
|
||||
|
||||
|
@ -79,6 +82,7 @@ public slots:
|
|||
private:
|
||||
void queueVoxelAdd(PacketType addPacketType, VoxelDetail& addVoxelDetails);
|
||||
VoxelTree* _tree;
|
||||
QUndoStack* _undoStack;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__VoxelsScriptingInterface__) */
|
||||
|
|
Loading…
Reference in a new issue