Merging from master

This commit is contained in:
Brad Davis 2015-03-17 18:28:58 -07:00
commit d066271e4e
8 changed files with 80 additions and 85 deletions

View file

@ -2133,10 +2133,12 @@ void Application::updateCursor(float deltaTime) {
}
void Application::updateCursorVisibility() {
if (!_cursorVisible || Menu::getInstance()->isOptionChecked(MenuOption::EnableVRMode)) {
_glWidget->setCursor(Qt::BlankCursor);
if (!_cursorVisible ||
Menu::getInstance()->isOptionChecked(MenuOption::EnableVRMode) ||
Menu::getInstance()->isOptionChecked(MenuOption::Enable3DTVMode)) {
_window->setCursor(Qt::BlankCursor);
} else {
_glWidget->unsetCursor();
_window->unsetCursor();
}
}
@ -2789,7 +2791,27 @@ QImage Application::renderAvatarBillboard() {
return image;
}
// FIXME, preprocessor guard this check to occur only in DEBUG builds
static QThread * activeRenderingThread = nullptr;
ViewFrustum* Application::getViewFrustum() {
if (QThread::currentThread() == activeRenderingThread) {
// FIXME, should this be an assert?
qWarning() << "Calling Application::getViewFrustum() from the active rendering thread, did you mean Application::getDisplayViewFrustum()?";
}
return &_viewFrustum;
}
ViewFrustum* Application::getDisplayViewFrustum() {
if (QThread::currentThread() != activeRenderingThread) {
// FIXME, should this be an assert?
qWarning() << "Calling Application::getDisplayViewFrustum() from outside the active rendering thread or outside rendering, did you mean Application::getViewFrustum()?";
}
return &_displayViewFrustum;
}
void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs::RenderSide renderSide) {
activeRenderingThread = QThread::currentThread();
PROFILE_RANGE(__FUNCTION__);
PerformanceTimer perfTimer("display");
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()");
@ -3014,6 +3036,7 @@ void Application::displaySide(Camera& theCamera, bool selfAvatarOnly, RenderArgs
glClear(GL_DEPTH_BUFFER_BIT);
_overlays.renderWorld(true);
}
activeRenderingThread = nullptr;
}
void Application::updateUntranslatedViewMatrix(const glm::vec3& viewMatrixTranslation) {
@ -3106,17 +3129,25 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) {
_myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_BODY_DISTANCE * _myAvatar->getScale());
} else { // HEAD zoom level
_mirrorCamera.setFieldOfView(MIRROR_FIELD_OF_VIEW); // degrees
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.setPosition(_myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale());
// FIXME note that the positioing of the camera relative to the avatar can suffer limited
// precision as the user's position moves further away from the origin. Thus at
// /1e7,1e7,1e7 (well outside the buildable volume) the mirror camera veers and sways
// wildly as you rotate your avatar because the floating point values are becoming
// larger, squeezing out the available digits of precision you have available at the
// human scale for camera positioning.
} else {
_mirrorCamera.setPosition(_myAvatar->getHead()->getEyePosition() +
_myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale());
}
// Previously there was a hack to correct this using the mechanism of repositioning
// the avatar at the origin of the world for the purposes of rendering the mirror,
// but it resulted in failing to render the avatar's head model in the mirror view
// when in first person mode. Presumably this was because of some missed culling logic
// that was not accounted for in the hack.
// This was removed in commit 71e59cfa88c6563749594e25494102fe01db38e9 but could be further
// investigated in order to adapt the technique while fixing the head rendering issue,
// but the complexity of the hack suggests that a better approach
_mirrorCamera.setFieldOfView(MIRROR_FIELD_OF_VIEW); // degrees
_mirrorCamera.setPosition(_myAvatar->getHead()->getEyePosition() +
_myAvatar->getOrientation() * glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_REARVIEW_DISTANCE * _myAvatar->getScale());
}
_mirrorCamera.setAspectRatio((float)region.width() / region.height());
@ -3143,58 +3174,7 @@ void Application::renderRearViewMirror(const QRect& region, bool billboard) {
// render rear mirror view
glPushMatrix();
if (eyeRelativeCamera) {
// save absolute translations
glm::vec3 absoluteSkeletonTranslation = _myAvatar->getSkeletonModel().getTranslation();
glm::vec3 absoluteFaceTranslation = _myAvatar->getHead()->getFaceModel().getTranslation();
// get the neck position so we can translate the face relative to it
glm::vec3 neckPosition;
_myAvatar->getSkeletonModel().setTranslation(glm::vec3());
_myAvatar->getSkeletonModel().getNeckPosition(neckPosition);
// get the eye position relative to the body
glm::vec3 eyePosition = _myAvatar->getHead()->getEyePosition();
float eyeHeight = eyePosition.y - _myAvatar->getPosition().y;
// set the translation of the face relative to the neck position
_myAvatar->getHead()->getFaceModel().setTranslation(neckPosition - glm::vec3(0, eyeHeight, 0));
// translate the neck relative to the face
_myAvatar->getSkeletonModel().setTranslation(_myAvatar->getHead()->getFaceModel().getTranslation() -
neckPosition);
// update the attachments to match
QVector<glm::vec3> absoluteAttachmentTranslations;
glm::vec3 delta = _myAvatar->getSkeletonModel().getTranslation() - absoluteSkeletonTranslation;
foreach (Model* attachment, _myAvatar->getAttachmentModels()) {
absoluteAttachmentTranslations.append(attachment->getTranslation());
attachment->setTranslation(attachment->getTranslation() + delta);
}
// and lo, even the shadow matrices
glm::mat4 savedShadowMatrices[CASCADED_SHADOW_MATRIX_COUNT];
for (int i = 0; i < CASCADED_SHADOW_MATRIX_COUNT; i++) {
savedShadowMatrices[i] = _shadowMatrices[i];
_shadowMatrices[i] = glm::transpose(glm::transpose(_shadowMatrices[i]) * glm::translate(-delta));
}
displaySide(_mirrorCamera, true);
// restore absolute translations
_myAvatar->getSkeletonModel().setTranslation(absoluteSkeletonTranslation);
_myAvatar->getHead()->getFaceModel().setTranslation(absoluteFaceTranslation);
for (int i = 0; i < absoluteAttachmentTranslations.size(); i++) {
_myAvatar->getAttachmentModels().at(i)->setTranslation(absoluteAttachmentTranslations.at(i));
}
// restore the shadow matrices
for (int i = 0; i < CASCADED_SHADOW_MATRIX_COUNT; i++) {
_shadowMatrices[i] = savedShadowMatrices[i];
}
} else {
displaySide(_mirrorCamera, true);
}
displaySide(_mirrorCamera, true);
glPopMatrix();
if (!billboard) {

View file

@ -174,8 +174,12 @@ public:
bool isThrottleRendering() const { return _glWidget->isThrottleRendering(); }
Camera* getCamera() { return &_myCamera; }
ViewFrustum* getViewFrustum() { return &_viewFrustum; }
ViewFrustum* getDisplayViewFrustum() { return &_displayViewFrustum; }
// Represents the current view frustum of the avatar.
ViewFrustum* getViewFrustum();
// Represents the view frustum of the current rendering pass,
// which might be different from the viewFrustum, i.e. shadowmap
// passes, mirror window passes, etc
ViewFrustum* getDisplayViewFrustum();
ViewFrustum* getShadowViewFrustum() { return &_shadowViewFrustum; }
const OctreePacketProcessor& getOctreePacketProcessor() const { return _octreeProcessor; }
EntityTreeRenderer* getEntities() { return &_entities; }

View file

@ -338,7 +338,7 @@ void Avatar::render(const glm::vec3& cameraPosition, RenderMode renderMode, bool
// simple frustum check
float boundingRadius = getBillboardSize();
ViewFrustum* frustum = (renderMode == Avatar::SHADOW_RENDER_MODE) ?
Application::getInstance()->getShadowViewFrustum() : Application::getInstance()->getViewFrustum();
Application::getInstance()->getShadowViewFrustum() : Application::getInstance()->getDisplayViewFrustum();
if (frustum->sphereInFrustum(getPosition(), boundingRadius) == ViewFrustum::OUTSIDE) {
return;
}

View file

@ -122,7 +122,7 @@ void Overlays::renderWorld(bool drawFront, RenderArgs::RenderMode renderMode, Re
float myAvatarScale = 1.0f;
auto lodManager = DependencyManager::get<LODManager>();
RenderArgs args = { NULL, Application::getInstance()->getViewFrustum(),
RenderArgs args = { NULL, Application::getInstance()->getDisplayViewFrustum(),
lodManager->getOctreeSizeScale(),
lodManager->getBoundaryLevelAdjust(),
renderMode, renderSide,

View file

@ -236,21 +236,28 @@ void EntityTree::setSimulation(EntitySimulation* simulation) {
_simulation = simulation;
}
void EntityTree::deleteEntity(const EntityItemID& entityID, bool force) {
void EntityTree::deleteEntity(const EntityItemID& entityID, bool force, bool ignoreWarnings) {
EntityTreeElement* containingElement = getContainingElement(entityID);
if (!containingElement) {
qDebug() << "UNEXPECTED!!!! EntityTree::deleteEntity() entityID doesn't exist!!! entityID=" << entityID;
if (!ignoreWarnings) {
qDebug() << "UNEXPECTED!!!! EntityTree::deleteEntity() entityID doesn't exist!!! entityID=" << entityID;
}
return;
}
EntityItem* existingEntity = containingElement->getEntityWithEntityItemID(entityID);
if (!existingEntity) {
qDebug() << "UNEXPECTED!!!! don't call EntityTree::deleteEntity() on entity items that don't exist. entityID=" << entityID;
if (!ignoreWarnings) {
qDebug() << "UNEXPECTED!!!! don't call EntityTree::deleteEntity() on entity items that don't exist. "
"entityID=" << entityID;
}
return;
}
if (existingEntity->getLocked() && !force) {
qDebug() << "ERROR! EntityTree::deleteEntity() trying to delete locked entity. entityID=" << entityID;
if (!ignoreWarnings) {
qDebug() << "ERROR! EntityTree::deleteEntity() trying to delete locked entity. entityID=" << entityID;
}
return;
}
@ -263,24 +270,31 @@ void EntityTree::deleteEntity(const EntityItemID& entityID, bool force) {
_isDirty = true;
}
void EntityTree::deleteEntities(QSet<EntityItemID> entityIDs, bool force) {
void EntityTree::deleteEntities(QSet<EntityItemID> entityIDs, bool force, bool ignoreWarnings) {
// NOTE: callers must lock the tree before using this method
DeleteEntityOperator theOperator(this);
foreach(const EntityItemID& entityID, entityIDs) {
EntityTreeElement* containingElement = getContainingElement(entityID);
if (!containingElement) {
qDebug() << "UNEXPECTED!!!! EntityTree::deleteEntities() entityID doesn't exist!!! entityID=" << entityID;
if (!ignoreWarnings) {
qDebug() << "UNEXPECTED!!!! EntityTree::deleteEntities() entityID doesn't exist!!! entityID=" << entityID;
}
continue;
}
EntityItem* existingEntity = containingElement->getEntityWithEntityItemID(entityID);
if (!existingEntity) {
qDebug() << "UNEXPECTED!!!! don't call EntityTree::deleteEntities() on entity items that don't exist. entityID=" << entityID;
if (!ignoreWarnings) {
qDebug() << "UNEXPECTED!!!! don't call EntityTree::deleteEntities() on entity items that don't exist. "
"entityID=" << entityID;
}
continue;
}
if (existingEntity->getLocked() && !force) {
qDebug() << "ERROR! EntityTree::deleteEntities() trying to delete locked entity. entityID=" << entityID;
if (!ignoreWarnings) {
qDebug() << "ERROR! EntityTree::deleteEntities() trying to delete locked entity. entityID=" << entityID;
}
continue;
}
@ -878,10 +892,9 @@ int EntityTree::processEraseMessage(const QByteArray& dataByteArray, const Share
EntityItemID entityItemID(entityID);
entityItemIDsToDelete << entityItemID;
}
deleteEntities(entityItemIDsToDelete);
deleteEntities(entityItemIDsToDelete, true, true);
}
unlock();
return processedBytes;
}
@ -918,7 +931,7 @@ int EntityTree::processEraseMessageDetails(const QByteArray& dataByteArray, cons
EntityItemID entityItemID(entityID);
entityItemIDsToDelete << entityItemID;
}
deleteEntities(entityItemIDsToDelete);
deleteEntities(entityItemIDsToDelete, true, true);
}
return processedBytes;
}

View file

@ -92,8 +92,8 @@ public:
// use this method if you have a pointer to the entity (avoid an extra entity lookup)
bool updateEntity(EntityItem* entity, const EntityItemProperties& properties, bool allowLockChange);
void deleteEntity(const EntityItemID& entityID, bool force = false);
void deleteEntities(QSet<EntityItemID> entityIDs, bool force = false);
void deleteEntity(const EntityItemID& entityID, bool force = false, bool ignoreWarnings = false);
void deleteEntities(QSet<EntityItemID> entityIDs, bool force = false, bool ignoreWarnings = false);
void removeEntityFromSimulation(EntityItem* entity);
/// \param position point of query in world-frame (meters)

View file

@ -28,7 +28,6 @@ elseif (WIN32)
target_link_libraries(${TARGET_NAME} "${NSIGHT_LIBRARIES}")
endif ()
endif()
elseif (ANDROID)
target_link_libraries(${TARGET_NAME} "-lGLESv3" "-lEGL")
else ()

View file

@ -27,8 +27,7 @@
const QString ADDRESS_MANAGER_SETTINGS_GROUP = "AddressManager";
const QString SETTINGS_CURRENT_ADDRESS_KEY = "address";
Setting::Handle<QUrl> currentAddressHandle(QStringList() << ADDRESS_MANAGER_SETTINGS_GROUP << "address");
Setting::Handle<QUrl> currentAddressHandle(QStringList() << ADDRESS_MANAGER_SETTINGS_GROUP << "address", DEFAULT_HIFI_ADDRESS);
AddressManager::AddressManager() :
_rootPlaceName(),