mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 16:55:07 +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;
|
||||
|
||||
void Application::update(float deltaTime) {
|
||||
|
@ -5533,28 +5605,10 @@ void Application::update(float deltaTime) {
|
|||
QMutexLocker viewLocker(&_viewMutex);
|
||||
_myCamera.loadViewFrustum(_viewFrustum);
|
||||
|
||||
|
||||
// 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.
|
||||
auto renderConfig = _renderEngine->getConfiguration();
|
||||
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;
|
||||
}
|
||||
|
||||
updateSecondaryCameraViewFrustum();
|
||||
}
|
||||
|
||||
quint64 now = usecTimestampNow();
|
||||
|
|
|
@ -149,6 +149,8 @@ public:
|
|||
void initializeRenderEngine();
|
||||
void initializeUi();
|
||||
|
||||
void updateSecondaryCameraViewFrustum();
|
||||
|
||||
void updateCamera(RenderArgs& renderArgs, float deltaTime);
|
||||
void paintGL();
|
||||
void resizeGL();
|
||||
|
|
Loading…
Reference in a new issue