mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-26 01:55:08 +02:00
Correctly update secondary camera frustum
This commit is contained in:
parent
fea49744ed
commit
4c90763236
2 changed files with 75 additions and 19 deletions
|
@ -5179,6 +5179,78 @@ void Application::updateDialogs(float deltaTime) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::updateSecondaryCameraViewFrustum() {
|
||||||
|
// TODO: Fix this by modeling the way the secondary camera works on how the main camera works
|
||||||
|
// ie. Use a camera object stored in the game logic and informs the Engine on where the secondary
|
||||||
|
// camera should be.
|
||||||
|
|
||||||
|
// Code based on SecondaryCameraJob
|
||||||
|
auto renderConfig = _renderEngine->getConfiguration();
|
||||||
|
assert(renderConfig);
|
||||||
|
auto camera = dynamic_cast<SecondaryCameraJobConfig*>(renderConfig->getConfig("SecondaryCamera"));
|
||||||
|
assert(camera);
|
||||||
|
|
||||||
|
if (!camera->isEnabled()) {
|
||||||
|
_hasSecondaryViewFrustum = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (camera->mirrorProjection && !camera->attachedEntityId.isNull()) {
|
||||||
|
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||||
|
auto entityProperties = entityScriptingInterface->getEntityProperties(camera->attachedEntityId);
|
||||||
|
glm::vec3 mirrorPropertiesPosition = entityProperties.getPosition();
|
||||||
|
glm::quat mirrorPropertiesRotation = entityProperties.getRotation();
|
||||||
|
glm::vec3 mirrorPropertiesDimensions = entityProperties.getDimensions();
|
||||||
|
glm::vec3 halfMirrorPropertiesDimensions = 0.5f * mirrorPropertiesDimensions;
|
||||||
|
|
||||||
|
// setup mirror from world as inverse of world from mirror transformation using inverted x and z for mirrored image
|
||||||
|
// TODO: we are assuming here that UP is world y-axis
|
||||||
|
glm::mat4 worldFromMirrorRotation = glm::mat4_cast(mirrorPropertiesRotation) * glm::scale(vec3(-1.0f, 1.0f, -1.0f));
|
||||||
|
glm::mat4 worldFromMirrorTranslation = glm::translate(mirrorPropertiesPosition);
|
||||||
|
glm::mat4 worldFromMirror = worldFromMirrorTranslation * worldFromMirrorRotation;
|
||||||
|
glm::mat4 mirrorFromWorld = glm::inverse(worldFromMirror);
|
||||||
|
|
||||||
|
// get mirror camera position by reflecting main camera position's z coordinate in mirror space
|
||||||
|
glm::vec3 mainCameraPositionWorld = getCamera().getPosition();
|
||||||
|
glm::vec3 mainCameraPositionMirror = vec3(mirrorFromWorld * vec4(mainCameraPositionWorld, 1.0f));
|
||||||
|
glm::vec3 mirrorCameraPositionMirror = vec3(mainCameraPositionMirror.x, mainCameraPositionMirror.y,
|
||||||
|
-mainCameraPositionMirror.z);
|
||||||
|
glm::vec3 mirrorCameraPositionWorld = vec3(worldFromMirror * vec4(mirrorCameraPositionMirror, 1.0f));
|
||||||
|
|
||||||
|
// set frustum position to be mirrored camera and set orientation to mirror's adjusted rotation
|
||||||
|
glm::quat mirrorCameraOrientation = glm::quat_cast(worldFromMirrorRotation);
|
||||||
|
_secondaryViewFrustum.setPosition(mirrorCameraPositionWorld);
|
||||||
|
_secondaryViewFrustum.setOrientation(mirrorCameraOrientation);
|
||||||
|
|
||||||
|
// build frustum using mirror space translation of mirrored camera
|
||||||
|
float nearClip = mirrorCameraPositionMirror.z + mirrorPropertiesDimensions.z * 2.0f;
|
||||||
|
glm::vec3 upperRight = halfMirrorPropertiesDimensions - mirrorCameraPositionMirror;
|
||||||
|
glm::vec3 bottomLeft = -halfMirrorPropertiesDimensions - mirrorCameraPositionMirror;
|
||||||
|
glm::mat4 frustum = glm::frustum(bottomLeft.x, upperRight.x, bottomLeft.y, upperRight.y, nearClip, camera->farClipPlaneDistance);
|
||||||
|
_secondaryViewFrustum.setProjection(frustum);
|
||||||
|
} else {
|
||||||
|
if (!camera->attachedEntityId.isNull()) {
|
||||||
|
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||||
|
auto entityProperties = entityScriptingInterface->getEntityProperties(camera->attachedEntityId);
|
||||||
|
_secondaryViewFrustum.setPosition(entityProperties.getPosition());
|
||||||
|
_secondaryViewFrustum.setOrientation(entityProperties.getRotation());
|
||||||
|
} else {
|
||||||
|
_secondaryViewFrustum.setPosition(camera->position);
|
||||||
|
_secondaryViewFrustum.setOrientation(camera->orientation);
|
||||||
|
}
|
||||||
|
|
||||||
|
float aspectRatio = (float)camera->textureWidth / (float)camera->textureHeight;
|
||||||
|
_secondaryViewFrustum.setProjection(camera->vFoV,
|
||||||
|
aspectRatio,
|
||||||
|
camera->nearClipPlaneDistance,
|
||||||
|
camera->farClipPlaneDistance);
|
||||||
|
}
|
||||||
|
// Without calculating the bound planes, the secondary camera will use the same culling frustum as the main camera,
|
||||||
|
// which is not what we want here.
|
||||||
|
_secondaryViewFrustum.calculate();
|
||||||
|
_hasSecondaryViewFrustum = true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool domainLoadingInProgress = false;
|
static bool domainLoadingInProgress = false;
|
||||||
|
|
||||||
void Application::update(float deltaTime) {
|
void Application::update(float deltaTime) {
|
||||||
|
@ -5533,28 +5605,10 @@ void Application::update(float deltaTime) {
|
||||||
QMutexLocker viewLocker(&_viewMutex);
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
_myCamera.loadViewFrustum(_viewFrustum);
|
_myCamera.loadViewFrustum(_viewFrustum);
|
||||||
|
|
||||||
|
|
||||||
// TODO: Fix this by modeling the way the secondary camera works on how the main camera works
|
// TODO: Fix this by modeling the way the secondary camera works on how the main camera works
|
||||||
// ie. Use a camera object stored in the game logic and informs the Engine on where the secondary
|
// ie. Use a camera object stored in the game logic and informs the Engine on where the secondary
|
||||||
// camera should be.
|
// camera should be.
|
||||||
auto renderConfig = _renderEngine->getConfiguration();
|
updateSecondaryCameraViewFrustum();
|
||||||
assert(renderConfig);
|
|
||||||
auto secondaryCamera = dynamic_cast<SecondaryCameraJobConfig*>(renderConfig->getConfig("SecondaryCamera"));
|
|
||||||
assert(secondaryCamera);
|
|
||||||
|
|
||||||
if (secondaryCamera->isEnabled()) {
|
|
||||||
_secondaryViewFrustum.setPosition(secondaryCamera->position);
|
|
||||||
_secondaryViewFrustum.setOrientation(secondaryCamera->orientation);
|
|
||||||
_secondaryViewFrustum.setProjection(secondaryCamera->vFoV,
|
|
||||||
secondaryCamera->textureWidth / secondaryCamera->textureHeight,
|
|
||||||
secondaryCamera->nearClipPlaneDistance,
|
|
||||||
secondaryCamera->farClipPlaneDistance);
|
|
||||||
_secondaryViewFrustum.calculate();
|
|
||||||
_hasSecondaryViewFrustum = true;
|
|
||||||
} else {
|
|
||||||
_hasSecondaryViewFrustum = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
quint64 now = usecTimestampNow();
|
quint64 now = usecTimestampNow();
|
||||||
|
|
|
@ -149,6 +149,8 @@ public:
|
||||||
void initializeRenderEngine();
|
void initializeRenderEngine();
|
||||||
void initializeUi();
|
void initializeUi();
|
||||||
|
|
||||||
|
void updateSecondaryCameraViewFrustum();
|
||||||
|
|
||||||
void updateCamera(RenderArgs& renderArgs, float deltaTime);
|
void updateCamera(RenderArgs& renderArgs, float deltaTime);
|
||||||
void paintGL();
|
void paintGL();
|
||||||
void resizeGL();
|
void resizeGL();
|
||||||
|
|
Loading…
Reference in a new issue