mirror of
https://github.com/overte-org/overte.git
synced 2025-04-25 17:35:45 +02:00
Merge pull request #316 from ey6es/master
Voxel editing improvements: apply color on add, menu items, free placement, dragging.
This commit is contained in:
commit
652832c207
2 changed files with 170 additions and 118 deletions
|
@ -18,6 +18,7 @@
|
||||||
#include <ifaddrs.h>
|
#include <ifaddrs.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <QActionGroup>
|
||||||
#include <QColorDialog>
|
#include <QColorDialog>
|
||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
#include <QGLWidget>
|
#include <QGLWidget>
|
||||||
|
@ -143,12 +144,10 @@ Application::Application(int& argc, char** argv) :
|
||||||
_mouseX(0),
|
_mouseX(0),
|
||||||
_mouseY(0),
|
_mouseY(0),
|
||||||
_mousePressed(false),
|
_mousePressed(false),
|
||||||
_mouseMode(NO_EDIT_MODE),
|
|
||||||
_mouseVoxelScale(1.0f / 1024.0f),
|
_mouseVoxelScale(1.0f / 1024.0f),
|
||||||
_paintOn(false),
|
_paintOn(false),
|
||||||
_dominantColor(0),
|
_dominantColor(0),
|
||||||
_perfStatsOn(false),
|
_perfStatsOn(false),
|
||||||
_destructiveAddVoxel(false),
|
|
||||||
_chatEntryOn(false),
|
_chatEntryOn(false),
|
||||||
_oculusTextureID(0),
|
_oculusTextureID(0),
|
||||||
_oculusProgram(0),
|
_oculusProgram(0),
|
||||||
|
@ -370,7 +369,8 @@ void Application::paintGL() {
|
||||||
glEnable(GL_COLOR_MATERIAL);
|
glEnable(GL_COLOR_MATERIAL);
|
||||||
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
|
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
|
||||||
|
|
||||||
GLfloat light_position0[] = { 1.0, 1.0, 0.0, 0.0 };
|
glm::vec3 relativeSunLoc = glm::normalize(_environment.getSunLocation() - whichCamera.getPosition());
|
||||||
|
GLfloat light_position0[] = { relativeSunLoc.x, relativeSunLoc.y, relativeSunLoc.z, 0.0 };
|
||||||
glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
|
glLightfv(GL_LIGHT0, GL_POSITION, light_position0);
|
||||||
GLfloat ambient_color[] = { 0.7, 0.7, 0.8 };
|
GLfloat ambient_color[] = { 0.7, 0.7, 0.8 };
|
||||||
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_color);
|
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_color);
|
||||||
|
@ -542,30 +542,6 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
||||||
case Qt::Key_Percent:
|
case Qt::Key_Percent:
|
||||||
sendVoxelServerAddScene();
|
sendVoxelServerAddScene();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Qt::Key_1:
|
|
||||||
_mouseMode = (_mouseMode == ADD_VOXEL_MODE) ? NO_EDIT_MODE : ADD_VOXEL_MODE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Qt::Key_2:
|
|
||||||
_mouseMode = (_mouseMode == DELETE_VOXEL_MODE) ? NO_EDIT_MODE : DELETE_VOXEL_MODE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Qt::Key_3:
|
|
||||||
_mouseMode = (_mouseMode == COLOR_VOXEL_MODE) ? NO_EDIT_MODE : COLOR_VOXEL_MODE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Qt::Key_4:
|
|
||||||
addVoxelInFrontOfAvatar();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Qt::Key_5:
|
|
||||||
_mouseVoxelScale /= 2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Qt::Key_6:
|
|
||||||
_mouseVoxelScale *= 2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Qt::Key_L:
|
case Qt::Key_L:
|
||||||
_displayLevels = !_displayLevels;
|
_displayLevels = !_displayLevels;
|
||||||
|
@ -689,6 +665,12 @@ void Application::keyReleaseEvent(QKeyEvent* event) {
|
||||||
void Application::mouseMoveEvent(QMouseEvent* event) {
|
void Application::mouseMoveEvent(QMouseEvent* event) {
|
||||||
_mouseX = event->x();
|
_mouseX = event->x();
|
||||||
_mouseY = event->y();
|
_mouseY = event->y();
|
||||||
|
|
||||||
|
// detect drag
|
||||||
|
glm::vec3 mouseVoxelPos(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z);
|
||||||
|
if (_colorVoxelMode->isChecked() && event->buttons().testFlag(Qt::LeftButton) && mouseVoxelPos != _lastMouseVoxelPos) {
|
||||||
|
addVoxelUnderCursor();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::mousePressEvent(QMouseEvent* event) {
|
void Application::mousePressEvent(QMouseEvent* event) {
|
||||||
|
@ -697,13 +679,13 @@ void Application::mousePressEvent(QMouseEvent* event) {
|
||||||
_mouseY = event->y();
|
_mouseY = event->y();
|
||||||
_mousePressed = true;
|
_mousePressed = true;
|
||||||
|
|
||||||
if (_mouseMode == ADD_VOXEL_MODE || _mouseMode == COLOR_VOXEL_MODE) {
|
if (_addVoxelMode->isChecked() || _colorVoxelMode->isChecked()) {
|
||||||
addVoxelUnderCursor();
|
addVoxelUnderCursor();
|
||||||
|
|
||||||
} else if (_mouseMode == DELETE_VOXEL_MODE) {
|
} else if (_deleteVoxelMode->isChecked()) {
|
||||||
deleteVoxelUnderCursor();
|
deleteVoxelUnderCursor();
|
||||||
}
|
}
|
||||||
} else if (event->button() == Qt::RightButton && _mouseMode != NO_EDIT_MODE) {
|
} else if (event->button() == Qt::RightButton && checkedVoxelModeAction() != 0) {
|
||||||
deleteVoxelUnderCursor();
|
deleteVoxelUnderCursor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -717,14 +699,14 @@ void Application::mouseReleaseEvent(QMouseEvent* event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::wheelEvent(QWheelEvent* event) {
|
void Application::wheelEvent(QWheelEvent* event) {
|
||||||
if (_mouseMode == NO_EDIT_MODE) {
|
if (checkedVoxelModeAction() == 0) {
|
||||||
event->ignore();
|
event->ignore();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (event->delta() > 0) {
|
if (event->delta() > 0) {
|
||||||
_mouseVoxelScale *= 2;
|
increaseVoxelSize();
|
||||||
} else {
|
} else {
|
||||||
_mouseVoxelScale /= 2;
|
decreaseVoxelSize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -814,48 +796,57 @@ void Application::idle() {
|
||||||
// tell my avatar the posiion and direction of the ray projected ino the world based on the mouse position
|
// tell my avatar the posiion and direction of the ray projected ino the world based on the mouse position
|
||||||
_myAvatar.setMouseRay(mouseRayOrigin, mouseRayDirection);
|
_myAvatar.setMouseRay(mouseRayOrigin, mouseRayDirection);
|
||||||
|
|
||||||
float distance;
|
|
||||||
BoxFace face;
|
|
||||||
_mouseVoxel.s = 0.0f;
|
_mouseVoxel.s = 0.0f;
|
||||||
if (_mouseMode != NO_EDIT_MODE && _voxels.findRayIntersection(
|
if (checkedVoxelModeAction() != 0) {
|
||||||
mouseRayOrigin, mouseRayDirection, _mouseVoxel, distance, face)) {
|
float distance;
|
||||||
// find the nearest voxel with the desired scale
|
BoxFace face;
|
||||||
if (_mouseVoxelScale > _mouseVoxel.s) {
|
if (_voxels.findRayIntersection(mouseRayOrigin, mouseRayDirection, _mouseVoxel, distance, face)) {
|
||||||
// choose the larger voxel that encompasses the one selected
|
// find the nearest voxel with the desired scale
|
||||||
_mouseVoxel.x = _mouseVoxelScale * floorf(_mouseVoxel.x / _mouseVoxelScale);
|
if (_mouseVoxelScale > _mouseVoxel.s) {
|
||||||
_mouseVoxel.y = _mouseVoxelScale * floorf(_mouseVoxel.y / _mouseVoxelScale);
|
// choose the larger voxel that encompasses the one selected
|
||||||
_mouseVoxel.z = _mouseVoxelScale * floorf(_mouseVoxel.z / _mouseVoxelScale);
|
_mouseVoxel.x = _mouseVoxelScale * floorf(_mouseVoxel.x / _mouseVoxelScale);
|
||||||
_mouseVoxel.s = _mouseVoxelScale;
|
_mouseVoxel.y = _mouseVoxelScale * floorf(_mouseVoxel.y / _mouseVoxelScale);
|
||||||
|
_mouseVoxel.z = _mouseVoxelScale * floorf(_mouseVoxel.z / _mouseVoxelScale);
|
||||||
} else {
|
|
||||||
glm::vec3 faceVector = getFaceVector(face);
|
|
||||||
if (_mouseVoxelScale < _mouseVoxel.s) {
|
|
||||||
// find the closest contained voxel
|
|
||||||
glm::vec3 pt = (mouseRayOrigin + mouseRayDirection * distance) / (float)TREE_SCALE -
|
|
||||||
faceVector * (_mouseVoxelScale * 0.5f);
|
|
||||||
_mouseVoxel.x = _mouseVoxelScale * floorf(pt.x / _mouseVoxelScale);
|
|
||||||
_mouseVoxel.y = _mouseVoxelScale * floorf(pt.y / _mouseVoxelScale);
|
|
||||||
_mouseVoxel.z = _mouseVoxelScale * floorf(pt.z / _mouseVoxelScale);
|
|
||||||
_mouseVoxel.s = _mouseVoxelScale;
|
_mouseVoxel.s = _mouseVoxelScale;
|
||||||
}
|
|
||||||
if (_mouseMode == ADD_VOXEL_MODE) {
|
|
||||||
// use the face to determine the side on which to create a neighbor
|
|
||||||
_mouseVoxel.x += faceVector.x * _mouseVoxel.s;
|
|
||||||
_mouseVoxel.y += faceVector.y * _mouseVoxel.s;
|
|
||||||
_mouseVoxel.z += faceVector.z * _mouseVoxel.s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_mouseMode == COLOR_VOXEL_MODE) {
|
} else {
|
||||||
|
glm::vec3 faceVector = getFaceVector(face);
|
||||||
|
if (_mouseVoxelScale < _mouseVoxel.s) {
|
||||||
|
// find the closest contained voxel
|
||||||
|
glm::vec3 pt = (mouseRayOrigin + mouseRayDirection * distance) / (float)TREE_SCALE -
|
||||||
|
faceVector * (_mouseVoxelScale * 0.5f);
|
||||||
|
_mouseVoxel.x = _mouseVoxelScale * floorf(pt.x / _mouseVoxelScale);
|
||||||
|
_mouseVoxel.y = _mouseVoxelScale * floorf(pt.y / _mouseVoxelScale);
|
||||||
|
_mouseVoxel.z = _mouseVoxelScale * floorf(pt.z / _mouseVoxelScale);
|
||||||
|
_mouseVoxel.s = _mouseVoxelScale;
|
||||||
|
}
|
||||||
|
if (_addVoxelMode->isChecked()) {
|
||||||
|
// use the face to determine the side on which to create a neighbor
|
||||||
|
_mouseVoxel.x += faceVector.x * _mouseVoxel.s;
|
||||||
|
_mouseVoxel.y += faceVector.y * _mouseVoxel.s;
|
||||||
|
_mouseVoxel.z += faceVector.z * _mouseVoxel.s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (_addVoxelMode->isChecked()) {
|
||||||
|
// place the voxel a fixed distance away
|
||||||
|
float worldMouseVoxelScale = _mouseVoxelScale * TREE_SCALE;
|
||||||
|
glm::vec3 pt = mouseRayOrigin + mouseRayDirection * (2.0f + worldMouseVoxelScale * 0.5f);
|
||||||
|
_mouseVoxel.x = _mouseVoxelScale * floorf(pt.x / worldMouseVoxelScale);
|
||||||
|
_mouseVoxel.y = _mouseVoxelScale * floorf(pt.y / worldMouseVoxelScale);
|
||||||
|
_mouseVoxel.z = _mouseVoxelScale * floorf(pt.z / worldMouseVoxelScale);
|
||||||
|
_mouseVoxel.s = _mouseVoxelScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_deleteVoxelMode->isChecked()) {
|
||||||
|
// red indicates deletion
|
||||||
|
_mouseVoxel.red = 255;
|
||||||
|
_mouseVoxel.green = _mouseVoxel.blue = 0;
|
||||||
|
|
||||||
|
} else { // _addVoxelMode->isChecked() || _colorVoxelMode->isChecked()
|
||||||
QColor paintColor = _voxelPaintColor->data().value<QColor>();
|
QColor paintColor = _voxelPaintColor->data().value<QColor>();
|
||||||
_mouseVoxel.red = paintColor.red();
|
_mouseVoxel.red = paintColor.red();
|
||||||
_mouseVoxel.green = paintColor.green();
|
_mouseVoxel.green = paintColor.green();
|
||||||
_mouseVoxel.blue = paintColor.blue();
|
_mouseVoxel.blue = paintColor.blue();
|
||||||
|
|
||||||
} else if (_mouseMode == DELETE_VOXEL_MODE) {
|
|
||||||
// red indicates deletion
|
|
||||||
_mouseVoxel.red = 255;
|
|
||||||
_mouseVoxel.green = _mouseVoxel.blue = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -985,10 +976,6 @@ void Application::cycleFrustumRenderMode() {
|
||||||
updateFrustumRenderModeAction();
|
updateFrustumRenderModeAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::setDestructivePaint(bool destructive) {
|
|
||||||
_destructiveAddVoxel = destructive;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::setRenderWarnings(bool renderWarnings) {
|
void Application::setRenderWarnings(bool renderWarnings) {
|
||||||
_voxels.setRenderPipelineWarnings(renderWarnings);
|
_voxels.setRenderPipelineWarnings(renderWarnings);
|
||||||
}
|
}
|
||||||
|
@ -1041,6 +1028,56 @@ void Application::setWantsDelta(bool wantsDelta) {
|
||||||
_myAvatar.setWantDelta(wantsDelta);
|
_myAvatar.setWantDelta(wantsDelta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::updateVoxelModeActions() {
|
||||||
|
// only the sender can be checked
|
||||||
|
foreach (QAction* action, _voxelModeActions->actions()) {
|
||||||
|
if (action->isChecked() && action != sender()) {
|
||||||
|
action->setChecked(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sendVoxelEditMessage(PACKET_HEADER header, VoxelDetail& detail) {
|
||||||
|
unsigned char* bufferOut;
|
||||||
|
int sizeOut;
|
||||||
|
|
||||||
|
if (createVoxelEditMessage(header, 0, 1, &detail, bufferOut, sizeOut)){
|
||||||
|
AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL, 1);
|
||||||
|
delete bufferOut;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::addVoxelInFrontOfAvatar() {
|
||||||
|
VoxelDetail detail;
|
||||||
|
|
||||||
|
glm::vec3 position = (_myAvatar.getPosition() + _myAvatar.getCameraDirection()) * (1.0f / TREE_SCALE);
|
||||||
|
detail.s = _mouseVoxelScale;
|
||||||
|
|
||||||
|
detail.x = detail.s * floor(position.x / detail.s);
|
||||||
|
detail.y = detail.s * floor(position.y / detail.s);
|
||||||
|
detail.z = detail.s * floor(position.z / detail.s);
|
||||||
|
QColor paintColor = _voxelPaintColor->data().value<QColor>();
|
||||||
|
detail.red = paintColor.red();
|
||||||
|
detail.green = paintColor.green();
|
||||||
|
detail.blue = paintColor.blue();
|
||||||
|
|
||||||
|
PACKET_HEADER message = (_destructiveAddVoxel->isChecked() ?
|
||||||
|
PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL);
|
||||||
|
sendVoxelEditMessage(message, detail);
|
||||||
|
|
||||||
|
// create the voxel locally so it appears immediately
|
||||||
|
_voxels.createVoxel(detail.x, detail.y, detail.z, detail.s,
|
||||||
|
detail.red, detail.green, detail.blue, _destructiveAddVoxel->isChecked());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::decreaseVoxelSize() {
|
||||||
|
_mouseVoxelScale /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::increaseVoxelSize() {
|
||||||
|
_mouseVoxelScale *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
static QIcon createSwatchIcon(const QColor& color) {
|
static QIcon createSwatchIcon(const QColor& color) {
|
||||||
QPixmap map(16, 16);
|
QPixmap map(16, 16);
|
||||||
map.fill(color);
|
map.fill(color);
|
||||||
|
@ -1093,11 +1130,29 @@ void Application::initMenu() {
|
||||||
_renderStatsOn->setShortcut(Qt::Key_Slash);
|
_renderStatsOn->setShortcut(Qt::Key_Slash);
|
||||||
(_logOn = toolsMenu->addAction("Log"))->setCheckable(true);
|
(_logOn = toolsMenu->addAction("Log"))->setCheckable(true);
|
||||||
_logOn->setChecked(true);
|
_logOn->setChecked(true);
|
||||||
_voxelPaintColor = toolsMenu->addAction("Voxel Paint Color", this, SLOT(chooseVoxelPaintColor()), Qt::Key_7);
|
|
||||||
|
QMenu* voxelMenu = menuBar->addMenu("Voxels");
|
||||||
|
_voxelModeActions = new QActionGroup(this);
|
||||||
|
_voxelModeActions->setExclusive(false); // exclusivity implies one is always checked
|
||||||
|
(_addVoxelMode = voxelMenu->addAction(
|
||||||
|
"Add Voxel Mode", this, SLOT(updateVoxelModeActions()), Qt::Key_1))->setCheckable(true);
|
||||||
|
_voxelModeActions->addAction(_addVoxelMode);
|
||||||
|
(_deleteVoxelMode = voxelMenu->addAction(
|
||||||
|
"Delete Voxel Mode", this, SLOT(updateVoxelModeActions()), Qt::Key_2))->setCheckable(true);
|
||||||
|
_voxelModeActions->addAction(_deleteVoxelMode);
|
||||||
|
(_colorVoxelMode = voxelMenu->addAction(
|
||||||
|
"Color Voxel Mode", this, SLOT(updateVoxelModeActions()), Qt::Key_3))->setCheckable(true);
|
||||||
|
_voxelModeActions->addAction(_colorVoxelMode);
|
||||||
|
|
||||||
|
voxelMenu->addAction("Place Voxel", this, SLOT(addVoxelInFrontOfAvatar()), Qt::Key_4);
|
||||||
|
voxelMenu->addAction("Decrease Voxel Size", this, SLOT(decreaseVoxelSize()), Qt::Key_5);
|
||||||
|
voxelMenu->addAction("Increase Voxel Size", this, SLOT(increaseVoxelSize()), Qt::Key_6);
|
||||||
|
|
||||||
|
_voxelPaintColor = voxelMenu->addAction("Voxel Paint Color", this, SLOT(chooseVoxelPaintColor()), Qt::Key_7);
|
||||||
QColor paintColor(128, 128, 128);
|
QColor paintColor(128, 128, 128);
|
||||||
_voxelPaintColor->setData(paintColor);
|
_voxelPaintColor->setData(paintColor);
|
||||||
_voxelPaintColor->setIcon(createSwatchIcon(paintColor));
|
_voxelPaintColor->setIcon(createSwatchIcon(paintColor));
|
||||||
toolsMenu->addAction("Create Voxel is Destructive", this, SLOT(setDestructivePaint(bool)))->setCheckable(true);
|
(_destructiveAddVoxel = voxelMenu->addAction("Create Voxel is Destructive"))->setCheckable(true);
|
||||||
|
|
||||||
QMenu* frustumMenu = menuBar->addMenu("Frustum");
|
QMenu* frustumMenu = menuBar->addMenu("Frustum");
|
||||||
(_frustumOn = frustumMenu->addAction("Display Frustum"))->setCheckable(true);
|
(_frustumOn = frustumMenu->addAction("Display Frustum"))->setCheckable(true);
|
||||||
|
@ -1184,16 +1239,6 @@ void Application::init() {
|
||||||
gettimeofday(&_lastTimeIdle, NULL);
|
gettimeofday(&_lastTimeIdle, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sendVoxelEditMessage(PACKET_HEADER header, VoxelDetail& detail) {
|
|
||||||
unsigned char* bufferOut;
|
|
||||||
int sizeOut;
|
|
||||||
|
|
||||||
if (createVoxelEditMessage(header, 0, 1, &detail, bufferOut, sizeOut)){
|
|
||||||
AgentList::getInstance()->broadcastToAgents(bufferOut, sizeOut, &AGENT_TYPE_VOXEL, 1);
|
|
||||||
delete bufferOut;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::updateAvatar(float deltaTime) {
|
void Application::updateAvatar(float deltaTime) {
|
||||||
// Update my avatar's head position from gyros
|
// Update my avatar's head position from gyros
|
||||||
_myAvatar.updateHeadFromGyros(deltaTime, &_serialPort, &_gravity);
|
_myAvatar.updateHeadFromGyros(deltaTime, &_serialPort, &_gravity);
|
||||||
|
@ -1318,7 +1363,8 @@ void Application::updateAvatar(float deltaTime) {
|
||||||
_paintingVoxel.y >= 0.0 && _paintingVoxel.y <= 1.0 &&
|
_paintingVoxel.y >= 0.0 && _paintingVoxel.y <= 1.0 &&
|
||||||
_paintingVoxel.z >= 0.0 && _paintingVoxel.z <= 1.0) {
|
_paintingVoxel.z >= 0.0 && _paintingVoxel.z <= 1.0) {
|
||||||
|
|
||||||
PACKET_HEADER message = (_destructiveAddVoxel ? PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL);
|
PACKET_HEADER message = (_destructiveAddVoxel->isChecked() ?
|
||||||
|
PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL);
|
||||||
sendVoxelEditMessage(message, _paintingVoxel);
|
sendVoxelEditMessage(message, _paintingVoxel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1568,8 +1614,9 @@ void Application::displaySide(Camera& whichCamera) {
|
||||||
|
|
||||||
// indicate what we'll be adding/removing in mouse mode, if anything
|
// indicate what we'll be adding/removing in mouse mode, if anything
|
||||||
if (_mouseVoxel.s != 0) {
|
if (_mouseVoxel.s != 0) {
|
||||||
|
glDisable(GL_LIGHTING);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
if (_mouseMode == ADD_VOXEL_MODE) {
|
if (_addVoxelMode->isChecked()) {
|
||||||
// use a contrasting color so that we can see what we're doing
|
// use a contrasting color so that we can see what we're doing
|
||||||
glColor3ub(_mouseVoxel.red + 128, _mouseVoxel.green + 128, _mouseVoxel.blue + 128);
|
glColor3ub(_mouseVoxel.red + 128, _mouseVoxel.green + 128, _mouseVoxel.blue + 128);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1583,6 +1630,7 @@ void Application::displaySide(Camera& whichCamera) {
|
||||||
glutWireCube(_mouseVoxel.s);
|
glutWireCube(_mouseVoxel.s);
|
||||||
glLineWidth(1.0f);
|
glLineWidth(1.0f);
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
glEnable(GL_LIGHTING);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_renderAvatarsOn->isChecked()) {
|
if (_renderAvatarsOn->isChecked()) {
|
||||||
|
@ -1887,35 +1935,18 @@ void Application::shiftPaintingColor() {
|
||||||
_paintingVoxel.blue = (_dominantColor == 2) ? randIntInRange(200, 255) : randIntInRange(40, 100);
|
_paintingVoxel.blue = (_dominantColor == 2) ? randIntInRange(200, 255) : randIntInRange(40, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::addVoxelInFrontOfAvatar() {
|
|
||||||
VoxelDetail detail;
|
|
||||||
|
|
||||||
glm::vec3 position = (_myAvatar.getPosition() + _myAvatar.getCameraDirection()) * (1.0f / TREE_SCALE);
|
|
||||||
detail.s = _mouseVoxelScale;
|
|
||||||
|
|
||||||
detail.x = detail.s * floor(position.x / detail.s);
|
|
||||||
detail.y = detail.s * floor(position.y / detail.s);
|
|
||||||
detail.z = detail.s * floor(position.z / detail.s);
|
|
||||||
QColor paintColor = _voxelPaintColor->data().value<QColor>();
|
|
||||||
detail.red = paintColor.red();
|
|
||||||
detail.green = paintColor.green();
|
|
||||||
detail.blue = paintColor.blue();
|
|
||||||
|
|
||||||
PACKET_HEADER message = (_destructiveAddVoxel ? PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL);
|
|
||||||
sendVoxelEditMessage(message, detail);
|
|
||||||
|
|
||||||
// create the voxel locally so it appears immediately
|
|
||||||
_voxels.createVoxel(detail.x, detail.y, detail.z, detail.s, detail.red, detail.green, detail.blue, _destructiveAddVoxel);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::addVoxelUnderCursor() {
|
void Application::addVoxelUnderCursor() {
|
||||||
if (_mouseVoxel.s != 0) {
|
if (_mouseVoxel.s != 0) {
|
||||||
PACKET_HEADER message = (_destructiveAddVoxel ? PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL);
|
PACKET_HEADER message = (_destructiveAddVoxel->isChecked() ?
|
||||||
|
PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL);
|
||||||
sendVoxelEditMessage(message, _mouseVoxel);
|
sendVoxelEditMessage(message, _mouseVoxel);
|
||||||
|
|
||||||
// create the voxel locally so it appears immediately
|
// create the voxel locally so it appears immediately
|
||||||
_voxels.createVoxel(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s,
|
_voxels.createVoxel(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s,
|
||||||
_mouseVoxel.red, _mouseVoxel.green, _mouseVoxel.blue, _destructiveAddVoxel);
|
_mouseVoxel.red, _mouseVoxel.green, _mouseVoxel.blue, _destructiveAddVoxel->isChecked());
|
||||||
|
|
||||||
|
// remember the position for drag detection
|
||||||
|
_lastMouseVoxelPos = glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1925,6 +1956,9 @@ void Application::deleteVoxelUnderCursor() {
|
||||||
|
|
||||||
// delete the voxel locally so it disappears immediately
|
// delete the voxel locally so it disappears immediately
|
||||||
_voxels.deleteVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
|
_voxels.deleteVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s);
|
||||||
|
|
||||||
|
// remember the position for drag detection
|
||||||
|
_lastMouseVoxelPos = glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1958,6 +1992,17 @@ void Application::setMenuShortcutsEnabled(bool enabled) {
|
||||||
setShortcutsEnabled(_window->menuBar(), enabled);
|
setShortcutsEnabled(_window->menuBar(), enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// when QActionGroup is set to non-exclusive, it doesn't return anything as checked;
|
||||||
|
// hence, we must check ourselves
|
||||||
|
QAction* Application::checkedVoxelModeAction() const {
|
||||||
|
foreach (QAction* action, _voxelModeActions->actions()) {
|
||||||
|
if (action->isChecked()) {
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void Application::attachNewHeadToAgent(Agent *newAgent) {
|
void Application::attachNewHeadToAgent(Agent *newAgent) {
|
||||||
if (newAgent->getLinkedData() == NULL) {
|
if (newAgent->getLinkedData() == NULL) {
|
||||||
newAgent->setLinkedData(new Avatar(false));
|
newAgent->setLinkedData(new Avatar(false));
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "ui/ChatEntry.h"
|
#include "ui/ChatEntry.h"
|
||||||
|
|
||||||
class QAction;
|
class QAction;
|
||||||
|
class QActionGroup;
|
||||||
class QGLWidget;
|
class QGLWidget;
|
||||||
class QKeyEvent;
|
class QKeyEvent;
|
||||||
class QMainWindow;
|
class QMainWindow;
|
||||||
|
@ -78,7 +79,6 @@ private slots:
|
||||||
void setFrustumOffset(bool frustumOffset);
|
void setFrustumOffset(bool frustumOffset);
|
||||||
void cycleFrustumRenderMode();
|
void cycleFrustumRenderMode();
|
||||||
|
|
||||||
void setDestructivePaint(bool destructive);
|
|
||||||
void setRenderWarnings(bool renderWarnings);
|
void setRenderWarnings(bool renderWarnings);
|
||||||
void doKillLocalVoxels();
|
void doKillLocalVoxels();
|
||||||
void doRandomizeVoxelColors();
|
void doRandomizeVoxelColors();
|
||||||
|
@ -91,6 +91,10 @@ private slots:
|
||||||
void setWantsMonochrome(bool wantsMonochrome);
|
void setWantsMonochrome(bool wantsMonochrome);
|
||||||
void setWantsResIn(bool wantsResIn);
|
void setWantsResIn(bool wantsResIn);
|
||||||
void setWantsDelta(bool wantsDelta);
|
void setWantsDelta(bool wantsDelta);
|
||||||
|
void updateVoxelModeActions();
|
||||||
|
void addVoxelInFrontOfAvatar();
|
||||||
|
void decreaseVoxelSize();
|
||||||
|
void increaseVoxelSize();
|
||||||
void chooseVoxelPaintColor();
|
void chooseVoxelPaintColor();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -112,7 +116,6 @@ private:
|
||||||
|
|
||||||
void setupPaintingVoxel();
|
void setupPaintingVoxel();
|
||||||
void shiftPaintingColor();
|
void shiftPaintingColor();
|
||||||
void addVoxelInFrontOfAvatar();
|
|
||||||
void addVoxelUnderCursor();
|
void addVoxelUnderCursor();
|
||||||
void deleteVoxelUnderCursor();
|
void deleteVoxelUnderCursor();
|
||||||
|
|
||||||
|
@ -120,6 +123,8 @@ private:
|
||||||
|
|
||||||
void setMenuShortcutsEnabled(bool enabled);
|
void setMenuShortcutsEnabled(bool enabled);
|
||||||
|
|
||||||
|
QAction* checkedVoxelModeAction() const;
|
||||||
|
|
||||||
static void attachNewHeadToAgent(Agent *newAgent);
|
static void attachNewHeadToAgent(Agent *newAgent);
|
||||||
static void* networkReceive(void* args);
|
static void* networkReceive(void* args);
|
||||||
|
|
||||||
|
@ -134,8 +139,13 @@ private:
|
||||||
QAction* _renderAvatarsOn; // Whether to render avatars
|
QAction* _renderAvatarsOn; // Whether to render avatars
|
||||||
QAction* _oculusOn; // Whether to configure the display for the Oculus Rift
|
QAction* _oculusOn; // Whether to configure the display for the Oculus Rift
|
||||||
QAction* _renderStatsOn; // Whether to show onscreen text overlay with stats
|
QAction* _renderStatsOn; // Whether to show onscreen text overlay with stats
|
||||||
QAction* _logOn; // Whether to show on-screen log
|
QAction* _logOn; // Whether to show on-screen log
|
||||||
|
QActionGroup* _voxelModeActions; // The group of voxel edit mode actions
|
||||||
|
QAction* _addVoxelMode; // Whether add voxel mode is enabled
|
||||||
|
QAction* _deleteVoxelMode; // Whether delete voxel mode is enabled
|
||||||
|
QAction* _colorVoxelMode; // Whether color voxel mode is enabled
|
||||||
QAction* _voxelPaintColor; // The color with which to paint voxels
|
QAction* _voxelPaintColor; // The color with which to paint voxels
|
||||||
|
QAction* _destructiveAddVoxel; // when doing voxel editing do we want them to be destructive
|
||||||
QAction* _frustumOn; // Whether or not to display the debug view frustum
|
QAction* _frustumOn; // Whether or not to display the debug view frustum
|
||||||
QAction* _viewFrustumFromOffset; // Whether or not to offset the view of the frustum
|
QAction* _viewFrustumFromOffset; // Whether or not to offset the view of the frustum
|
||||||
QAction* _cameraFrustum; // which frustum to look at
|
QAction* _cameraFrustum; // which frustum to look at
|
||||||
|
@ -191,18 +201,15 @@ private:
|
||||||
int _mouseY;
|
int _mouseY;
|
||||||
bool _mousePressed; // true if mouse has been pressed (clear when finished)
|
bool _mousePressed; // true if mouse has been pressed (clear when finished)
|
||||||
|
|
||||||
// The current mode for mouse interaction
|
VoxelDetail _mouseVoxel; // details of the voxel under the mouse cursor
|
||||||
enum MouseMode { NO_EDIT_MODE, ADD_VOXEL_MODE, DELETE_VOXEL_MODE, COLOR_VOXEL_MODE };
|
float _mouseVoxelScale; // the scale for adding/removing voxels
|
||||||
MouseMode _mouseMode;
|
glm::vec3 _lastMouseVoxelPos; // the position of the last mouse voxel edit
|
||||||
VoxelDetail _mouseVoxel; // details of the voxel under the mouse cursor
|
|
||||||
float _mouseVoxelScale; // the scale for adding/removing voxels
|
|
||||||
|
|
||||||
bool _paintOn; // Whether to paint voxels as you fly around
|
bool _paintOn; // Whether to paint voxels as you fly around
|
||||||
unsigned char _dominantColor; // The dominant color of the voxel we're painting
|
unsigned char _dominantColor; // The dominant color of the voxel we're painting
|
||||||
VoxelDetail _paintingVoxel; // The voxel we're painting if we're painting
|
VoxelDetail _paintingVoxel; // The voxel we're painting if we're painting
|
||||||
|
|
||||||
bool _perfStatsOn; // Do we want to display perfStats?
|
bool _perfStatsOn; // Do we want to display perfStats?
|
||||||
bool _destructiveAddVoxel; // when doing voxel editing do we want them to be destructive
|
|
||||||
|
|
||||||
ChatEntry _chatEntry; // chat entry field
|
ChatEntry _chatEntry; // chat entry field
|
||||||
bool _chatEntryOn; // Whether to show the chat entry
|
bool _chatEntryOn; // Whether to show the chat entry
|
||||||
|
|
Loading…
Reference in a new issue