wip portals

This commit is contained in:
HifiExperiments 2023-11-13 00:13:35 -08:00
parent 10de1288c2
commit 97c4184db1
4 changed files with 40 additions and 25 deletions

View file

@ -193,7 +193,7 @@ ItemKey EntityRenderer::getKey() {
builder.withSubMetaCulled(); builder.withSubMetaCulled();
} }
if (_mirrorMode != MirrorMode::NONE) { if (_mirrorMode == MirrorMode::MIRROR || (_mirrorMode == MirrorMode::PORTAL && !_portalExitID.isNull())) {
builder.withMirror(); builder.withMirror();
} }
@ -227,32 +227,50 @@ bool EntityRenderer::passesZoneOcclusionTest(const std::unordered_set<QUuid>& co
} }
void EntityRenderer::computeMirrorView(ViewFrustum& viewFrustum) const { void EntityRenderer::computeMirrorView(ViewFrustum& viewFrustum) const {
glm::vec3 mirrorPropertiesPosition; glm::vec3 inPropertiesPosition;
glm::quat mirrorPropertiesRotation; glm::quat inPropertiesRotation;
MirrorMode mirrorMode;
QUuid portalExitID;
withReadLock([&]{ withReadLock([&]{
mirrorPropertiesPosition = _entity->getWorldPosition(); inPropertiesPosition = _entity->getWorldPosition();
mirrorPropertiesRotation = _entity->getWorldOrientation(); inPropertiesRotation = _entity->getWorldOrientation();
mirrorMode = _mirrorMode;
portalExitID = _portalExitID;
}); });
glm::mat4 worldFromMirrorRotation = glm::mat4_cast(mirrorPropertiesRotation); glm::mat4 inToWorld = glm::translate(inPropertiesPosition) * glm::mat4_cast(inPropertiesRotation);
glm::mat4 worldFromMirrorTranslation = glm::translate(mirrorPropertiesPosition); glm::mat4 worldToIn = glm::inverse(inToWorld);
glm::mat4 worldFromMirror = worldFromMirrorTranslation * worldFromMirrorRotation;
glm::mat4 mirrorFromWorld = glm::inverse(worldFromMirror); glm::vec3 outPropertiesPosition = inPropertiesPosition;
glm::quat outPropertiesRotation = inPropertiesRotation;
glm::mat4 outToWorld = inToWorld;
if (mirrorMode == MirrorMode::PORTAL && !portalExitID.isNull()) {
auto renderer = DependencyManager::get<EntityTreeRenderer>();
if (renderer) {
if (auto renderable = renderer->renderableForEntityId(portalExitID)) {
renderable->withReadLock([&] {
outPropertiesPosition = renderable->_entity->getWorldPosition();
outPropertiesRotation = renderable->_entity->getWorldOrientation();
});
outToWorld = glm::translate(outPropertiesPosition) * glm::mat4_cast(outPropertiesRotation);
}
}
}
// get mirror camera position by reflecting main camera position's z coordinate in mirror space // get mirror camera position by reflecting main camera position's z coordinate in mirror space
glm::vec3 mainCameraPositionWorld = viewFrustum.getPosition(); glm::vec3 cameraPositionWorld = viewFrustum.getPosition();
glm::vec3 mainCameraPositionMirror = vec3(mirrorFromWorld * vec4(mainCameraPositionWorld, 1.0f)); glm::vec3 cameraPositionIn = vec3(worldToIn * vec4(cameraPositionWorld, 1.0f));
glm::vec3 mirrorCameraPositionMirror = vec3(mainCameraPositionMirror.x, mainCameraPositionMirror.y, glm::vec3 mirrorCameraPositionIn = vec3(cameraPositionIn.x, cameraPositionIn.y, -cameraPositionIn.z);
-mainCameraPositionMirror.z); glm::vec3 mirrorCameraPositionWorld = vec3(outToWorld * vec4(mirrorCameraPositionIn, 1.0f));
glm::vec3 mirrorCameraPositionWorld = vec3(worldFromMirror * vec4(mirrorCameraPositionMirror, 1.0f));
// get mirror camera rotation by reflecting main camera rotation in mirror space // get mirror camera rotation by reflecting main camera rotation in mirror space
// TODO: we are assuming here that UP is world y-axis // TODO: we are assuming here that UP is world y-axis
glm::quat mainCameraRotationWorld = viewFrustum.getOrientation(); glm::quat mainCameraRotationWorld = viewFrustum.getOrientation();
glm::quat mainCameraRotationMirror = mirrorFromWorld * glm::mat4_cast(mainCameraRotationWorld); glm::quat mainCameraRotationMirror = worldToIn * glm::mat4_cast(mainCameraRotationWorld);
glm::quat mirrorCameraRotationMirror = glm::quat(mainCameraRotationMirror.w, -mainCameraRotationMirror.x, -mainCameraRotationMirror.y, mainCameraRotationMirror.z) * glm::quat mirrorCameraRotationMirror = glm::quat(mainCameraRotationMirror.w, -mainCameraRotationMirror.x, -mainCameraRotationMirror.y, mainCameraRotationMirror.z) *
glm::angleAxis((float)M_PI, glm::vec3(0, 1, 0)); glm::angleAxis((float)M_PI, glm::vec3(0, 1, 0));
glm::quat mirrorCameraRotationWorld = worldFromMirror * glm::mat4_cast(mirrorCameraRotationMirror); glm::quat mirrorCameraRotationWorld = outToWorld * glm::mat4_cast(mirrorCameraRotationMirror);
viewFrustum.setPosition(mirrorCameraPositionWorld); viewFrustum.setPosition(mirrorCameraPositionWorld);
viewFrustum.setOrientation(mirrorCameraRotationWorld); viewFrustum.setOrientation(mirrorCameraRotationWorld);
@ -263,8 +281,8 @@ void EntityRenderer::computeMirrorView(ViewFrustum& viewFrustum) const {
glm::mat4 projection = viewFrustum.getProjection(); glm::mat4 projection = viewFrustum.getProjection();
//Find the camera-space 4D reflection plane vector //Find the camera-space 4D reflection plane vector
glm::vec3 cameraSpacePosition = glm::inverse(view) * glm::vec4(mirrorPropertiesPosition, 1.0f); glm::vec3 cameraSpacePosition = glm::inverse(view) * glm::vec4(outPropertiesPosition, 1.0f);
glm::vec3 cameraSpaceNormal = glm::transpose(view) * (worldFromMirrorRotation * glm::vec4(0, 0, -1, 0)); glm::vec3 cameraSpaceNormal = glm::transpose(view) * (outPropertiesRotation * glm::vec4(0, 0, -1, 0));
glm::vec4 clipPlane = glm::vec4(cameraSpaceNormal, -glm::dot(cameraSpaceNormal, cameraSpacePosition)); glm::vec4 clipPlane = glm::vec4(cameraSpaceNormal, -glm::dot(cameraSpaceNormal, cameraSpacePosition));
if (clipPlane.w > 0.0f) { if (clipPlane.w > 0.0f) {
clipPlane *= -1.0f; clipPlane *= -1.0f;

View file

@ -1085,7 +1085,7 @@ void ModelEntityRenderer::setKey(bool didVisualGeometryRequestSucceed, const Mod
builder.withSubMetaCulled(); builder.withSubMetaCulled();
} }
if (_mirrorMode != MirrorMode::NONE) { if (_mirrorMode == MirrorMode::MIRROR || (_mirrorMode == MirrorMode::PORTAL && !_portalExitID.isNull())) {
builder.withMirror(); builder.withMirror();
} }

View file

@ -217,7 +217,7 @@ void ModelMeshPartPayload::updateKey(const render::ItemKey& key) {
builder.withTransparent(); builder.withTransparent();
} }
if (_cullWithParent || _mirrorMode != MirrorMode::NONE) { if (_cullWithParent) {
builder.withSubMetaCulled(); builder.withSubMetaCulled();
} }

View file

@ -1078,11 +1078,9 @@ void Model::setMirrorMode(MirrorMode mirrorMode, const render::ScenePointer& sce
} }
render::Transaction transaction; render::Transaction transaction;
auto renderItemsKey = _renderItemKeyGlobalFlags;
for (auto item : _modelMeshRenderItemIDs) { for (auto item : _modelMeshRenderItemIDs) {
transaction.updateItem<ModelMeshPartPayload>(item, [mirrorMode, renderItemsKey](ModelMeshPartPayload& data) { transaction.updateItem<ModelMeshPartPayload>(item, [mirrorMode](ModelMeshPartPayload& data) {
data.setMirrorMode(mirrorMode); data.setMirrorMode(mirrorMode);
data.updateKey(renderItemsKey);
}); });
} }
scene->enqueueTransaction(transaction); scene->enqueueTransaction(transaction);
@ -1098,9 +1096,8 @@ void Model::setPortalExitID(const QUuid& portalExitID, const render::ScenePointe
} }
render::Transaction transaction; render::Transaction transaction;
auto renderItemsKey = _renderItemKeyGlobalFlags;
for (auto item : _modelMeshRenderItemIDs) { for (auto item : _modelMeshRenderItemIDs) {
transaction.updateItem<ModelMeshPartPayload>(item, [portalExitID, renderItemsKey](ModelMeshPartPayload& data) { transaction.updateItem<ModelMeshPartPayload>(item, [portalExitID](ModelMeshPartPayload& data) {
data.setPortalExitID(portalExitID); data.setPortalExitID(portalExitID);
}); });
} }