More work on metavoxel editing (track mouse ray intersection with grid).

This commit is contained in:
Andrzej Kapolka 2014-01-22 11:11:12 -08:00
parent 0a3d6ae5e0
commit 15021b6ebc
3 changed files with 62 additions and 47 deletions

View file

@ -1896,25 +1896,23 @@ const float HEAD_SPHERE_RADIUS = 0.07f;
static QUuid DEFAULT_NODE_ID_REF;
void Application::updateLookatTargetAvatar(const glm::vec3& mouseRayOrigin, const glm::vec3& mouseRayDirection,
glm::vec3& eyePosition) {
void Application::updateLookatTargetAvatar(glm::vec3& eyePosition) {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateLookatTargetAvatar()");
if (!_mousePressed) {
_lookatTargetAvatar = findLookatTargetAvatar(mouseRayOrigin, mouseRayDirection, eyePosition, DEFAULT_NODE_ID_REF);
_lookatTargetAvatar = findLookatTargetAvatar(eyePosition, DEFAULT_NODE_ID_REF);
}
}
Avatar* Application::findLookatTargetAvatar(const glm::vec3& mouseRayOrigin, const glm::vec3& mouseRayDirection,
glm::vec3& eyePosition, QUuid& nodeUUID = DEFAULT_NODE_ID_REF) {
Avatar* Application::findLookatTargetAvatar(glm::vec3& eyePosition, QUuid& nodeUUID = DEFAULT_NODE_ID_REF) {
foreach (const SharedNodePointer& node, NodeList::getInstance()->getNodeHash()) {
if (node->getLinkedData() != NULL && node->getType() == NODE_TYPE_AGENT) {
Avatar* avatar = (Avatar*)node->getLinkedData();
float distance;
if (avatar->findRayIntersection(mouseRayOrigin, mouseRayDirection, distance)) {
if (avatar->findRayIntersection(_mouseRayOrigin, _mouseRayDirection, distance)) {
// rescale to compensate for head embiggening
eyePosition = (avatar->getHead().calculateAverageEyePosition() - avatar->getHead().getScalePivot()) *
(avatar->getScale() / avatar->getHead().getScale()) + avatar->getHead().getScalePivot();
@ -1965,7 +1963,7 @@ void Application::renderHighlightVoxel(VoxelDetail voxel) {
glPopMatrix();
}
void Application::updateAvatars(float deltaTime, glm::vec3 mouseRayOrigin, glm::vec3 mouseRayDirection) {
void Application::updateAvatars(float deltaTime) {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateAvatars()");
@ -1977,7 +1975,7 @@ void Application::updateAvatars(float deltaTime, glm::vec3 mouseRayOrigin, glm::
avatar->init();
}
avatar->simulate(deltaTime, NULL);
avatar->setMouseRay(mouseRayOrigin, mouseRayDirection);
avatar->setMouseRay(_mouseRayOrigin, _mouseRayDirection);
}
}
@ -2000,28 +1998,28 @@ void Application::updateAvatars(float deltaTime, glm::vec3 mouseRayOrigin, glm::
}
}
void Application::updateMouseRay(float deltaTime, glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection) {
void Application::updateMouseRay() {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateMouseRay()");
_viewFrustum.computePickRay(_mouseX / (float)_glWidget->width(), _mouseY / (float)_glWidget->height(),
mouseRayOrigin, mouseRayDirection);
_mouseRayOrigin, _mouseRayDirection);
// adjust for mirroring
if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
glm::vec3 mouseRayOffset = mouseRayOrigin - _viewFrustum.getPosition();
mouseRayOrigin -= 2.0f * (_viewFrustum.getDirection() * glm::dot(_viewFrustum.getDirection(), mouseRayOffset) +
glm::vec3 mouseRayOffset = _mouseRayOrigin - _viewFrustum.getPosition();
_mouseRayOrigin -= 2.0f * (_viewFrustum.getDirection() * glm::dot(_viewFrustum.getDirection(), mouseRayOffset) +
_viewFrustum.getRight() * glm::dot(_viewFrustum.getRight(), mouseRayOffset));
mouseRayDirection -= 2.0f * (_viewFrustum.getDirection() * glm::dot(_viewFrustum.getDirection(), mouseRayDirection) +
_viewFrustum.getRight() * glm::dot(_viewFrustum.getRight(), mouseRayDirection));
_mouseRayDirection -= 2.0f * (_viewFrustum.getDirection() * glm::dot(_viewFrustum.getDirection(), _mouseRayDirection) +
_viewFrustum.getRight() * glm::dot(_viewFrustum.getRight(), _mouseRayDirection));
}
// tell my avatar if the mouse is being pressed...
_myAvatar.setMousePressed(_mousePressed);
// 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);
}
void Application::updateFaceshift() {
@ -2038,8 +2036,7 @@ void Application::updateFaceshift() {
}
}
void Application::updateMyAvatarLookAtPosition(glm::vec3& lookAtSpot, glm::vec3& lookAtRayOrigin,
glm::vec3& lookAtRayDirection) {
void Application::updateMyAvatarLookAtPosition(glm::vec3& lookAtSpot) {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateMyAvatarLookAtPosition()");
@ -2061,7 +2058,7 @@ void Application::updateMyAvatarLookAtPosition(glm::vec3& lookAtSpot, glm::vec3&
} else {
// Just look in direction of the mouse ray
lookAtSpot = lookAtRayOrigin + lookAtRayDirection * FAR_AWAY_STARE;
lookAtSpot = _mouseRayOrigin + _mouseRayDirection * FAR_AWAY_STARE;
}
}
if (_faceshift.isActive()) {
@ -2076,8 +2073,7 @@ void Application::updateMyAvatarLookAtPosition(glm::vec3& lookAtSpot, glm::vec3&
_myAvatar.getHead().setLookAtPosition(lookAtSpot);
}
void Application::updateHoverVoxels(float deltaTime, glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection,
float& distance, BoxFace& face) {
void Application::updateHoverVoxels(float deltaTime, float& distance, BoxFace& face) {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateHoverVoxels()");
@ -2108,7 +2104,7 @@ void Application::updateHoverVoxels(float deltaTime, glm::vec3& mouseRayOrigin,
if (!(_voxels.treeIsBusy() || _mousePressed)) {
{
PerformanceWarning warn(showWarnings, "Application::updateHoverVoxels() _voxels.findRayIntersection()");
_isHoverVoxel = _voxels.findRayIntersection(mouseRayOrigin, mouseRayDirection, _hoverVoxel, distance, face);
_isHoverVoxel = _voxels.findRayIntersection(_mouseRayOrigin, _mouseRayDirection, _hoverVoxel, distance, face);
}
if (MAKE_SOUND_ON_VOXEL_HOVER && _isHoverVoxel &&
glm::vec4(_hoverVoxel.x, _hoverVoxel.y, _hoverVoxel.z, _hoverVoxel.s) != oldVoxel) {
@ -2124,8 +2120,7 @@ void Application::updateHoverVoxels(float deltaTime, glm::vec3& mouseRayOrigin,
}
}
void Application::updateMouseVoxels(float deltaTime, glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection,
float& distance, BoxFace& face) {
void Application::updateMouseVoxels(float deltaTime, float& distance, BoxFace& face) {
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
PerformanceWarning warn(showWarnings, "Application::updateMouseVoxels()");
@ -2137,7 +2132,7 @@ void Application::updateMouseVoxels(float deltaTime, glm::vec3& mouseRayOrigin,
fabs(_myAvatar.getVelocity().y) +
fabs(_myAvatar.getVelocity().z)) / 3 < MAX_AVATAR_EDIT_VELOCITY) {
if (_voxels.findRayIntersection(mouseRayOrigin, mouseRayDirection, _mouseVoxel, distance, face)) {
if (_voxels.findRayIntersection(_mouseRayOrigin, _mouseRayDirection, _mouseVoxel, distance, face)) {
if (distance < MAX_VOXEL_EDIT_DISTANCE) {
// set the voxel scale to that of the first moused-over voxel
if (!wasInitialized) {
@ -2157,7 +2152,7 @@ void Application::updateMouseVoxels(float deltaTime, glm::vec3& mouseRayOrigin,
glm::vec3 faceVector = getFaceVector(face);
if (_mouseVoxelScale < _mouseVoxel.s) {
// find the closest contained voxel
glm::vec3 pt = (mouseRayOrigin + mouseRayDirection * distance) / (float)TREE_SCALE -
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);
@ -2178,7 +2173,7 @@ void Application::updateMouseVoxels(float deltaTime, glm::vec3& mouseRayOrigin,
|| Menu::getInstance()->isOptionChecked(MenuOption::VoxelSelectMode)) {
// place the voxel a fixed distance away
float worldMouseVoxelScale = _mouseVoxelScale * TREE_SCALE;
glm::vec3 pt = mouseRayOrigin + mouseRayDirection * (2.0f + worldMouseVoxelScale * 0.5f);
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);
@ -2412,29 +2407,28 @@ void Application::update(float deltaTime) {
PerformanceWarning warn(showWarnings, "Application::update()");
// check what's under the mouse and update the mouse voxel
glm::vec3 mouseRayOrigin, mouseRayDirection;
updateMouseRay(deltaTime, mouseRayOrigin, mouseRayDirection);
updateMouseRay();
// Set where I am looking based on my mouse ray (so that other people can see)
glm::vec3 lookAtSpot;
updateFaceshift();
updateLookatTargetAvatar(mouseRayOrigin, mouseRayDirection, lookAtSpot);
updateMyAvatarLookAtPosition(lookAtSpot, mouseRayOrigin, mouseRayDirection);
updateLookatTargetAvatar(lookAtSpot);
updateMyAvatarLookAtPosition(lookAtSpot);
// Find the voxel we are hovering over, and respond if clicked
float distance;
BoxFace face;
updateHoverVoxels(deltaTime, mouseRayOrigin, mouseRayDirection, distance, face); // clicking on voxels and making sounds
updateMouseVoxels(deltaTime, mouseRayOrigin, mouseRayDirection, distance, face); // UI/UX related to voxels
updateHoverVoxels(deltaTime, distance, face); // clicking on voxels and making sounds
updateMouseVoxels(deltaTime, distance, face); // UI/UX related to voxels
updateHandAndTouch(deltaTime); // Update state for touch sensors
updateLeap(deltaTime); // Leap finger-sensing device
updateSixense(deltaTime); // Razer Hydra controllers
updateSerialDevices(deltaTime); // Read serial port interface devices
updateAvatar(deltaTime); // Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes
updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process...
updateAvatars(deltaTime, mouseRayOrigin, mouseRayDirection); //loop through all the other avatars and simulate them...
updateAvatars(deltaTime); //loop through all the other avatars and simulate them...
updateMyAvatarSimulation(deltaTime); // Simulate myself
updateParticles(deltaTime); // Simulate particle cloud movements
updateMetavoxels(deltaTime); // update metavoxels

View file

@ -155,6 +155,8 @@ public:
VoxelTree* getClipboard() { return &_clipboard; }
Environment* getEnvironment() { return &_environment; }
bool isMouseHidden() const { return _mouseHidden; }
const glm::vec3& getMouseRayOrigin() const { return _mouseRayOrigin; }
const glm::vec3& getMouseRayDirection() const { return _mouseRayDirection; }
Faceshift* getFaceshift() { return &_faceshift; }
SixenseManager* getSixenseManager() { return &_sixenseManager; }
BandwidthMeter* getBandwidthMeter() { return &_bandwidthMeter; }
@ -280,15 +282,12 @@ private:
void update(float deltaTime);
// Various helper functions called during update()
void updateMouseRay(float deltaTime, glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection);
void updateMouseRay();
void updateFaceshift();
void updateMyAvatarLookAtPosition(glm::vec3& lookAtSpot, glm::vec3& lookAtRayOrigin, glm::vec3& lookAtRayDirection);
void updateHoverVoxels(float deltaTime, glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection,
float& distance, BoxFace& face);
void updateMouseVoxels(float deltaTime, glm::vec3& mouseRayOrigin, glm::vec3& mouseRayDirection,
float& distance, BoxFace& face);
void updateLookatTargetAvatar(const glm::vec3& mouseRayOrigin, const glm::vec3& mouseRayDirection,
glm::vec3& eyePosition);
void updateMyAvatarLookAtPosition(glm::vec3& lookAtSpot);
void updateHoverVoxels(float deltaTime, float& distance, BoxFace& face);
void updateMouseVoxels(float deltaTime, float& distance, BoxFace& face);
void updateLookatTargetAvatar(glm::vec3& eyePosition);
void updateHandAndTouch(float deltaTime);
void updateLeap(float deltaTime);
void updateSixense(float deltaTime);
@ -303,15 +302,14 @@ private:
void updateAudio(float deltaTime);
void updateCursor(float deltaTime);
Avatar* findLookatTargetAvatar(const glm::vec3& mouseRayOrigin, const glm::vec3& mouseRayDirection,
glm::vec3& eyePosition, QUuid &nodeUUID);
Avatar* findLookatTargetAvatar(glm::vec3& eyePosition, QUuid &nodeUUID);
bool isLookingAtMyAvatar(Avatar* avatar);
void renderLookatIndicator(glm::vec3 pointOfInterest);
void renderHighlightVoxel(VoxelDetail voxel);
void updateAvatar(float deltaTime);
void updateAvatars(float deltaTime, glm::vec3 mouseRayOrigin, glm::vec3 mouseRayDirection);
void updateAvatars(float deltaTime);
void queryOctree(NODE_TYPE serverType, PACKET_TYPE packetType, NodeToJurisdictionMap& jurisdictions);
void loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum);
@ -413,6 +411,9 @@ private:
bool _mouseHidden;
bool _seenMouseMove;
glm::vec3 _mouseRayOrigin;
glm::vec3 _mouseRayDirection;
float _touchAvgX;
float _touchAvgY;
float _lastTouchAvgX;

View file

@ -164,12 +164,32 @@ void MetavoxelEditorDialog::render() {
break;
}
// find the intersection of the rotated mouse ray with the plane
glm::vec3 rayOrigin = rotation * Application::getInstance()->getMouseRayOrigin();
glm::vec3 rayDirection = rotation * Application::getInstance()->getMouseRayDirection();
float spacing = _gridSpacing->value();
float position = _gridPosition->value();
if (fabs(rayDirection.z) > EPSILON) {
float distance = (position - rayOrigin.z) / rayDirection.z;
glm::vec3 intersection = rayOrigin + rayDirection * distance;
glLineWidth(4.0f);
glBegin(GL_LINE_LOOP);
float x = spacing * floorf(intersection.x / spacing);
float y = spacing * floorf(intersection.y / spacing);
glVertex3f(x, y, position);
glVertex3f(x + spacing, y, position);
glVertex3f(x + spacing, y + spacing, position);
glVertex3f(x, y + spacing, position);
glEnd();
glLineWidth(1.0f);
}
// center the grid around the camera position on the plane
glm::vec3 rotated = rotation * Application::getInstance()->getCamera()->getPosition();
float spacing = _gridSpacing->value();
const int GRID_DIVISIONS = 300;
glTranslatef(spacing * (floor(rotated.x / spacing) - GRID_DIVISIONS / 2),
spacing * (floor(rotated.y / spacing) - GRID_DIVISIONS / 2), _gridPosition->value());
glTranslatef(spacing * (floorf(rotated.x / spacing) - GRID_DIVISIONS / 2),
spacing * (floorf(rotated.y / spacing) - GRID_DIVISIONS / 2), position);
float scale = GRID_DIVISIONS * spacing;
glScalef(scale, scale, scale);