Merge pull request #925 from LionTurtle/master

Add limit to nudge precision. Fix bugs in certain nudge scenarios. Fix rendering of nudge guide.
This commit is contained in:
ZappoMan 2013-09-11 18:46:54 -07:00
commit 53e189e95b
3 changed files with 99 additions and 20 deletions

View file

@ -1160,8 +1160,16 @@ const glm::vec3 Application::getMouseVoxelWorldCoordinates(const VoxelDetail _mo
(_mouseVoxel.z + _mouseVoxel.s / 2.f) * TREE_SCALE);
}
const float NUDGE_PRECISION_LIMIT = 1 / pow(2.0, 12.0);
void Application::decreaseVoxelSize() {
_mouseVoxelScale /= 2;
if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelNudgeMode)) {
if (_mouseVoxelScale >= NUDGE_PRECISION_LIMIT) {
_mouseVoxelScale /= 2;
}
} else {
_mouseVoxelScale /= 2;
}
}
void Application::increaseVoxelSize() {
@ -2315,17 +2323,18 @@ void Application::displaySide(Camera& whichCamera) {
} else {
glColor3ub(_mouseVoxel.red, _mouseVoxel.green, _mouseVoxel.blue);
}
glTranslatef(_mouseVoxel.x + _mouseVoxel.s*0.5f,
_mouseVoxel.y + _mouseVoxel.s*0.5f,
_mouseVoxel.z + _mouseVoxel.s*0.5f);
glLineWidth(4.0f);
if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelNudgeMode)) {
if (_nudgeVoxel.s) {
glutWireCube(_nudgeVoxel.s);
} else {
glutWireCube(_mouseVoxel.s);
}
glTranslatef(_mouseVoxel.x + _nudgeVoxel.s*0.5f,
_mouseVoxel.y + _nudgeVoxel.s*0.5f,
_mouseVoxel.z + _nudgeVoxel.s*0.5f);
glLineWidth(4.0f);
glutWireCube(_nudgeVoxel.s);
} else {
glTranslatef(_mouseVoxel.x + _mouseVoxel.s*0.5f,
_mouseVoxel.y + _mouseVoxel.s*0.5f,
_mouseVoxel.z + _mouseVoxel.s*0.5f);
glLineWidth(4.0f);
glutWireCube(_mouseVoxel.s);
}
glLineWidth(1.0f);

View file

@ -1861,9 +1861,9 @@ void VoxelTree::cancelImport() {
class NodeChunkArgs {
public:
VoxelTree* thisVoxelTree;
float ancestorSize;
glm::vec3 nudgeVec;
VoxelEditPacketSender* voxelEditSenderPtr;
int childOrder[NUMBER_OF_CHILDREN];
};
float findNewLeafSize(const glm::vec3& nudgeAmount, float leafSize) {
@ -1885,6 +1885,65 @@ float findNewLeafSize(const glm::vec3& nudgeAmount, float leafSize) {
return newLeafSize;
}
void reorderChildrenForNudge(void* extraData) {
NodeChunkArgs* args = (NodeChunkArgs*)extraData;
glm::vec3 nudgeVec = args->nudgeVec;
int lastToNudgeVote[NUMBER_OF_CHILDREN] = { 0 };
const int POSITIVE_X_ORDERING[4] = {0, 1, 2, 3};
const int NEGATIVE_X_ORDERING[4] = {4, 5, 6, 7};
const int POSITIVE_Y_ORDERING[4] = {0, 1, 4, 5};
const int NEGATIVE_Y_ORDERING[4] = {2, 3, 6, 7};
const int POSITIVE_Z_ORDERING[4] = {0, 2, 4, 6};
const int NEGATIVE_Z_ORDERING[4] = {1, 3, 5, 7};
if (nudgeVec.x > 0) {
for (int i = 0; i < NUMBER_OF_CHILDREN / 2; i++) {
lastToNudgeVote[POSITIVE_X_ORDERING[i]]++;
}
} else if (nudgeVec.x < 0) {
for (int i = 0; i < NUMBER_OF_CHILDREN / 2; i++) {
lastToNudgeVote[NEGATIVE_X_ORDERING[i]]++;
}
}
if (nudgeVec.y > 0) {
for (int i = 0; i < NUMBER_OF_CHILDREN / 2; i++) {
lastToNudgeVote[POSITIVE_Y_ORDERING[i]]++;
}
} else if (nudgeVec.y < 0) {
for (int i = 0; i < NUMBER_OF_CHILDREN / 2; i++) {
lastToNudgeVote[NEGATIVE_Y_ORDERING[i]]++;
}
}
if (nudgeVec.z > 0) {
for (int i = 0; i < NUMBER_OF_CHILDREN / 2; i++) {
lastToNudgeVote[POSITIVE_Z_ORDERING[i]]++;
}
} else if (nudgeVec.z > 0) {
for (int i = 0; i < NUMBER_OF_CHILDREN / 2; i++) {
lastToNudgeVote[NEGATIVE_Z_ORDERING[i]]++;
}
}
int nUncountedVotes = NUMBER_OF_CHILDREN;
while (nUncountedVotes > 0) {
int maxNumVotes = 0;
int maxVoteIndex = -1;
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
if (lastToNudgeVote[i] > maxNumVotes) {
maxNumVotes = lastToNudgeVote[i];
maxVoteIndex = i;
} else if (lastToNudgeVote[i] == maxNumVotes && maxVoteIndex == -1) {
maxVoteIndex = i;
}
}
lastToNudgeVote[maxVoteIndex] = -1;
args->childOrder[nUncountedVotes - 1] = maxVoteIndex;
nUncountedVotes--;
}
}
bool VoxelTree::nudgeCheck(VoxelNode* node, void* extraData) {
if (node->isLeaf()) {
// we have reached the deepest level of nodes/voxels
@ -1953,20 +2012,30 @@ void VoxelTree::nudgeLeaf(VoxelNode* node, void* extraData) {
glm::vec3 nudge = args->nudgeVec;
// delete the old node
// 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);
}
args->voxelEditSenderPtr->sendVoxelEditMessage(PACKET_TYPE_ERASE_VOXEL, voxelDetails);
// nudge the old node
voxelDetails.x = unNudgedDetails.x + nudge.x;
voxelDetails.y = unNudgedDetails.y + nudge.y;
voxelDetails.z = unNudgedDetails.z + nudge.z;
voxelDetails.x += nudge.x;
voxelDetails.y += nudge.y;
voxelDetails.z += nudge.z;
// create a new voxel in its stead
args->voxelEditSenderPtr->sendVoxelEditMessage(PACKET_TYPE_SET_VOXEL_DESTRUCTIVE, voxelDetails);
}
// Recurses voxel node with an operation function
void VoxelTree::recurseNodeForNudge(VoxelNode* node, RecurseVoxelTreeOperation operation, void* extraData) {
NodeChunkArgs* args = (NodeChunkArgs*)extraData;
if (operation(node, extraData)) {
for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
VoxelNode* child = node->getChildAtIndex(args->childOrder[i]);
if (child) {
recurseNodeForNudge(child, operation, extraData);
}
}
}
}
void VoxelTree::nudgeSubTree(VoxelNode* nodeToNudge, const glm::vec3& nudgeAmount, VoxelEditPacketSender& voxelEditSender) {
if (nudgeAmount == glm::vec3(0, 0, 0)) {
return;
@ -1981,9 +2050,9 @@ void VoxelTree::nudgeSubTree(VoxelNode* nodeToNudge, const glm::vec3& nudgeAmoun
NodeChunkArgs args;
args.thisVoxelTree = this;
args.ancestorSize = ancestorDetails.s;
args.nudgeVec = nudgeAmount;
args.voxelEditSenderPtr = &voxelEditSender;
reorderChildrenForNudge(&args);
recurseNodeWithOperation(nodeToNudge, nudgeCheck, &args);
recurseNodeForNudge(nodeToNudge, nudgeCheck, &args);
}

View file

@ -253,6 +253,7 @@ private:
void emptyDeleteQueue();
// helper functions for nudgeSubTree
void recurseNodeForNudge(VoxelNode* node, RecurseVoxelTreeOperation operation, void* extraData);
static bool nudgeCheck(VoxelNode* node, void* extraData);
void nudgeLeaf(VoxelNode* node, void* extraData);
void chunkifyLeaf(VoxelNode* node);