UI for nudge completed!

This commit is contained in:
LionTurtle 2013-09-09 16:53:31 -07:00
parent 78f1468a12
commit ac878c9c63
5 changed files with 105 additions and 81 deletions

View file

@ -128,7 +128,8 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
_bytesPerSecond(0),
_bytesCount(0),
_swatch(NULL),
_pasteMode(false)
_pasteMode(false),
_finishedNudge(true)
{
_applicationStartupTime = startup_time;
_window->setWindowTitle("Interface");
@ -844,10 +845,15 @@ void Application::mousePressEvent(QMouseEvent* event) {
pasteVoxels();
}
if (MAKE_SOUND_ON_VOXEL_CLICK && _isHoverVoxel && !_isHoverVoxelSounding) {
if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelNudgeMode)) {
_nudgeVoxel = _hoverVoxel;
if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelNudgeMode)) {
VoxelNode* clickedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
if (clickedNode) {
_nudgeVoxel = _mouseVoxel;
_finishedNudge = false;
}
}
if (MAKE_SOUND_ON_VOXEL_CLICK && _isHoverVoxel && !_isHoverVoxelSounding) {
_hoverVoxelOriginalColor[0] = _hoverVoxel.red;
_hoverVoxelOriginalColor[1] = _hoverVoxel.green;
_hoverVoxelOriginalColor[2] = _hoverVoxel.blue;
@ -1287,52 +1293,16 @@ void Application::pasteVoxels() {
void Application::nudgeVoxels() {
if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelNudgeMode)) {
cutVoxels();
unsigned char* calculatedOctCode = NULL;
VoxelNode* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
// calculate nudgeVec
glm::vec3 nudgeVec(_mouseVoxel.x - _nudgeVoxel.x, _mouseVoxel.y - _nudgeVoxel.y, _mouseVoxel.z - _nudgeVoxel.z);
// Recurse the clipboard tree, where everything is root relative, and send all the colored voxels to
// the server as an set voxel message, this will also rebase the voxels to the new location
SendVoxelsOperationArgs args;
VoxelNode* nodeToNudge = _voxels.getVoxelAt(_nudgeVoxel.x, _nudgeVoxel.y, _nudgeVoxel.z, _nudgeVoxel.s);
// we only need the selected voxel to get the newBaseOctCode, which we can actually calculate from the
// voxel size/position details. If we don't have an actual selectedNode then use the mouseVoxel to create a
// target octalCode for where the user is pointing.
if (selectedNode) {
args.newBaseOctCode = selectedNode->getOctalCode();
} else {
args.newBaseOctCode = calculatedOctCode = pointToVoxel(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
}
_sharedVoxelSystem.getTree()->recurseTreeWithOperation(sendVoxelsOperation, &args);
glm::vec3 nudgeVec(0.25 * _mouseVoxel.s, 0.25 * _mouseVoxel.s, 0.25 * _mouseVoxel.s);
_voxels.getVoxelTree()->nudgeSubTree(selectedNode, nudgeVec, _voxelEditSender);
if (_sharedVoxelSystem.getTree() != &_clipboard) {
_sharedVoxelSystem.killLocalVoxels();
_sharedVoxelSystem.changeTree(&_clipboard);
}
_voxelEditSender.flushQueue();
if (calculatedOctCode) {
delete[] calculatedOctCode;
if (nodeToNudge) {
_voxels.getVoxelTree()->nudgeSubTree(nodeToNudge, nudgeVec, _voxelEditSender);
_finishedNudge = true;
}
}
// VoxelNode* selectedNode = _voxels.getVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
// if (selectedNode) {
// qDebug("UnNudged xyz: %f, %f, %f\n", _mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z);
// // nudge the node
// // glm::vec3 nudgeVec(_mouseVoxel.s, _mouseVoxel.s, _mouseVoxel.s);
// // glm::vec3 nudgeVec(0.5 * _mouseVoxel.s, 0.5 * _mouseVoxel.s, 0.5 * _mouseVoxel.s);
// glm::vec3 nudgeVec(0.25 * _mouseVoxel.s, 0.25 * _mouseVoxel.s, 0.25 * _mouseVoxel.s);
// _voxels.getVoxelTree()->nudgeSubTree(selectedNode, nudgeVec, _voxelEditSender);
// }
}
void Application::setListenModeNormal() {
@ -1612,7 +1582,7 @@ void Application::update(float deltaTime) {
lookAtSpot = lookAtRayOrigin + lookAtRayDirection * FAR_AWAY_STARE;
_myAvatar.getHead().setLookAtPosition(lookAtSpot);
}
// Find the voxel we are hovering over, and respond if clicked
float distance;
BoxFace face;
@ -1702,11 +1672,13 @@ void Application::update(float deltaTime) {
_mouseVoxel.z += faceVector.z * _mouseVoxel.s;
}
}
_nudgeVoxel.s = _mouseVoxel.s;
} else {
_mouseVoxel.s = 0.0f;
}
} else if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelAddMode)
|| Menu::getInstance()->isOptionChecked(MenuOption::VoxelSelectMode)) {
|| Menu::getInstance()->isOptionChecked(MenuOption::VoxelSelectMode)
|| Menu::getInstance()->isOptionChecked(MenuOption::VoxelNudgeMode)) {
// place the voxel a fixed distance away
float worldMouseVoxelScale = _mouseVoxelScale * TREE_SCALE;
glm::vec3 pt = mouseRayOrigin + mouseRayDirection * (2.0f + worldMouseVoxelScale * 0.5f);
@ -2308,13 +2280,22 @@ void Application::displaySide(Camera& whichCamera) {
glPushMatrix();
glScalef(TREE_SCALE, TREE_SCALE, TREE_SCALE);
if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelNudgeMode)) {
// VoxelNode* selectedNode = _voxels.getVoxelAt(_nudgeVoxel.x, _nudgeVoxel.y, _nudgeVoxel.z, _nudgeVoxel.s);
// if (selectedNode) {
renderNudgeGrid(_nudgeVoxel.x, _nudgeVoxel.y, _nudgeVoxel.z, _nudgeVoxel.s);
// }
if (!_finishedNudge) {
renderNudgeGuide(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _nudgeVoxel.s);
renderNudgeGrid(_nudgeVoxel.x, _nudgeVoxel.y, _nudgeVoxel.z, _nudgeVoxel.s, _mouseVoxel.s);
glPushMatrix();
glTranslatef(_nudgeVoxel.x + _nudgeVoxel.s * 0.5f,
_nudgeVoxel.y + _nudgeVoxel.s * 0.5f,
_nudgeVoxel.z + _nudgeVoxel.s * 0.5f);
glColor3ub(255, 255, 255);
glLineWidth(4.0f);
glutWireCube(_nudgeVoxel.s);
glPopMatrix();
}
} else {
renderMouseVoxelGrid(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
}
if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelAddMode)) {
// use a contrasting color so that we can see what we're doing
glColor3ub(_mouseVoxel.red + 128, _mouseVoxel.green + 128, _mouseVoxel.blue + 128);
@ -2325,7 +2306,11 @@ void Application::displaySide(Camera& whichCamera) {
_mouseVoxel.y + _mouseVoxel.s*0.5f,
_mouseVoxel.z + _mouseVoxel.s*0.5f);
glLineWidth(4.0f);
glutWireCube(_mouseVoxel.s);
if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelNudgeMode)) {
glutWireCube(_nudgeVoxel.s);
} else {
glutWireCube(_mouseVoxel.s);
}
glLineWidth(1.0f);
glPopMatrix();
glEnable(GL_LIGHTING);

View file

@ -357,6 +357,7 @@ private:
Swatch _swatch;
bool _pasteMode;
bool _finishedNudge;
PieMenu _pieMenu;

View file

@ -414,30 +414,57 @@ void renderMouseVoxelGrid(const float& mouseVoxelX, const float& mouseVoxelY, co
glEnd();
}
void renderNudgeGrid(const float& voxelX, const float& voxelY, const float& voxelZ, const float& voxelS) {
void renderNudgeGrid(const float& voxelX, const float& voxelY, const float& voxelZ, const float& voxelS, const float& voxelPrecision) {
glm::vec3 origin = glm::vec3(voxelX, voxelY, voxelZ);
glLineWidth(1.0);
const int GRID_DIMENSIONS = 4;
const int GRID_SCALER = voxelS / voxelPrecision;
const int GRID_SEGMENTS = GRID_DIMENSIONS * GRID_SCALER;
glBegin(GL_LINES);
for (int xz = - (GRID_DIMENSIONS / 2); xz <= GRID_DIMENSIONS / 2 + 1; xz++) {
for (int xz = - (GRID_SEGMENTS / 2); xz <= GRID_SEGMENTS / 2 + GRID_SCALER; xz++) {
glm::vec3 xColor(0.0, 0.6, 0.0);
glColor3fv(&xColor.x);
glVertex3f(origin.x + GRID_DIMENSIONS * voxelS, 0, origin.z + xz * voxelS);
glVertex3f(origin.x - (GRID_DIMENSIONS - 1) * voxelS, 0, origin.z + xz * voxelS);
glVertex3f(origin.x + GRID_DIMENSIONS * voxelS, 0, origin.z + xz * voxelPrecision);
glVertex3f(origin.x - (GRID_DIMENSIONS - 1) * voxelS, 0, origin.z + xz * voxelPrecision);
glm::vec3 zColor(0.0, 0.0, 0.6);
glColor3fv(&zColor.x);
glVertex3f(origin.x + xz * voxelS, 0, origin.z + GRID_DIMENSIONS * voxelS);
glVertex3f(origin.x + xz * voxelS, 0, origin.z - (GRID_DIMENSIONS - 1) * voxelS);
glVertex3f(origin.x + xz * voxelPrecision, 0, origin.z + GRID_DIMENSIONS * voxelS);
glVertex3f(origin.x + xz * voxelPrecision, 0, origin.z - (GRID_DIMENSIONS - 1) * voxelS);
}
glEnd();
}
void renderNudgeGuide(const float& voxelX, const float& voxelY, const float& voxelZ, const float& voxelS) {
glm::vec3 origin = glm::vec3(voxelX, voxelY, voxelZ);
glLineWidth(3.0);
glBegin(GL_LINES);
glm::vec3 guideColor(1.0, 1.0, 1.0);
glColor3fv(&guideColor.x);
glVertex3f(origin.x + voxelS, 0, origin.z);
glVertex3f(origin.x, 0, origin.z);
glVertex3f(origin.x, 0, origin.z);
glVertex3f(origin.x, 0, origin.z + voxelS);
glVertex3f(origin.x + voxelS, 0, origin.z);
glVertex3f(origin.x + voxelS, 0, origin.z + voxelS);
glVertex3f(origin.x, 0, origin.z + voxelS);
glVertex3f(origin.x + voxelS, 0, origin.z + voxelS);
glEnd();
}
void renderDiskShadow(glm::vec3 position, glm::vec3 upDirection, float radius, float darkness) {
glColor4f(0.0f, 0.0f, 0.0f, darkness);

View file

@ -61,7 +61,9 @@ void renderGroundPlaneGrid(float size, float impact);
void renderMouseVoxelGrid(const float& mouseVoxelX, const float& mouseVoxelY, const float& mouseVoxelZ, const float& mouseVoxelS);
void renderNudgeGrid(const float& voxelX, const float& voxelY, const float& voxelZ, const float& voxelS);
void renderNudgeGrid(const float& voxelX, const float& voxelY, const float& voxelZ, const float& voxelS, const float& voxelPrecision);
void renderNudgeGuide(const float& voxelX, const float& voxelY, const float& voxelZ, const float& voxelS);
void renderCollisionOverlay(int width, int height, float magnitude);

View file

@ -1858,23 +1858,35 @@ void VoxelTree::cancelImport() {
_stopImport = true;
}
typedef unsigned char nodeColor[4];
const nodeColor red = {255, 0, 0, 0};
const nodeColor green = {0, 255, 0, 0};
const nodeColor blue = {0, 0, 255, 0};
class NodeChunkArgs {
public:
VoxelTree* thisVoxelTree;
float ancestorSize;
float newSize;
glm::vec3 nudgeVec;
VoxelEditPacketSender* voxelEditSenderPtr;
int colorIndex;
};
float findNewLeafSize(const glm::vec3& nudgeAmount, float leafSize) {
// we want the smallest non-zero and non-negative new leafSize
float newLeafSizeX = fabs(fmod(nudgeAmount.x, leafSize));
float newLeafSizeY = fabs(fmod(nudgeAmount.y, leafSize));
float newLeafSizeZ = fabs(fmod(nudgeAmount.z, leafSize));
float newLeafSize = leafSize;
if (newLeafSizeX) {
newLeafSize = fmin(newLeafSize, newLeafSizeX);
}
if (newLeafSizeY) {
newLeafSize = fmin(newLeafSize, newLeafSizeY);
}
if (newLeafSizeZ) {
newLeafSize = fmin(newLeafSize, newLeafSizeZ);
}
return newLeafSize;
}
bool VoxelTree::nudgeCheck(VoxelNode* node, void* extraData) {
if (node->isLeaf()) {
// we have reached the deepest level of nodes/voxels
@ -1893,8 +1905,12 @@ bool VoxelTree::nudgeCheck(VoxelNode* node, void* extraData) {
VoxelPositionSize unNudgedDetails;
voxelDetailsForCode(octalCode, unNudgedDetails);
// find necessary leaf size
float newLeafSize = findNewLeafSize(args->nudgeVec, unNudgedDetails.s);
args->ancestorSize = unNudgedDetails.s;
// check to see if this unNudged node can be nudged
if (unNudgedDetails.s <= args->newSize) {
if (unNudgedDetails.s <= newLeafSize) {
args->thisVoxelTree->nudgeLeaf(node, extraData);
return false;
} else {
@ -1928,8 +1944,6 @@ void VoxelTree::nudgeLeaf(VoxelNode* node, void* extraData) {
// get voxel position/size
VoxelPositionSize unNudgedDetails;
voxelDetailsForCode(octalCode, unNudgedDetails);
qDebug("UnNudged xyz: %f, %f, %f\n", unNudgedDetails.x, unNudgedDetails.y, unNudgedDetails.z);
VoxelDetail voxelDetails;
voxelDetails.x = unNudgedDetails.x;
@ -1942,28 +1956,24 @@ void VoxelTree::nudgeLeaf(VoxelNode* node, void* extraData) {
glm::vec3 nudge = args->nudgeVec;
// delete the old node
if (nudge.x >= args->ancestorSize && nudge.y >= args->ancestorSize && nudge.z >= args->ancestorSize) {
// if the nudge replaces the node in an area outside of the ancestor node
if (fabs(nudge.x) >= args->ancestorSize || fabs(nudge.y) >= args->ancestorSize || fabs(nudge.z) >= args->ancestorSize) {
args->voxelEditSenderPtr->sendVoxelEditMessage(PACKET_TYPE_ERASE_VOXEL, voxelDetails);
qDebug("unNudged voxel deleted!\n");
}
// nudge the old node
qDebug("nudged by %f, %f, %f\n", nudge.x, nudge.y, nudge.z);
voxelDetails.x = unNudgedDetails.x + nudge.x;
voxelDetails.y = unNudgedDetails.y + nudge.y;
voxelDetails.z = unNudgedDetails.z + nudge.z;
// create a new voxel in its stead
args->voxelEditSenderPtr->sendVoxelEditMessage(PACKET_TYPE_SET_VOXEL, voxelDetails);
qDebug("Nudged xyz: %f, %f, %f\n", voxelDetails.x, voxelDetails.y, voxelDetails.z);
qDebug("nudged node created!\n");
args->voxelEditSenderPtr->sendVoxelEditMessage(PACKET_TYPE_SET_VOXEL_DESTRUCTIVE, voxelDetails);
}
void VoxelTree::nudgeSubTree(VoxelNode* nodeToNudge, const glm::vec3& nudgeAmount, VoxelEditPacketSender& voxelEditSender) {
// calculate minNudgeAmount to check if breaking the tree into smaller chunks is necessary
float minNudgeAmount = fmin(nudgeAmount.x, nudgeAmount.y);
minNudgeAmount = fmin(minNudgeAmount, nudgeAmount.z);
if (nudgeAmount == glm::vec3(0, 0, 0)) {
return;
}
// get octal code of this node
unsigned char* octalCode = nodeToNudge->getOctalCode();
@ -1975,7 +1985,6 @@ void VoxelTree::nudgeSubTree(VoxelNode* nodeToNudge, const glm::vec3& nudgeAmoun
NodeChunkArgs args;
args.thisVoxelTree = this;
args.ancestorSize = ancestorDetails.s;
args.newSize = minNudgeAmount;
args.nudgeVec = nudgeAmount;
args.voxelEditSenderPtr = &voxelEditSender;
args.colorIndex = 0;