From ca3fe461427b490ac45dba7b02b9bf55947df4bb Mon Sep 17 00:00:00 2001 From: Alex Fuller Date: Mon, 18 Nov 2019 13:35:19 -0800 Subject: [PATCH] Based on https://github.com/boberfly/GafferCycles/pull/33 --- .../IECoreCyclesPreview/CameraAlgo.h | 2 +- .../IECoreCyclesPreview/CameraAlgo.cpp | 34 +++++-------------- .../IECoreCyclesPreview/Renderer.cpp | 32 +++++++++++++---- 3 files changed, 35 insertions(+), 33 deletions(-) diff --git a/include/GafferCycles/IECoreCyclesPreview/CameraAlgo.h b/include/GafferCycles/IECoreCyclesPreview/CameraAlgo.h index 983b910..e1d8d3e 100644 --- a/include/GafferCycles/IECoreCyclesPreview/CameraAlgo.h +++ b/include/GafferCycles/IECoreCyclesPreview/CameraAlgo.h @@ -51,7 +51,7 @@ namespace CameraAlgo { /// Converts the specified IECoreScene::Camera into a ccl::Camera. -IECORECYCLES_API ccl::Camera *convert( const IECoreScene::Camera *camera, const std::string &nodeName ); +IECORECYCLES_API ccl::Camera *convert( const IECoreScene::Camera *camera, const std::string &nodeName, int frame ); } // namespace CameraAlgo diff --git a/src/GafferCycles/IECoreCyclesPreview/CameraAlgo.cpp b/src/GafferCycles/IECoreCyclesPreview/CameraAlgo.cpp index 5497c4e..e47cee7 100644 --- a/src/GafferCycles/IECoreCyclesPreview/CameraAlgo.cpp +++ b/src/GafferCycles/IECoreCyclesPreview/CameraAlgo.cpp @@ -66,7 +66,7 @@ ccl::Camera *convertCommon( const IECoreScene::Camera *camera, const std::string ccam->fov = M_PI_2; if( camera->getFStop() > 0.0f ) { - ccam->aperturesize = camera->getFocalLength() * camera->getFocalLengthWorldScale() / camera->getFStop(); + ccam->aperturesize = 0.5f * camera->getFocalLength() * camera->getFocalLengthWorldScale() / camera->getFStop(); ccam->focaldistance = camera->getFocusDistance(); } } @@ -87,7 +87,7 @@ ccl::Camera *convertCommon( const IECoreScene::Camera *camera, const std::string // Screen window/resolution TODO: full_ might be something to do with cropping? const Imath::Box2f &frustum = camera->frustum(); - const Imath::V2i &resolution = camera->getResolution(); + const Imath::V2i &resolution = camera->renderResolution(); const float pixelAspectRatio = camera->getPixelAspectRatio(); ccam->width = resolution[0]; ccam->height = resolution[1]; @@ -95,15 +95,16 @@ ccl::Camera *convertCommon( const IECoreScene::Camera *camera, const std::string ccam->full_height = resolution[1]; ccam->viewplane.left = frustum.min.x; ccam->viewplane.right = frustum.max.x; - ccam->viewplane.bottom = frustum.min.y; - ccam->viewplane.top = frustum.max.y; + // Invert the viewplane in Y so Gaffer's aperture offsets and overscan are applied in the correct direction + ccam->viewplane.bottom = -frustum.max.y; + ccam->viewplane.top = -frustum.min.y; ccam->aperture_ratio = pixelAspectRatio; // This is more for the bokeh, maybe it should be a separate parameter? // Clipping planes const Imath::V2f &clippingPlanes = camera->getClippingPlanes(); ccam->nearclip = clippingPlanes.x; ccam->farclip = clippingPlanes.y; - + // Crop window if ( camera->hasCropWindow() ) { @@ -115,28 +116,9 @@ ccl::Camera *convertCommon( const IECoreScene::Camera *camera, const std::string ccam->border.clamp(); } - // Shutter TODO: Need to see if this is correct or not, cycles also has a shutter curve... + // Shutter TODO: Cycles also has a shutter curve... const Imath::V2f &shutter = camera->getShutter(); - if ((shutter.x > 0.0) && (shutter.y > 0.0)) - { - ccam->motion_position = ccl::Camera::MOTION_POSITION_START; - ccam->shuttertime = shutter.x + shutter.y; - } - else if ((shutter.x < 0.0) && (shutter.y > 0.0)) - { - ccam->motion_position = ccl::Camera::MOTION_POSITION_CENTER; - ccam->shuttertime = abs(shutter.x) + shutter.y; - } - else if ((shutter.x < 0.0) && (shutter.y <= 0.0)) - { - ccam->motion_position = ccl::Camera::MOTION_POSITION_END; - ccam->shuttertime = abs(shutter.x) + abs(shutter.y); - } - else - { - ccam->motion_position = ccl::Camera::MOTION_POSITION_CENTER; - ccam->shuttertime = 1.0; - } + ccam->shuttertime = abs( shutter.y - shutter.x ); return ccam; } diff --git a/src/GafferCycles/IECoreCyclesPreview/Renderer.cpp b/src/GafferCycles/IECoreCyclesPreview/Renderer.cpp index 367f029..d8b722d 100644 --- a/src/GafferCycles/IECoreCyclesPreview/Renderer.cpp +++ b/src/GafferCycles/IECoreCyclesPreview/Renderer.cpp @@ -1909,16 +1909,36 @@ class CameraCache : public IECore::RefCounted } // Can be called concurrently with other get() calls. - SharedCCameraPtr get( const IECoreScene::Camera *camera, const std::string &name ) + SharedCCameraPtr get( const IECoreScene::Camera *camera, const std::string &name, int frame ) { - const IECore::MurmurHash hash = camera->Object::hash(); + IECore::MurmurHash hash = camera->Object::hash(); + + hash.append( frame ); Cache::accessor a; m_cache.insert( a, hash ); if( !a->second ) { - a->second = SharedCCameraPtr( CameraAlgo::convert( camera, name ) ); + ccl::Camera *ccam = CameraAlgo::convert( camera, name ); + + // Set the correct motion position here as we need access to the current frame. + const Imath::V2f &shutter = camera->getShutter(); + const Imath::V2f relativeShutter = shutter - Imath::V2f( frame ); + if ( ( relativeShutter.x >= 0.0f ) && ( relativeShutter.y > 0.0f ) ) + { + ccam->motion_position = ccl::Camera::MOTION_POSITION_START; + } + else if ( ( relativeShutter.x < 0.0f ) && ( relativeShutter.y <= 0.0f ) ) + { + ccam->motion_position = ccl::Camera::MOTION_POSITION_END; + } + else + { + ccam->motion_position = ccl::Camera::MOTION_POSITION_CENTER; + } + + a->second = SharedCCameraPtr( ccam ); } return a->second; @@ -2961,7 +2981,7 @@ class CyclesRenderer final : public IECoreScenePreview::Renderer ObjectInterfacePtr camera( const std::string &name, const IECoreScene::Camera *camera, const AttributesInterface *attributes ) override { - SharedCCameraPtr ccamera = m_cameraCache->get( camera, name ); + SharedCCameraPtr ccamera = m_cameraCache->get( camera, name, m_frame ); if( !ccamera ) { return nullptr; @@ -3347,7 +3367,7 @@ class CyclesRenderer final : public IECoreScenePreview::Renderer } else { - auto ccamera = m_cameraCache->get( cameraIt->second.get(), cameraIt->first ); + auto ccamera = m_cameraCache->get( cameraIt->second.get(), cameraIt->first, m_frame ); if( m_scene->camera != ccamera.get() ) { m_scene->camera = ccamera.get(); @@ -3373,7 +3393,7 @@ class CyclesRenderer final : public IECoreScenePreview::Renderer } else { - auto ccamera = m_cameraCache->get( cameraIt->second.get(), cameraIt->first ); + auto ccamera = m_cameraCache->get( cameraIt->second.get(), cameraIt->first, m_frame ); m_instanceCache->updateDicingCamera( ccamera.get() ); } }