mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-05 00:46:47 +02:00
Merging from master
This commit is contained in:
commit
d066271e4e
8 changed files with 80 additions and 85 deletions
|
@ -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) {
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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(),
|
||||
|
|
Loading…
Reference in a new issue