mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 04:44:11 +02:00
UI for nudge completed!
This commit is contained in:
parent
78f1468a12
commit
ac878c9c63
5 changed files with 105 additions and 81 deletions
|
@ -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);
|
||||
|
|
|
@ -357,6 +357,7 @@ private:
|
|||
Swatch _swatch;
|
||||
|
||||
bool _pasteMode;
|
||||
bool _finishedNudge;
|
||||
|
||||
PieMenu _pieMenu;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue