Showing the changes to interface/src/Application.cpp (1 of 2 files). Show all
Unified · Split
| @@ -5179,6 +5179,78 @@ void Application::updateDialogs(float deltaTime) const { · 5178 unmodified lines | ||
| 5179 | 5179 | } |
| 5180 | 5180 | } |
| 5181 | 5181 | |
| 5182 | +void Application::updateSecondaryCameraViewFrustum() { | |
| 5183 | + // TODO: Fix this by modeling the way the secondary camera works on how the main camera works | |
| 5184 | + // ie. Use a camera object stored in the game logic and informs the Engine on where the secondary | |
| 5185 | + // camera should be. | |
| 5186 | + | |
| 5187 | + // Code based on SecondaryCameraJob | |
| 5188 | + auto renderConfig = _renderEngine->getConfiguration(); | |
| 5189 | + assert(renderConfig); | |
| 5190 | + auto camera = dynamic_cast<SecondaryCameraJobConfig*>(renderConfig->getConfig("SecondaryCamera")); | |
| 5191 | + assert(camera); | |
| 5192 | + | |
| 5193 | + if (!camera->isEnabled()) { | |
| 5194 | + _hasSecondaryViewFrustum = false; | |
| 5195 | + return; | |
| 5196 | + } | |
| 5197 | + | |
| 5198 | + if (camera->mirrorProjection && !camera->attachedEntityId.isNull()) { | |
| 5199 | + auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>(); | |
| 5200 | + auto entityProperties = entityScriptingInterface->getEntityProperties(camera->attachedEntityId); | |
| 5201 | + glm::vec3 mirrorPropertiesPosition = entityProperties.getPosition(); | |
| 5202 | + glm::quat mirrorPropertiesRotation = entityProperties.getRotation(); | |
| 5203 | + glm::vec3 mirrorPropertiesDimensions = entityProperties.getDimensions(); | |
| 5204 | + glm::vec3 halfMirrorPropertiesDimensions = 0.5f * mirrorPropertiesDimensions; | |
| 5205 | + | |
| 5206 | + // setup mirror from world as inverse of world from mirror transformation using inverted x and z for mirrored image | |
| 5207 | + // TODO: we are assuming here that UP is world y-axis | |
| 5208 | + glm::mat4 worldFromMirrorRotation = glm::mat4_cast(mirrorPropertiesRotation) * glm::scale(vec3(-1.0f, 1.0f, -1.0f)); | |
| 5209 | + glm::mat4 worldFromMirrorTranslation = glm::translate(mirrorPropertiesPosition); | |
| 5210 | + glm::mat4 worldFromMirror = worldFromMirrorTranslation * worldFromMirrorRotation; | |
| 5211 | + glm::mat4 mirrorFromWorld = glm::inverse(worldFromMirror); | |
| 5212 | + | |
| 5213 | + // get mirror camera position by reflecting main camera position's z coordinate in mirror space | |
| 5214 | + glm::vec3 mainCameraPositionWorld = getCamera().getPosition(); | |
| 5215 | + glm::vec3 mainCameraPositionMirror = vec3(mirrorFromWorld * vec4(mainCameraPositionWorld, 1.0f)); | |
| 5216 | + glm::vec3 mirrorCameraPositionMirror = vec3(mainCameraPositionMirror.x, mainCameraPositionMirror.y, | |
| 5217 | + -mainCameraPositionMirror.z); | |
| 5218 | + glm::vec3 mirrorCameraPositionWorld = vec3(worldFromMirror * vec4(mirrorCameraPositionMirror, 1.0f)); | |
| 5219 | + | |
| 5220 | + // set frustum position to be mirrored camera and set orientation to mirror's adjusted rotation | |
| 5221 | + glm::quat mirrorCameraOrientation = glm::quat_cast(worldFromMirrorRotation); | |
| 5222 | + _secondaryViewFrustum.setPosition(mirrorCameraPositionWorld); | |
| 5223 | + _secondaryViewFrustum.setOrientation(mirrorCameraOrientation); | |
| 5224 | + | |
| 5225 | + // build frustum using mirror space translation of mirrored camera | |
| 5226 | + float nearClip = mirrorCameraPositionMirror.z + mirrorPropertiesDimensions.z * 2.0f; | |
| 5227 | + glm::vec3 upperRight = halfMirrorPropertiesDimensions - mirrorCameraPositionMirror; | |
| 5228 | + glm::vec3 bottomLeft = -halfMirrorPropertiesDimensions - mirrorCameraPositionMirror; | |
| 5229 | + glm::mat4 frustum = glm::frustum(bottomLeft.x, upperRight.x, bottomLeft.y, upperRight.y, nearClip, camera->farClipPlaneDistance); | |
| 5230 | + _secondaryViewFrustum.setProjection(frustum); | |
| 5231 | + } else { | |
| 5232 | + if (!camera->attachedEntityId.isNull()) { | |
| 5233 | + auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>(); | |
| 5234 | + auto entityProperties = entityScriptingInterface->getEntityProperties(camera->attachedEntityId); | |
| 5235 | + _secondaryViewFrustum.setPosition(entityProperties.getPosition()); | |
| 5236 | + _secondaryViewFrustum.setOrientation(entityProperties.getRotation()); | |
| 5237 | + } else { | |
| 5238 | + _secondaryViewFrustum.setPosition(camera->position); | |
| 5239 | + _secondaryViewFrustum.setOrientation(camera->orientation); | |
| 5240 | + } | |
| 5241 | + | |
| 5242 | + float aspectRatio = (float)camera->textureWidth / (float)camera->textureHeight; | |
| 5243 | + _secondaryViewFrustum.setProjection(camera->vFoV, | |
| 5244 | + aspectRatio, | |
| 5245 | + camera->nearClipPlaneDistance, | |
| 5246 | + camera->farClipPlaneDistance); | |
| 5247 | + } | |
| 5248 | + // Without calculating the bound planes, the secondary camera will use the same culling frustum as the main camera, | |
| 5249 | + // which is not what we want here. | |
| 5250 | + _secondaryViewFrustum.calculate(); | |
| 5251 | + _hasSecondaryViewFrustum = true; | |
| 5252 | +} | |
| 5253 | + | |
| 5182 | 5254 | static bool domainLoadingInProgress = false; |
| 5183 | 5255 | |
| 5184 | 5256 | void Application::update(float deltaTime) { |
| @@ -5533,28 +5605,10 @@ void Application::update(float deltaTime) { · 348 unmodified lines | ||
| 5533 | 5605 | QMutexLocker viewLocker(&_viewMutex); |
| 5534 | 5606 | _myCamera.loadViewFrustum(_viewFrustum); |
| 5535 | 5607 | |
| 5536 | − | |
| 5537 | 5608 | // TODO: Fix this by modeling the way the secondary camera works on how the main camera works |
| 5538 | 5609 | // ie. Use a camera object stored in the game logic and informs the Engine on where the secondary |
| 5539 | 5610 | // camera should be. |
| 5540 | − auto renderConfig = _renderEngine->getConfiguration(); | |
| 5541 | − assert(renderConfig); | |
| 5542 | − auto secondaryCamera = dynamic_cast<SecondaryCameraJobConfig*>(renderConfig->getConfig("SecondaryCamera")); | |
| 5543 | − assert(secondaryCamera); | |
| 5544 | − | |
| 5545 | − if (secondaryCamera->isEnabled()) { | |
| 5546 | − _secondaryViewFrustum.setPosition(secondaryCamera->position); | |
| 5547 | − _secondaryViewFrustum.setOrientation(secondaryCamera->orientation); | |
| 5548 | − _secondaryViewFrustum.setProjection(secondaryCamera->vFoV, | |
| 5549 | − secondaryCamera->textureWidth / secondaryCamera->textureHeight, | |
| 5550 | − secondaryCamera->nearClipPlaneDistance, | |
| 5551 | − secondaryCamera->farClipPlaneDistance); | |
| 5552 | − _secondaryViewFrustum.calculate(); | |
| 5553 | − _hasSecondaryViewFrustum = true; | |
| 5554 | − } else { | |
| 5555 | − _hasSecondaryViewFrustum = false; | |
| 5556 | − } | |
| 5557 | − | |
| 5611 | + updateSecondaryCameraViewFrustum(); | |
| 5558 | 5612 | } |
| 5559 | 5613 | |
| 5560 | 5614 | quint64 now = usecTimestampNow(); |