mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 23:14:34 +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");
|
voxelDetails = calculateVoxelFromIntersection(intersection,"add");
|
||||||
Voxels.eraseVoxel(voxelDetails.x, voxelDetails.y, voxelDetails.z, voxelDetails.s);
|
|
||||||
Voxels.setVoxel(voxelDetails.x, voxelDetails.y, voxelDetails.z, voxelDetails.s,
|
Voxels.setVoxel(voxelDetails.x, voxelDetails.y, voxelDetails.z, voxelDetails.s,
|
||||||
newColor.red, newColor.green, newColor.blue);
|
newColor.red, newColor.green, newColor.blue);
|
||||||
lastVoxelPosition = { x: voxelDetails.x, y: voxelDetails.y, z: voxelDetails.z };
|
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.
|
// we can use the same ones from the application.
|
||||||
scriptEngine->getVoxelsScriptingInterface()->setPacketSender(&_voxelEditSender);
|
scriptEngine->getVoxelsScriptingInterface()->setPacketSender(&_voxelEditSender);
|
||||||
scriptEngine->getVoxelsScriptingInterface()->setVoxelTree(_voxels.getTree());
|
scriptEngine->getVoxelsScriptingInterface()->setVoxelTree(_voxels.getTree());
|
||||||
|
scriptEngine->getVoxelsScriptingInterface()->setUndoStack(&_undoStack);
|
||||||
scriptEngine->getParticlesScriptingInterface()->setPacketSender(&_particleEditSender);
|
scriptEngine->getParticlesScriptingInterface()->setPacketSender(&_particleEditSender);
|
||||||
scriptEngine->getParticlesScriptingInterface()->setParticleTree(_particles.getTree());
|
scriptEngine->getParticlesScriptingInterface()->setParticleTree(_particles.getTree());
|
||||||
|
|
||||||
|
|
|
@ -14,14 +14,15 @@
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QImage>
|
|
||||||
#include <QSettings>
|
|
||||||
#include <QTouchEvent>
|
|
||||||
#include <QList>
|
|
||||||
#include <QSet>
|
|
||||||
#include <QStringList>
|
|
||||||
#include <QPointer>
|
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
|
#include <QImage>
|
||||||
|
#include <QList>
|
||||||
|
#include <QPointer>
|
||||||
|
#include <QSet>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QTouchEvent>
|
||||||
|
#include <QUndoStack>
|
||||||
|
|
||||||
#include <NetworkPacket.h>
|
#include <NetworkPacket.h>
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
|
@ -176,6 +177,7 @@ public:
|
||||||
Visage* getVisage() { return &_visage; }
|
Visage* getVisage() { return &_visage; }
|
||||||
SixenseManager* getSixenseManager() { return &_sixenseManager; }
|
SixenseManager* getSixenseManager() { return &_sixenseManager; }
|
||||||
BandwidthMeter* getBandwidthMeter() { return &_bandwidthMeter; }
|
BandwidthMeter* getBandwidthMeter() { return &_bandwidthMeter; }
|
||||||
|
QUndoStack* getUndoStack() { return &_undoStack; }
|
||||||
|
|
||||||
/// if you need to access the application settings, use lockSettings()/unlockSettings()
|
/// if you need to access the application settings, use lockSettings()/unlockSettings()
|
||||||
QSettings* lockSettings() { _settingsMutex.lock(); return _settings; }
|
QSettings* lockSettings() { _settingsMutex.lock(); return _settings; }
|
||||||
|
@ -366,6 +368,8 @@ private:
|
||||||
QMutex _settingsMutex;
|
QMutex _settingsMutex;
|
||||||
QSettings* _settings;
|
QSettings* _settings;
|
||||||
|
|
||||||
|
QUndoStack _undoStack;
|
||||||
|
|
||||||
glm::vec3 _gravity;
|
glm::vec3 _gravity;
|
||||||
|
|
||||||
// Frame Rate Measurement
|
// Frame Rate Measurement
|
||||||
|
|
|
@ -161,6 +161,15 @@ Menu::Menu() :
|
||||||
|
|
||||||
|
|
||||||
QMenu* editMenu = addMenu("Edit");
|
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,
|
addActionToQMenuAndActionHash(editMenu,
|
||||||
MenuOption::Preferences,
|
MenuOption::Preferences,
|
||||||
|
@ -620,6 +629,41 @@ QAction* Menu::addActionToQMenuAndActionHash(QMenu* destinationMenu,
|
||||||
return action;
|
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,
|
QAction* Menu::addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu,
|
||||||
const QString& actionName,
|
const QString& actionName,
|
||||||
const QKeySequence& shortcut,
|
const QKeySequence& shortcut,
|
||||||
|
|
|
@ -102,7 +102,13 @@ public:
|
||||||
const char* member = NULL,
|
const char* member = NULL,
|
||||||
QAction::MenuRole role = QAction::NoRole,
|
QAction::MenuRole role = QAction::NoRole,
|
||||||
int menuItemLocation = UNSPECIFIED_POSITION);
|
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);
|
void removeAction(QMenu* menu, const QString& actionName);
|
||||||
|
|
||||||
bool goToDestination(QString destination);
|
bool goToDestination(QString destination);
|
||||||
|
@ -219,65 +225,65 @@ private:
|
||||||
namespace MenuOption {
|
namespace MenuOption {
|
||||||
const QString AboutApp = "About Interface";
|
const QString AboutApp = "About Interface";
|
||||||
const QString AmbientOcclusion = "Ambient Occlusion";
|
const QString AmbientOcclusion = "Ambient Occlusion";
|
||||||
const QString Avatars = "Avatars";
|
|
||||||
const QString Atmosphere = "Atmosphere";
|
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 Bandwidth = "Bandwidth Display";
|
||||||
const QString BandwidthDetails = "Bandwidth Details";
|
const QString BandwidthDetails = "Bandwidth Details";
|
||||||
const QString BuckyBalls = "Bucky Balls";
|
const QString BuckyBalls = "Bucky Balls";
|
||||||
|
const QString Chat = "Chat...";
|
||||||
const QString ChatCircling = "Chat Circling";
|
const QString ChatCircling = "Chat Circling";
|
||||||
const QString Collisions = "Collisions";
|
|
||||||
const QString CollideWithAvatars = "Collide With Avatars";
|
const QString CollideWithAvatars = "Collide With Avatars";
|
||||||
|
const QString CollideWithEnvironment = "Collide With World Boundaries";
|
||||||
const QString CollideWithParticles = "Collide With Particles";
|
const QString CollideWithParticles = "Collide With Particles";
|
||||||
const QString CollideWithVoxels = "Collide With Voxels";
|
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 CullSharedFaces = "Cull Shared Voxel Faces";
|
||||||
const QString DecreaseAvatarSize = "Decrease Avatar Size";
|
const QString DecreaseAvatarSize = "Decrease Avatar Size";
|
||||||
const QString DecreaseVoxelSize = "Decrease Voxel Size";
|
const QString DecreaseVoxelSize = "Decrease Voxel Size";
|
||||||
|
const QString DisableAutoAdjustLOD = "Disable Automatically Adjusting LOD";
|
||||||
const QString DisplayFrustum = "Display Frustum";
|
const QString DisplayFrustum = "Display Frustum";
|
||||||
const QString DisplayHands = "Display Hands";
|
const QString DisplayHands = "Display Hands";
|
||||||
const QString DisplayHandTargets = "Display Hand Targets";
|
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 DontFadeOnVoxelServerChanges = "Don't Fade In/Out on Voxel Server Changes";
|
||||||
const QString HeadMouse = "Head Mouse";
|
const QString EchoLocalAudio = "Echo Local Audio";
|
||||||
const QString HandsCollideWithSelf = "Collide With Self";
|
const QString EchoServerAudio = "Echo Server Audio";
|
||||||
|
const QString Enable3DTVMode = "Enable 3DTV Mode";
|
||||||
const QString Faceshift = "Faceshift";
|
const QString Faceshift = "Faceshift";
|
||||||
|
const QString FilterSixense = "Smooth Sixense Movement";
|
||||||
const QString FirstPerson = "First Person";
|
const QString FirstPerson = "First Person";
|
||||||
const QString FrameTimer = "Show Timer";
|
const QString FrameTimer = "Show Timer";
|
||||||
const QString FrustumRenderMode = "Render Mode";
|
const QString FrustumRenderMode = "Render Mode";
|
||||||
const QString Fullscreen = "Fullscreen";
|
const QString Fullscreen = "Fullscreen";
|
||||||
const QString FullscreenMirror = "Fullscreen Mirror";
|
const QString FullscreenMirror = "Fullscreen Mirror";
|
||||||
const QString GlowMode = "Cycle Glow Mode";
|
const QString GlowMode = "Cycle Glow Mode";
|
||||||
|
const QString GoHome = "Go Home";
|
||||||
|
const QString GoTo = "Go To...";
|
||||||
const QString GoToDomain = "Go To Domain...";
|
const QString GoToDomain = "Go To Domain...";
|
||||||
const QString GoToLocation = "Go To Location...";
|
const QString GoToLocation = "Go To Location...";
|
||||||
const QString NameLocation = "Name this location";
|
const QString Gravity = "Use Gravity";
|
||||||
const QString GoTo = "Go To...";
|
const QString HandsCollideWithSelf = "Collide With Self";
|
||||||
|
const QString HeadMouse = "Head Mouse";
|
||||||
const QString IncreaseAvatarSize = "Increase Avatar Size";
|
const QString IncreaseAvatarSize = "Increase Avatar Size";
|
||||||
const QString IncreaseVoxelSize = "Increase Voxel Size";
|
const QString IncreaseVoxelSize = "Increase Voxel Size";
|
||||||
const QString GoHome = "Go Home";
|
const QString LoadScript = "Open and Run Script File...";
|
||||||
const QString Gravity = "Use Gravity";
|
const QString LoadScriptURL = "Open and Run Script from URL...";
|
||||||
const QString LodTools = "LOD Tools";
|
const QString LodTools = "LOD Tools";
|
||||||
const QString Log = "Log";
|
const QString Log = "Log";
|
||||||
const QString Login = "Login";
|
const QString Login = "Login";
|
||||||
const QString Logout = "Logout";
|
const QString Logout = "Logout";
|
||||||
const QString LookAtVectors = "Look-at Vectors";
|
const QString LookAtVectors = "Look-at Vectors";
|
||||||
const QString MetavoxelEditor = "Metavoxel Editor...";
|
const QString MetavoxelEditor = "Metavoxel Editor...";
|
||||||
const QString Chat = "Chat...";
|
|
||||||
const QString Metavoxels = "Metavoxels";
|
const QString Metavoxels = "Metavoxels";
|
||||||
const QString Mirror = "Mirror";
|
const QString Mirror = "Mirror";
|
||||||
const QString MoveWithLean = "Move with Lean";
|
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 NewVoxelCullingMode = "New Voxel Culling Mode";
|
||||||
|
const QString OctreeStats = "Voxel and Particle Statistics";
|
||||||
const QString OffAxisProjection = "Off-Axis Projection";
|
const QString OffAxisProjection = "Off-Axis Projection";
|
||||||
const QString OldVoxelCullingMode = "Old Voxel Culling Mode";
|
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 Oscilloscope = "Audio Oscilloscope";
|
||||||
const QString Pair = "Pair";
|
const QString Pair = "Pair";
|
||||||
const QString Particles = "Particles";
|
const QString Particles = "Particles";
|
||||||
|
@ -285,30 +291,30 @@ namespace MenuOption {
|
||||||
const QString PipelineWarnings = "Show Render Pipeline Warnings";
|
const QString PipelineWarnings = "Show Render Pipeline Warnings";
|
||||||
const QString PlaySlaps = "Play Slaps";
|
const QString PlaySlaps = "Play Slaps";
|
||||||
const QString Preferences = "Preferences...";
|
const QString Preferences = "Preferences...";
|
||||||
|
const QString Quit = "Quit";
|
||||||
const QString ReloadAllScripts = "Reload All Scripts";
|
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 RenderBoundingCollisionShapes = "Bounding Collision Shapes";
|
||||||
|
const QString RenderHeadCollisionShapes = "Head Collision Shapes";
|
||||||
|
const QString RenderSkeletonCollisionShapes = "Skeleton Collision Shapes";
|
||||||
const QString ResetAvatarSize = "Reset Avatar Size";
|
const QString ResetAvatarSize = "Reset Avatar Size";
|
||||||
const QString RunningScripts = "Running Scripts";
|
const QString RunningScripts = "Running Scripts";
|
||||||
const QString RunTimingTests = "Run Timing Tests";
|
const QString RunTimingTests = "Run Timing Tests";
|
||||||
|
const QString SettingsExport = "Export Settings";
|
||||||
const QString SettingsImport = "Import Settings";
|
const QString SettingsImport = "Import Settings";
|
||||||
const QString Shadows = "Shadows";
|
const QString Shadows = "Shadows";
|
||||||
const QString SettingsExport = "Export Settings";
|
|
||||||
const QString ShowCulledSharedFaces = "Show Culled Shared Voxel Faces";
|
const QString ShowCulledSharedFaces = "Show Culled Shared Voxel Faces";
|
||||||
const QString SuppressShortTimings = "Suppress Timings Less than 10ms";
|
|
||||||
const QString Stars = "Stars";
|
const QString Stars = "Stars";
|
||||||
const QString Stats = "Stats";
|
const QString Stats = "Stats";
|
||||||
const QString StopAllScripts = "Stop All Scripts";
|
const QString StopAllScripts = "Stop All Scripts";
|
||||||
|
const QString SuppressShortTimings = "Suppress Timings Less than 10ms";
|
||||||
const QString TestPing = "Test Ping";
|
const QString TestPing = "Test Ping";
|
||||||
const QString TransmitterDrive = "Transmitter Drive";
|
const QString TransmitterDrive = "Transmitter Drive";
|
||||||
|
const QString TurnWithHead = "Turn using Head";
|
||||||
const QString UploadHead = "Upload Head Model";
|
const QString UploadHead = "Upload Head Model";
|
||||||
const QString UploadSkeleton = "Upload Skeleton Model";
|
const QString UploadSkeleton = "Upload Skeleton Model";
|
||||||
const QString Visage = "Visage";
|
const QString Visage = "Visage";
|
||||||
const QString Quit = "Quit";
|
|
||||||
const QString Voxels = "Voxels";
|
|
||||||
const QString VoxelMode = "Cycle Voxel Mode";
|
const QString VoxelMode = "Cycle Voxel Mode";
|
||||||
const QString OctreeStats = "Voxel and Particle Statistics";
|
const QString Voxels = "Voxels";
|
||||||
const QString VoxelTextures = "Voxel Textures";
|
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.
|
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "VoxelTreeCommands.h"
|
||||||
|
|
||||||
#include "VoxelsScriptingInterface.h"
|
#include "VoxelsScriptingInterface.h"
|
||||||
|
|
||||||
void VoxelsScriptingInterface::queueVoxelAdd(PacketType addPacketType, VoxelDetail& addVoxelDetails) {
|
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,
|
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
|
// 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};
|
scale / (float)TREE_SCALE, red, green, blue};
|
||||||
|
|
||||||
// queue the add packet
|
|
||||||
queueVoxelAdd(PacketTypeVoxelSet, addVoxelDetail);
|
|
||||||
|
|
||||||
// handle the local tree also...
|
// handle the local tree also...
|
||||||
if (_tree) {
|
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,
|
VoxelDetail addVoxelDetail = {x / (float)TREE_SCALE, y / (float)TREE_SCALE, z / (float)TREE_SCALE,
|
||||||
scale / (float)TREE_SCALE, red, green, blue};
|
scale / (float)TREE_SCALE, red, green, blue};
|
||||||
|
|
||||||
// queue the destructive add
|
|
||||||
queueVoxelAdd(PacketTypeVoxelSetDestructive, addVoxelDetail);
|
|
||||||
|
|
||||||
// handle the local tree also...
|
// handle the local tree also...
|
||||||
if (_tree) {
|
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) {
|
void VoxelsScriptingInterface::eraseVoxel(float x, float y, float z, float scale) {
|
||||||
|
|
||||||
// setup a VoxelDetail struct with data
|
// setup a VoxelDetail struct with data
|
||||||
VoxelDetail deleteVoxelDetail = {x / (float)TREE_SCALE, y / (float)TREE_SCALE, z / (float)TREE_SCALE,
|
VoxelDetail deleteVoxelDetail = {x / (float)TREE_SCALE, y / (float)TREE_SCALE, z / (float)TREE_SCALE,
|
||||||
scale / (float)TREE_SCALE, 0, 0, 0};
|
scale / (float)TREE_SCALE};
|
||||||
|
|
||||||
getVoxelPacketSender()->queueVoxelEditMessages(PacketTypeVoxelErase, 1, &deleteVoxelDetail);
|
|
||||||
|
|
||||||
// handle the local tree also...
|
// handle the local tree also...
|
||||||
if (_tree) {
|
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 "VoxelEditPacketSender.h"
|
||||||
#include "VoxelTree.h"
|
#include "VoxelTree.h"
|
||||||
|
|
||||||
|
class QUndoStack;
|
||||||
|
|
||||||
/// handles scripting of voxel commands from JS passed to assigned clients
|
/// handles scripting of voxel commands from JS passed to assigned clients
|
||||||
class VoxelsScriptingInterface : public OctreeScriptingInterface {
|
class VoxelsScriptingInterface : public OctreeScriptingInterface {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
VoxelsScriptingInterface() : _tree(NULL) {};
|
VoxelsScriptingInterface() : _tree(NULL), _undoStack(NULL) {};
|
||||||
VoxelEditPacketSender* getVoxelPacketSender() { return (VoxelEditPacketSender*)getPacketSender(); }
|
VoxelEditPacketSender* getVoxelPacketSender() { return (VoxelEditPacketSender*)getPacketSender(); }
|
||||||
|
|
||||||
virtual NodeType_t getServerNodeType() const { return NodeType::VoxelServer; }
|
virtual NodeType_t getServerNodeType() const { return NodeType::VoxelServer; }
|
||||||
virtual OctreeEditPacketSender* createPacketSender() { return new VoxelEditPacketSender(); }
|
virtual OctreeEditPacketSender* createPacketSender() { return new VoxelEditPacketSender(); }
|
||||||
void setVoxelTree(VoxelTree* tree) { _tree = tree; }
|
void setVoxelTree(VoxelTree* tree) { _tree = tree; }
|
||||||
|
void setUndoStack(QUndoStack* undoStack) { _undoStack = undoStack; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
|
@ -79,6 +82,7 @@ public slots:
|
||||||
private:
|
private:
|
||||||
void queueVoxelAdd(PacketType addPacketType, VoxelDetail& addVoxelDetails);
|
void queueVoxelAdd(PacketType addPacketType, VoxelDetail& addVoxelDetails);
|
||||||
VoxelTree* _tree;
|
VoxelTree* _tree;
|
||||||
|
QUndoStack* _undoStack;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__hifi__VoxelsScriptingInterface__) */
|
#endif /* defined(__hifi__VoxelsScriptingInterface__) */
|
||||||
|
|
Loading…
Reference in a new issue