mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +02:00
Merge pull request #1735 from AndrewMeadows/fix-particle-avatar-collisions
Fix crash on shutdown caused by duplicate delete on a QObject
This commit is contained in:
commit
c58f44f54a
6 changed files with 145 additions and 142 deletions
|
@ -121,6 +121,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
|||
_wantToKillLocalVoxels(false),
|
||||
_audioScope(256, 200, true),
|
||||
_avatarManager(),
|
||||
_myAvatar(NULL),
|
||||
_profile(QString()),
|
||||
_mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)),
|
||||
_mouseX(0),
|
||||
|
@ -157,6 +158,8 @@ Application::Application(int& argc, char** argv, timeval &startup_time) :
|
|||
_logger(new FileLogger()),
|
||||
_persistThread(NULL)
|
||||
{
|
||||
_myAvatar = _avatarManager.getMyAvatar();
|
||||
|
||||
_applicationStartupTime = startup_time;
|
||||
|
||||
switchToResourcesParentIfRequired();
|
||||
|
@ -327,6 +330,9 @@ Application::~Application() {
|
|||
VoxelTreeElement::removeDeleteHook(&_voxels); // we don't need to do this processing on shutdown
|
||||
Menu::getInstance()->deleteLater();
|
||||
|
||||
_avatarManager.clear();
|
||||
_myAvatar = NULL;
|
||||
|
||||
delete _logger;
|
||||
delete _settings;
|
||||
delete _glWidget;
|
||||
|
@ -441,25 +447,25 @@ void Application::paintGL() {
|
|||
_myCamera.setUpShift (0.0f);
|
||||
_myCamera.setDistance (0.0f);
|
||||
_myCamera.setTightness (0.0f); // Camera is directly connected to head without smoothing
|
||||
_myCamera.setTargetPosition(_myAvatar.getHead().calculateAverageEyePosition());
|
||||
_myCamera.setTargetRotation(_myAvatar.getHead().getOrientation());
|
||||
_myCamera.setTargetPosition(_myAvatar->getHead().calculateAverageEyePosition());
|
||||
_myCamera.setTargetRotation(_myAvatar->getHead().getOrientation());
|
||||
|
||||
} else if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {
|
||||
_myCamera.setTightness(0.0f); // In first person, camera follows head exactly without delay
|
||||
_myCamera.setTargetPosition(_myAvatar.getHead().calculateAverageEyePosition());
|
||||
_myCamera.setTargetRotation(_myAvatar.getHead().getCameraOrientation());
|
||||
_myCamera.setTargetPosition(_myAvatar->getHead().calculateAverageEyePosition());
|
||||
_myCamera.setTargetRotation(_myAvatar->getHead().getCameraOrientation());
|
||||
|
||||
} else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
|
||||
_myCamera.setTightness (0.0f); // Camera is directly connected to head without smoothing
|
||||
_myCamera.setTargetPosition(_myAvatar.getUprightHeadPosition());
|
||||
_myCamera.setTargetRotation(_myAvatar.getHead().getCameraOrientation());
|
||||
_myCamera.setTargetPosition(_myAvatar->getUprightHeadPosition());
|
||||
_myCamera.setTargetRotation(_myAvatar->getHead().getCameraOrientation());
|
||||
|
||||
} else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
|
||||
_myCamera.setTightness(0.0f);
|
||||
float headHeight = _myAvatar.getHead().calculateAverageEyePosition().y - _myAvatar.getPosition().y;
|
||||
_myCamera.setDistance(MIRROR_FULLSCREEN_DISTANCE * _myAvatar.getScale());
|
||||
_myCamera.setTargetPosition(_myAvatar.getPosition() + glm::vec3(0, headHeight, 0));
|
||||
_myCamera.setTargetRotation(_myAvatar.getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PIf, 0.0f)));
|
||||
float headHeight = _myAvatar->getHead().calculateAverageEyePosition().y - _myAvatar->getPosition().y;
|
||||
_myCamera.setDistance(MIRROR_FULLSCREEN_DISTANCE * _myAvatar->getScale());
|
||||
_myCamera.setTargetPosition(_myAvatar->getPosition() + glm::vec3(0, headHeight, 0));
|
||||
_myCamera.setTargetRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PIf, 0.0f)));
|
||||
}
|
||||
|
||||
// Update camera position
|
||||
|
@ -516,22 +522,22 @@ void Application::paintGL() {
|
|||
|
||||
bool eyeRelativeCamera = false;
|
||||
if (_rearMirrorTools->getZoomLevel() == BODY) {
|
||||
_mirrorCamera.setDistance(MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar.getScale());
|
||||
_mirrorCamera.setTargetPosition(_myAvatar.getChestPosition());
|
||||
_mirrorCamera.setDistance(MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar->getScale());
|
||||
_mirrorCamera.setTargetPosition(_myAvatar->getChestPosition());
|
||||
} else { // HEAD zoom level
|
||||
_mirrorCamera.setDistance(MIRROR_REARVIEW_DISTANCE * _myAvatar.getScale());
|
||||
if (_myAvatar.getSkeletonModel().isActive() && _myAvatar.getHead().getFaceModel().isActive()) {
|
||||
_mirrorCamera.setDistance(MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale());
|
||||
if (_myAvatar->getSkeletonModel().isActive() && _myAvatar->getHead().getFaceModel().isActive()) {
|
||||
// as a hack until we have a better way of dealing with coordinate precision issues, reposition the
|
||||
// face/body so that the average eye position lies at the origin
|
||||
eyeRelativeCamera = true;
|
||||
_mirrorCamera.setTargetPosition(glm::vec3());
|
||||
|
||||
} else {
|
||||
_mirrorCamera.setTargetPosition(_myAvatar.getHead().calculateAverageEyePosition());
|
||||
_mirrorCamera.setTargetPosition(_myAvatar->getHead().calculateAverageEyePosition());
|
||||
}
|
||||
}
|
||||
|
||||
_mirrorCamera.setTargetRotation(_myAvatar.getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PIf, 0.0f)));
|
||||
_mirrorCamera.setTargetRotation(_myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PIf, 0.0f)));
|
||||
_mirrorCamera.update(1.0f/_fps);
|
||||
|
||||
// set the bounds of rear mirror view
|
||||
|
@ -548,27 +554,27 @@ void Application::paintGL() {
|
|||
glPushMatrix();
|
||||
if (eyeRelativeCamera) {
|
||||
// save absolute translations
|
||||
glm::vec3 absoluteSkeletonTranslation = _myAvatar.getSkeletonModel().getTranslation();
|
||||
glm::vec3 absoluteFaceTranslation = _myAvatar.getHead().getFaceModel().getTranslation();
|
||||
glm::vec3 absoluteSkeletonTranslation = _myAvatar->getSkeletonModel().getTranslation();
|
||||
glm::vec3 absoluteFaceTranslation = _myAvatar->getHead().getFaceModel().getTranslation();
|
||||
|
||||
// get the eye positions relative to the neck and use them to set the face translation
|
||||
glm::vec3 leftEyePosition, rightEyePosition;
|
||||
_myAvatar.getHead().getFaceModel().setTranslation(glm::vec3());
|
||||
_myAvatar.getHead().getFaceModel().getEyePositions(leftEyePosition, rightEyePosition);
|
||||
_myAvatar.getHead().getFaceModel().setTranslation((leftEyePosition + rightEyePosition) * -0.5f);
|
||||
_myAvatar->getHead().getFaceModel().setTranslation(glm::vec3());
|
||||
_myAvatar->getHead().getFaceModel().getEyePositions(leftEyePosition, rightEyePosition);
|
||||
_myAvatar->getHead().getFaceModel().setTranslation((leftEyePosition + rightEyePosition) * -0.5f);
|
||||
|
||||
// get the neck position relative to the body and use it to set the skeleton translation
|
||||
glm::vec3 neckPosition;
|
||||
_myAvatar.getSkeletonModel().setTranslation(glm::vec3());
|
||||
_myAvatar.getSkeletonModel().getNeckPosition(neckPosition);
|
||||
_myAvatar.getSkeletonModel().setTranslation(_myAvatar.getHead().getFaceModel().getTranslation() -
|
||||
_myAvatar->getSkeletonModel().setTranslation(glm::vec3());
|
||||
_myAvatar->getSkeletonModel().getNeckPosition(neckPosition);
|
||||
_myAvatar->getSkeletonModel().setTranslation(_myAvatar->getHead().getFaceModel().getTranslation() -
|
||||
neckPosition);
|
||||
|
||||
displaySide(_mirrorCamera, true);
|
||||
|
||||
// restore absolute translations
|
||||
_myAvatar.getSkeletonModel().setTranslation(absoluteSkeletonTranslation);
|
||||
_myAvatar.getHead().getFaceModel().setTranslation(absoluteFaceTranslation);
|
||||
_myAvatar->getSkeletonModel().setTranslation(absoluteSkeletonTranslation);
|
||||
_myAvatar->getHead().getFaceModel().setTranslation(absoluteFaceTranslation);
|
||||
} else {
|
||||
displaySide(_mirrorCamera, true);
|
||||
}
|
||||
|
@ -689,12 +695,12 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
if (activeWindow() == _window) {
|
||||
if (_chatEntryOn) {
|
||||
if (_chatEntry.keyPressEvent(event)) {
|
||||
_myAvatar.setKeyState(event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete ?
|
||||
_myAvatar->setKeyState(event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete ?
|
||||
DELETE_KEY_DOWN : INSERT_KEY_DOWN);
|
||||
_myAvatar.setChatMessage(string(_chatEntry.getContents().size(), SOLID_BLOCK_CHAR));
|
||||
_myAvatar->setChatMessage(string(_chatEntry.getContents().size(), SOLID_BLOCK_CHAR));
|
||||
|
||||
} else {
|
||||
_myAvatar.setChatMessage(_chatEntry.getContents());
|
||||
_myAvatar->setChatMessage(_chatEntry.getContents());
|
||||
_chatEntry.clear();
|
||||
_chatEntryOn = false;
|
||||
setMenuShortcutsEnabled(true);
|
||||
|
@ -738,10 +744,10 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
if (_nudgeStarted) {
|
||||
_nudgeGuidePosition.y += _mouseVoxel.s;
|
||||
} else {
|
||||
if (!_myAvatar.getDriveKeys(UP)) {
|
||||
_myAvatar.jump();
|
||||
if (!_myAvatar->getDriveKeys(UP)) {
|
||||
_myAvatar->jump();
|
||||
}
|
||||
_myAvatar.setDriveKeys(UP, 1);
|
||||
_myAvatar->setDriveKeys(UP, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -753,7 +759,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
if (_nudgeStarted) {
|
||||
_nudgeGuidePosition.y -= _mouseVoxel.s;
|
||||
} else {
|
||||
_myAvatar.setDriveKeys(DOWN, 1);
|
||||
_myAvatar->setDriveKeys(DOWN, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -773,7 +779,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
_myAvatar.setDriveKeys(FWD, 1);
|
||||
_myAvatar->setDriveKeys(FWD, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -799,7 +805,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
_myAvatar.setDriveKeys(BACK, 1);
|
||||
_myAvatar->setDriveKeys(BACK, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -833,7 +839,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
_myAvatar.setDriveKeys(ROT_LEFT, 1);
|
||||
_myAvatar->setDriveKeys(ROT_LEFT, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -853,7 +859,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
_myAvatar.setDriveKeys(ROT_RIGHT, 1);
|
||||
_myAvatar->setDriveKeys(ROT_RIGHT, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -863,8 +869,8 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
nudgeVoxels();
|
||||
} else {
|
||||
_chatEntryOn = true;
|
||||
_myAvatar.setKeyState(NO_KEY_DOWN);
|
||||
_myAvatar.setChatMessage(string());
|
||||
_myAvatar->setKeyState(NO_KEY_DOWN);
|
||||
_myAvatar->setChatMessage(string());
|
||||
setMenuShortcutsEnabled(false);
|
||||
}
|
||||
break;
|
||||
|
@ -887,7 +893,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
} else if (_nudgeStarted && isShifted) {
|
||||
_nudgeGuidePosition.y += _mouseVoxel.s;
|
||||
} else {
|
||||
_myAvatar.setDriveKeys(isShifted ? UP : FWD, 1);
|
||||
_myAvatar->setDriveKeys(isShifted ? UP : FWD, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -909,7 +915,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
} else if (_nudgeStarted && isShifted) {
|
||||
_nudgeGuidePosition.y -= _mouseVoxel.s;
|
||||
} else {
|
||||
_myAvatar.setDriveKeys(isShifted ? DOWN : BACK, 1);
|
||||
_myAvatar->setDriveKeys(isShifted ? DOWN : BACK, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -929,7 +935,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
_myAvatar.setDriveKeys(isShifted ? LEFT : ROT_LEFT, 1);
|
||||
_myAvatar->setDriveKeys(isShifted ? LEFT : ROT_LEFT, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -949,7 +955,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
_myAvatar.setDriveKeys(isShifted ? RIGHT : ROT_RIGHT, 1);
|
||||
_myAvatar->setDriveKeys(isShifted ? RIGHT : ROT_RIGHT, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1067,13 +1073,13 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
}
|
||||
break;
|
||||
case Qt::Key_Plus:
|
||||
_myAvatar.increaseSize();
|
||||
_myAvatar->increaseSize();
|
||||
break;
|
||||
case Qt::Key_Minus:
|
||||
_myAvatar.decreaseSize();
|
||||
_myAvatar->decreaseSize();
|
||||
break;
|
||||
case Qt::Key_Equal:
|
||||
_myAvatar.resetSize();
|
||||
_myAvatar->resetSize();
|
||||
break;
|
||||
|
||||
case Qt::Key_1:
|
||||
|
@ -1108,7 +1114,7 @@ void Application::keyReleaseEvent(QKeyEvent* event) {
|
|||
|
||||
if (activeWindow() == _window) {
|
||||
if (_chatEntryOn) {
|
||||
_myAvatar.setKeyState(NO_KEY_DOWN);
|
||||
_myAvatar->setKeyState(NO_KEY_DOWN);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1117,47 +1123,47 @@ void Application::keyReleaseEvent(QKeyEvent* event) {
|
|||
_pasteMode = false;
|
||||
break;
|
||||
case Qt::Key_E:
|
||||
_myAvatar.setDriveKeys(UP, 0);
|
||||
_myAvatar->setDriveKeys(UP, 0);
|
||||
break;
|
||||
|
||||
case Qt::Key_C:
|
||||
_myAvatar.setDriveKeys(DOWN, 0);
|
||||
_myAvatar->setDriveKeys(DOWN, 0);
|
||||
break;
|
||||
|
||||
case Qt::Key_W:
|
||||
_myAvatar.setDriveKeys(FWD, 0);
|
||||
_myAvatar->setDriveKeys(FWD, 0);
|
||||
break;
|
||||
|
||||
case Qt::Key_S:
|
||||
_myAvatar.setDriveKeys(BACK, 0);
|
||||
_myAvatar->setDriveKeys(BACK, 0);
|
||||
break;
|
||||
|
||||
case Qt::Key_A:
|
||||
_myAvatar.setDriveKeys(ROT_LEFT, 0);
|
||||
_myAvatar->setDriveKeys(ROT_LEFT, 0);
|
||||
break;
|
||||
|
||||
case Qt::Key_D:
|
||||
_myAvatar.setDriveKeys(ROT_RIGHT, 0);
|
||||
_myAvatar->setDriveKeys(ROT_RIGHT, 0);
|
||||
break;
|
||||
|
||||
case Qt::Key_Up:
|
||||
_myAvatar.setDriveKeys(FWD, 0);
|
||||
_myAvatar.setDriveKeys(UP, 0);
|
||||
_myAvatar->setDriveKeys(FWD, 0);
|
||||
_myAvatar->setDriveKeys(UP, 0);
|
||||
break;
|
||||
|
||||
case Qt::Key_Down:
|
||||
_myAvatar.setDriveKeys(BACK, 0);
|
||||
_myAvatar.setDriveKeys(DOWN, 0);
|
||||
_myAvatar->setDriveKeys(BACK, 0);
|
||||
_myAvatar->setDriveKeys(DOWN, 0);
|
||||
break;
|
||||
|
||||
case Qt::Key_Left:
|
||||
_myAvatar.setDriveKeys(LEFT, 0);
|
||||
_myAvatar.setDriveKeys(ROT_LEFT, 0);
|
||||
_myAvatar->setDriveKeys(LEFT, 0);
|
||||
_myAvatar->setDriveKeys(ROT_LEFT, 0);
|
||||
break;
|
||||
|
||||
case Qt::Key_Right:
|
||||
_myAvatar.setDriveKeys(RIGHT, 0);
|
||||
_myAvatar.setDriveKeys(ROT_RIGHT, 0);
|
||||
_myAvatar->setDriveKeys(RIGHT, 0);
|
||||
_myAvatar->setDriveKeys(ROT_RIGHT, 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -1192,11 +1198,11 @@ void Application::mouseMoveEvent(QMouseEvent* event) {
|
|||
// orbit behavior
|
||||
if (_mousePressed && !Menu::getInstance()->isVoxelModeActionChecked()) {
|
||||
if (_avatarManager.getLookAtTargetAvatar()) {
|
||||
_myAvatar.orbit(_avatarManager.getLookAtTargetAvatar()->getPosition(), deltaX, deltaY);
|
||||
_myAvatar->orbit(_avatarManager.getLookAtTargetAvatar()->getPosition(), deltaX, deltaY);
|
||||
return;
|
||||
}
|
||||
if (_isHoverVoxel) {
|
||||
_myAvatar.orbit(getMouseVoxelWorldCoordinates(_hoverVoxel), deltaX, deltaY);
|
||||
_myAvatar->orbit(getMouseVoxelWorldCoordinates(_hoverVoxel), deltaX, deltaY);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -1279,14 +1285,14 @@ void Application::mousePressEvent(QMouseEvent* event) {
|
|||
|
||||
const float PERCENTAGE_TO_MOVE_TOWARD = 0.90f;
|
||||
glm::vec3 newTarget = getMouseVoxelWorldCoordinates(_hoverVoxel);
|
||||
glm::vec3 myPosition = _myAvatar.getPosition();
|
||||
glm::vec3 myPosition = _myAvatar->getPosition();
|
||||
|
||||
// If there is not an action tool set (add, delete, color), move to this voxel
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::ClickToFly) &&
|
||||
!(Menu::getInstance()->isOptionChecked(MenuOption::VoxelAddMode) ||
|
||||
Menu::getInstance()->isOptionChecked(MenuOption::VoxelDeleteMode) ||
|
||||
Menu::getInstance()->isOptionChecked(MenuOption::VoxelColorMode))) {
|
||||
_myAvatar.setMoveTarget(myPosition + (newTarget - myPosition) * PERCENTAGE_TO_MOVE_TOWARD);
|
||||
_myAvatar->setMoveTarget(myPosition + (newTarget - myPosition) * PERCENTAGE_TO_MOVE_TOWARD);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1438,8 +1444,8 @@ void Application::timer() {
|
|||
DataServerClient::resendUnmatchedPackets();
|
||||
|
||||
// give the MyAvatar object position, orientation to the Profile so it can propagate to the data-server
|
||||
_profile.updatePosition(_myAvatar.getPosition());
|
||||
_profile.updateOrientation(_myAvatar.getOrientation());
|
||||
_profile.updatePosition(_myAvatar->getPosition());
|
||||
_profile.updateOrientation(_myAvatar->getOrientation());
|
||||
}
|
||||
|
||||
static glm::vec3 getFaceVector(BoxFace face) {
|
||||
|
@ -1734,7 +1740,7 @@ void Application::pasteVoxels() {
|
|||
}
|
||||
|
||||
void Application::findAxisAlignment() {
|
||||
glm::vec3 direction = _myAvatar.getMouseRayDirection();
|
||||
glm::vec3 direction = _myAvatar->getMouseRayDirection();
|
||||
if (fabs(direction.z) > fabs(direction.x)) {
|
||||
_lookingAlongX = false;
|
||||
if (direction.z < 0) {
|
||||
|
@ -1820,12 +1826,10 @@ void Application::init() {
|
|||
_headMouseY = _mouseY = _glWidget->height() / 2;
|
||||
QCursor::setPos(_headMouseX, _headMouseY);
|
||||
|
||||
_myAvatar.init();
|
||||
_myAvatar.setPosition(START_LOCATION);
|
||||
// TODO: move _myAvatar out of Application. Move relevant code to MyAvataar or AvatarManager
|
||||
_avatarManager.init();
|
||||
_myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
|
||||
_myCamera.setModeShiftRate(1.0f);
|
||||
_myAvatar.setDisplayingLookatVectors(false);
|
||||
_avatarManager.setMyAvatar(&_myAvatar);
|
||||
|
||||
_mirrorCamera.setMode(CAMERA_MODE_MIRROR);
|
||||
_mirrorCamera.setAspectRatio((float)MIRROR_VIEW_WIDTH / (float)MIRROR_VIEW_HEIGHT);
|
||||
|
@ -1930,9 +1934,9 @@ const float HEAD_SPHERE_RADIUS = 0.07f;
|
|||
|
||||
bool Application::isLookingAtMyAvatar(Avatar* avatar) {
|
||||
glm::vec3 theirLookat = avatar->getHead().getLookAtPosition();
|
||||
glm::vec3 myHeadPosition = _myAvatar.getHead().getPosition();
|
||||
glm::vec3 myHeadPosition = _myAvatar->getHead().getPosition();
|
||||
|
||||
if (pointInSphere(theirLookat, myHeadPosition, HEAD_SPHERE_RADIUS * _myAvatar.getScale())) {
|
||||
if (pointInSphere(theirLookat, myHeadPosition, HEAD_SPHERE_RADIUS * _myAvatar->getScale())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1970,10 +1974,10 @@ void Application::updateMouseRay() {
|
|||
}
|
||||
|
||||
// tell my avatar if the mouse is being pressed...
|
||||
_myAvatar.setMousePressed(_mousePressed);
|
||||
_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() {
|
||||
|
@ -1986,7 +1990,7 @@ void Application::updateFaceshift() {
|
|||
|
||||
// Copy angular velocity if measured by faceshift, to the head
|
||||
if (_faceshift.isActive()) {
|
||||
_myAvatar.getHead().setAngularVelocity(_faceshift.getHeadAngularVelocity());
|
||||
_myAvatar->getHead().setAngularVelocity(_faceshift.getHeadAngularVelocity());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2010,14 +2014,14 @@ void Application::updateMyAvatarLookAtPosition(glm::vec3& lookAtSpot) {
|
|||
}
|
||||
if (_faceshift.isActive()) {
|
||||
// deflect using Faceshift gaze data
|
||||
glm::vec3 origin = _myAvatar.getHead().calculateAverageEyePosition();
|
||||
glm::vec3 origin = _myAvatar->getHead().calculateAverageEyePosition();
|
||||
float pitchSign = (_myCamera.getMode() == CAMERA_MODE_MIRROR) ? -1.0f : 1.0f;
|
||||
float deflection = Menu::getInstance()->getFaceshiftEyeDeflection();
|
||||
lookAtSpot = origin + _myCamera.getRotation() * glm::quat(glm::radians(glm::vec3(
|
||||
_faceshift.getEstimatedEyePitch() * pitchSign * deflection, _faceshift.getEstimatedEyeYaw() * deflection, 0.0f))) *
|
||||
glm::inverse(_myCamera.getRotation()) * (lookAtSpot - origin);
|
||||
}
|
||||
_myAvatar.getHead().setLookAtPosition(lookAtSpot);
|
||||
_myAvatar->getHead().setLookAtPosition(lookAtSpot);
|
||||
}
|
||||
|
||||
void Application::updateHoverVoxels(float deltaTime, float& distance, BoxFace& face) {
|
||||
|
@ -2075,9 +2079,9 @@ void Application::updateMouseVoxels(float deltaTime, float& distance, BoxFace& f
|
|||
_mouseVoxel.s = 0.0f;
|
||||
bool wasInitialized = _mouseVoxelScaleInitialized;
|
||||
if (Menu::getInstance()->isVoxelModeActionChecked() &&
|
||||
(fabs(_myAvatar.getVelocity().x) +
|
||||
fabs(_myAvatar.getVelocity().y) +
|
||||
fabs(_myAvatar.getVelocity().z)) / 3 < MAX_AVATAR_EDIT_VELOCITY) {
|
||||
(fabs(_myAvatar->getVelocity().x) +
|
||||
fabs(_myAvatar->getVelocity().y) +
|
||||
fabs(_myAvatar->getVelocity().z)) / 3 < MAX_AVATAR_EDIT_VELOCITY) {
|
||||
|
||||
if (_voxels.findRayIntersection(_mouseRayOrigin, _mouseRayDirection, _mouseVoxel, distance, face)) {
|
||||
if (distance < MAX_VOXEL_EDIT_DISTANCE) {
|
||||
|
@ -2209,16 +2213,16 @@ void Application::updateMyAvatarSimulation(float deltaTime) {
|
|||
PerformanceWarning warn(showWarnings, "Application::updateMyAvatarSimulation()");
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Gravity)) {
|
||||
_myAvatar.setGravity(_environment.getGravity(_myAvatar.getPosition()));
|
||||
_myAvatar->setGravity(_environment.getGravity(_myAvatar->getPosition()));
|
||||
}
|
||||
else {
|
||||
_myAvatar.setGravity(glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
_myAvatar->setGravity(glm::vec3(0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::TransmitterDrive) && _myTransmitter.isConnected()) {
|
||||
_myAvatar.simulate(deltaTime, &_myTransmitter);
|
||||
_myAvatar->simulate(deltaTime, &_myTransmitter);
|
||||
} else {
|
||||
_myAvatar.simulate(deltaTime, NULL);
|
||||
_myAvatar->simulate(deltaTime, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2246,8 +2250,8 @@ void Application::updateTransmitter(float deltaTime) {
|
|||
|
||||
// no transmitter drive implies transmitter pick
|
||||
if (!Menu::getInstance()->isOptionChecked(MenuOption::TransmitterDrive) && _myTransmitter.isConnected()) {
|
||||
_transmitterPickStart = _myAvatar.getChestPosition();
|
||||
glm::vec3 direction = _myAvatar.getOrientation() *
|
||||
_transmitterPickStart = _myAvatar->getChestPosition();
|
||||
glm::vec3 direction = _myAvatar->getOrientation() *
|
||||
glm::quat(glm::radians(_myTransmitter.getEstimatedRotation())) * IDENTITY_FRONT;
|
||||
|
||||
// check against voxels, avatars
|
||||
|
@ -2321,8 +2325,8 @@ void Application::updateAudio(float deltaTime) {
|
|||
PerformanceWarning warn(showWarnings, "Application::updateAudio()");
|
||||
|
||||
// Update audio stats for procedural sounds
|
||||
_audio.setLastAcceleration(_myAvatar.getThrust());
|
||||
_audio.setLastVelocity(_myAvatar.getVelocity());
|
||||
_audio.setLastAcceleration(_myAvatar->getThrust());
|
||||
_audio.setLastVelocity(_myAvatar->getVelocity());
|
||||
}
|
||||
|
||||
void Application::updateCursor(float deltaTime) {
|
||||
|
@ -2394,16 +2398,16 @@ void Application::updateAvatar(float deltaTime) {
|
|||
PerformanceWarning warn(showWarnings, "Application::updateAvatar()");
|
||||
|
||||
// rotate body yaw for yaw received from multitouch
|
||||
_myAvatar.setOrientation(_myAvatar.getOrientation()
|
||||
_myAvatar->setOrientation(_myAvatar->getOrientation()
|
||||
* glm::quat(glm::vec3(0, _yawFromTouch, 0)));
|
||||
_yawFromTouch = 0.f;
|
||||
|
||||
// apply pitch from touch
|
||||
_myAvatar.getHead().setPitch(_myAvatar.getHead().getPitch() + _pitchFromTouch);
|
||||
_myAvatar->getHead().setPitch(_myAvatar->getHead().getPitch() + _pitchFromTouch);
|
||||
_pitchFromTouch = 0.0f;
|
||||
|
||||
// Update my avatar's state from gyros
|
||||
_myAvatar.updateFromGyros(Menu::getInstance()->isOptionChecked(MenuOption::TurnWithHead));
|
||||
_myAvatar->updateFromGyros(Menu::getInstance()->isOptionChecked(MenuOption::TurnWithHead));
|
||||
|
||||
// Update head mouse from faceshift if active
|
||||
if (_faceshift.isActive()) {
|
||||
|
@ -2424,17 +2428,17 @@ void Application::updateAvatar(float deltaTime) {
|
|||
float yaw, pitch, roll;
|
||||
OculusManager::getEulerAngles(yaw, pitch, roll);
|
||||
|
||||
_myAvatar.getHead().setYaw(yaw);
|
||||
_myAvatar.getHead().setPitch(pitch);
|
||||
_myAvatar.getHead().setRoll(roll);
|
||||
_myAvatar->getHead().setYaw(yaw);
|
||||
_myAvatar->getHead().setPitch(pitch);
|
||||
_myAvatar->getHead().setRoll(roll);
|
||||
}
|
||||
|
||||
// Get audio loudness data from audio input device
|
||||
_myAvatar.getHead().setAudioLoudness(_audio.getLastInputLoudness());
|
||||
_myAvatar->getHead().setAudioLoudness(_audio.getLastInputLoudness());
|
||||
|
||||
// send head/hand data to the avatar mixer and voxel server
|
||||
QByteArray avatarData = byteArrayWithPopluatedHeader(PacketTypeAvatarData);
|
||||
avatarData.append(_myAvatar.toByteArray());
|
||||
avatarData.append(_myAvatar->toByteArray());
|
||||
|
||||
controlledBroadcastToNodes(avatarData, NodeSet() << NodeType::AvatarMixer);
|
||||
|
||||
|
@ -3319,7 +3323,7 @@ void Application::displayStats() {
|
|||
horizontalOffset += 171;
|
||||
}
|
||||
|
||||
glm::vec3 avatarPos = _myAvatar.getPosition();
|
||||
glm::vec3 avatarPos = _myAvatar->getPosition();
|
||||
|
||||
lines = _statsExpanded ? 4 : 3;
|
||||
displayStatsBackground(backgroundColor, horizontalOffset, 0, _glWidget->width() - (mirrorEnabled ? 301 : 411) - horizontalOffset, lines * STATS_PELS_PER_LINE + 10);
|
||||
|
@ -3334,9 +3338,9 @@ void Application::displayStats() {
|
|||
sprintf(avatarPosition, "Position: %.3f, %.3f, %.3f", avatarPos.x, avatarPos.y, avatarPos.z);
|
||||
}
|
||||
char avatarVelocity[30];
|
||||
sprintf(avatarVelocity, "Velocity: %.1f", glm::length(_myAvatar.getVelocity()));
|
||||
sprintf(avatarVelocity, "Velocity: %.1f", glm::length(_myAvatar->getVelocity()));
|
||||
char avatarBodyYaw[30];
|
||||
sprintf(avatarBodyYaw, "Yaw: %.2f", _myAvatar.getBodyYaw());
|
||||
sprintf(avatarBodyYaw, "Yaw: %.2f", _myAvatar->getBodyYaw());
|
||||
char avatarMixerStats[200];
|
||||
|
||||
verticalOffset += STATS_PELS_PER_LINE;
|
||||
|
@ -3957,10 +3961,10 @@ void Application::resetSensors() {
|
|||
}
|
||||
|
||||
QCursor::setPos(_headMouseX, _headMouseY);
|
||||
_myAvatar.reset();
|
||||
_myAvatar->reset();
|
||||
_myTransmitter.resetLevels();
|
||||
_myAvatar.setVelocity(glm::vec3(0,0,0));
|
||||
_myAvatar.setThrust(glm::vec3(0,0,0));
|
||||
_myAvatar->setVelocity(glm::vec3(0,0,0));
|
||||
_myAvatar->setThrust(glm::vec3(0,0,0));
|
||||
|
||||
QMetaObject::invokeMethod(&_audio, "reset", Qt::QueuedConnection);
|
||||
}
|
||||
|
@ -4089,7 +4093,7 @@ void Application::nodeKilled(SharedNodePointer node) {
|
|||
|
||||
} else if (node->getType() == NodeType::AvatarMixer) {
|
||||
// our avatar mixer has gone away - clear the hash of avatars
|
||||
_avatarManager.clearHash();
|
||||
_avatarManager.clearMixedAvatars();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4204,7 +4208,7 @@ void Application::removeScriptName(const QString& fileNameString)
|
|||
_activeScripts.removeOne(fileNameString);
|
||||
}
|
||||
|
||||
void Application::loadScript(const QString& fileNameString){
|
||||
void Application::loadScript(const QString& fileNameString) {
|
||||
_activeScripts.append(fileNameString);
|
||||
QByteArray fileNameAscii = fileNameString.toLocal8Bit();
|
||||
const char* fileName = fileNameAscii.data();
|
||||
|
@ -4242,7 +4246,7 @@ void Application::loadScript(const QString& fileNameString){
|
|||
scriptEngine->getParticlesScriptingInterface()->setParticleTree(_particles.getTree());
|
||||
|
||||
// hook our avatar object into this script engine
|
||||
scriptEngine->setAvatarData(&_myAvatar, "MyAvatar");
|
||||
scriptEngine->setAvatarData( static_cast<Avatar*>(_myAvatar), "MyAvatar");
|
||||
|
||||
QThread* workerThread = new QThread(this);
|
||||
|
||||
|
@ -4409,6 +4413,6 @@ void Application::takeSnapshot() {
|
|||
player->setMedia(QUrl::fromLocalFile(inf.absoluteFilePath()));
|
||||
player->play();
|
||||
|
||||
Snapshot::saveSnapshot(_glWidget, _profile.getUsername(), _myAvatar.getPosition());
|
||||
Snapshot::saveSnapshot(_glWidget, _profile.getUsername(), _myAvatar->getPosition());
|
||||
}
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ public:
|
|||
glm::vec3 getMouseVoxelWorldCoordinates(const VoxelDetail& mouseVoxel);
|
||||
|
||||
QGLWidget* getGLWidget() { return _glWidget; }
|
||||
MyAvatar* getAvatar() { return &_myAvatar; }
|
||||
MyAvatar* getAvatar() { return _myAvatar; }
|
||||
Audio* getAudio() { return &_audio; }
|
||||
Camera* getCamera() { return &_myCamera; }
|
||||
ViewFrustum* getViewFrustum() { return &_viewFrustum; }
|
||||
|
@ -374,10 +374,10 @@ private:
|
|||
VoxelQuery _voxelQuery; // NodeData derived class for querying voxels from voxel server
|
||||
|
||||
AvatarManager _avatarManager;
|
||||
MyAvatar _myAvatar; // The rendered avatar of oneself
|
||||
Profile _profile; // The data-server linked profile for this user
|
||||
MyAvatar* _myAvatar; // TODO: move this and relevant code to AvatarManager (or MyAvatar as the case may be)
|
||||
Profile _profile; // The data-server linked profile for this user
|
||||
|
||||
Transmitter _myTransmitter; // Gets UDP data from transmitter app used to animate the avatar
|
||||
Transmitter _myTransmitter; // Gets UDP data from transmitter app used to animate the avatar
|
||||
|
||||
Faceshift _faceshift;
|
||||
|
||||
|
|
|
@ -23,21 +23,24 @@ AvatarManager::AvatarManager(QObject* parent) :
|
|||
_lookAtTargetAvatar(),
|
||||
_lookAtOtherPosition(),
|
||||
_lookAtIndicatorScale(1.0f),
|
||||
_avatarFades(),
|
||||
_myAvatar(NULL)
|
||||
{
|
||||
_avatarFades() {
|
||||
// register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar
|
||||
qRegisterMetaType<QWeakPointer<Node> >("NodeWeakPointer");
|
||||
_myAvatar = QSharedPointer<MyAvatar>(new MyAvatar());
|
||||
}
|
||||
|
||||
void AvatarManager::setMyAvatar(MyAvatar* myAvatar) {
|
||||
if (!_myAvatar) {
|
||||
// can only ever set this once
|
||||
_myAvatar = myAvatar;
|
||||
// add _myAvatar to the list
|
||||
AvatarSharedPointer myPointer = AvatarSharedPointer(_myAvatar);
|
||||
_avatarHash.insert(MY_AVATAR_KEY, myPointer);
|
||||
}
|
||||
void AvatarManager::clear() {
|
||||
_lookAtTargetAvatar.clear();
|
||||
_avatarFades.clear();
|
||||
_avatarHash.clear();
|
||||
_myAvatar.clear();
|
||||
}
|
||||
|
||||
void AvatarManager::init() {
|
||||
_myAvatar->init();
|
||||
_myAvatar->setPosition(START_LOCATION);
|
||||
_myAvatar->setDisplayingLookatVectors(false);
|
||||
_avatarHash.insert(MY_AVATAR_KEY, _myAvatar);
|
||||
}
|
||||
|
||||
void AvatarManager::updateLookAtTargetAvatar(glm::vec3 &eyePosition) {
|
||||
|
@ -52,7 +55,7 @@ void AvatarManager::updateLookAtTargetAvatar(glm::vec3 &eyePosition) {
|
|||
|
||||
foreach (const AvatarSharedPointer& avatarPointer, _avatarHash) {
|
||||
Avatar* avatar = static_cast<Avatar*>(avatarPointer.data());
|
||||
if (avatar != static_cast<Avatar*>(_myAvatar)) {
|
||||
if (avatar != static_cast<Avatar*>(_myAvatar.data())) {
|
||||
float distance;
|
||||
if (avatar->findRayIntersection(mouseOrigin, mouseDirection, distance)) {
|
||||
// rescale to compensate for head embiggening
|
||||
|
@ -86,7 +89,7 @@ void AvatarManager::updateAvatars(float deltaTime) {
|
|||
AvatarHash::iterator avatarIterator = _avatarHash.begin();
|
||||
while (avatarIterator != _avatarHash.end()) {
|
||||
Avatar* avatar = static_cast<Avatar*>(avatarIterator.value().data());
|
||||
if (avatar == static_cast<Avatar*>(_myAvatar)) {
|
||||
if (avatar == static_cast<Avatar*>(_myAvatar.data())) {
|
||||
// for now skip updates to _myAvatar because it is done explicitly in Application
|
||||
// TODO: update _myAvatar in this context
|
||||
++avatarIterator;
|
||||
|
@ -122,7 +125,7 @@ void AvatarManager::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) {
|
|||
if (!avatar->isInitialized()) {
|
||||
avatar->init();
|
||||
}
|
||||
if (avatar == static_cast<Avatar*>(_myAvatar)) {
|
||||
if (avatar == static_cast<Avatar*>(_myAvatar.data())) {
|
||||
avatar->render(forceRenderHead);
|
||||
} else {
|
||||
avatar->render(false);
|
||||
|
@ -130,8 +133,8 @@ void AvatarManager::renderAvatars(bool forceRenderHead, bool selfAvatarOnly) {
|
|||
avatar->setDisplayingLookatVectors(renderLookAtVectors);
|
||||
}
|
||||
renderAvatarFades();
|
||||
} else if (_myAvatar) {
|
||||
// Render my own Avatar
|
||||
} else {
|
||||
// just render myAvatar
|
||||
_myAvatar->render(forceRenderHead);
|
||||
_myAvatar->setDisplayingLookatVectors(renderLookAtVectors);
|
||||
}
|
||||
|
@ -261,10 +264,11 @@ AvatarHash::iterator AvatarManager::erase(const AvatarHash::iterator& iterator)
|
|||
}
|
||||
}
|
||||
|
||||
void AvatarManager::clearHash() {
|
||||
// clear the AvatarManager hash - typically happens on the removal of the avatar-mixer
|
||||
void AvatarManager::clearMixedAvatars() {
|
||||
// clear any avatars that came from an avatar-mixer
|
||||
AvatarHash::iterator removeAvatar = _avatarHash.begin();
|
||||
while (removeAvatar != _avatarHash.end()) {
|
||||
removeAvatar = erase(removeAvatar);
|
||||
}
|
||||
_lookAtTargetAvatar.clear();
|
||||
}
|
||||
|
|
|
@ -25,7 +25,11 @@ class AvatarManager : public QObject, public DataServerCallbackObject, public Av
|
|||
public:
|
||||
AvatarManager(QObject* parent = 0);
|
||||
|
||||
void setMyAvatar(MyAvatar* myAvatar);
|
||||
void clear();
|
||||
|
||||
void init();
|
||||
|
||||
MyAvatar* getMyAvatar() { return _myAvatar.data(); }
|
||||
|
||||
AvatarData* getLookAtTargetAvatar() const { return _lookAtTargetAvatar.data(); }
|
||||
|
||||
|
@ -34,8 +38,7 @@ public:
|
|||
void updateAvatars(float deltaTime);
|
||||
void renderAvatars(bool forceRenderHead, bool selfAvatarOnly = false);
|
||||
|
||||
// virtual override
|
||||
void clearHash();
|
||||
void clearMixedAvatars();
|
||||
|
||||
public slots:
|
||||
void processDataServerResponse(const QString& userString, const QStringList& keyList, const QStringList& valueList);
|
||||
|
@ -57,7 +60,7 @@ private:
|
|||
float _lookAtIndicatorScale;
|
||||
|
||||
QVector<AvatarSharedPointer> _avatarFades;
|
||||
MyAvatar* _myAvatar;
|
||||
QSharedPointer<MyAvatar> _myAvatar;
|
||||
};
|
||||
|
||||
#endif /* defined(__hifi__AvatarManager__) */
|
||||
|
|
|
@ -17,13 +17,6 @@ void AvatarHashMap::insert(const QUuid& id, AvatarSharedPointer avatar) {
|
|||
_avatarHash.insert(id, avatar);
|
||||
}
|
||||
|
||||
void AvatarHashMap::clearHash() {
|
||||
AvatarHash::iterator removeAvatar = _avatarHash.begin();
|
||||
while (removeAvatar != _avatarHash.end()) {
|
||||
removeAvatar = erase(removeAvatar);
|
||||
}
|
||||
}
|
||||
|
||||
AvatarHash::iterator AvatarHashMap::erase(const AvatarHash::iterator& iterator) {
|
||||
return _avatarHash.erase(iterator);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ public:
|
|||
int size() const { return _avatarHash.size(); }
|
||||
|
||||
virtual void insert(const QUuid& id, AvatarSharedPointer avatar);
|
||||
virtual void clearHash();
|
||||
|
||||
protected:
|
||||
virtual AvatarHash::iterator erase(const AvatarHash::iterator& iterator);
|
||||
|
|
Loading…
Reference in a new issue