IECore::ConstObjectPtr Camera::computeSource( const Context *context ) const { IECore::CameraPtr result = new IECore::Camera; result->parameters()["projection"] = new IECore::StringData( projectionPlug()->getValue() ); result->parameters()["projection:fov"] = new IECore::FloatData( fieldOfViewPlug()->getValue() ); result->parameters()["clippingPlanes"] = new IECore::V2fData( clippingPlanesPlug()->getValue() ); return result; }
void Render::outputCamera( const ScenePlug *scene, const IECore::CompoundObject *globals, IECore::Renderer *renderer ) const { // get the camera from the scene const StringData *cameraPathData = globals->member<StringData>( "render:camera" ); IECore::CameraPtr camera = 0; if( cameraPathData ) { ScenePlug::ScenePath cameraPath; ScenePlug::stringToPath( cameraPathData->readable(), cameraPath ); IECore::ConstCameraPtr constCamera = runTimeCast<const IECore::Camera>( scene->object( cameraPath ) ); if( constCamera ) { camera = constCamera->copy(); const BoolData *cameraBlurData = globals->member<BoolData>( "render:cameraBlur" ); const bool cameraBlur = cameraBlurData ? cameraBlurData->readable() : false; camera->setTransform( transform( scene, cameraPath, shutter( globals ), cameraBlur ) ); } } if( !camera ) { camera = new IECore::Camera(); } // apply the resolution const V2iData *resolutionData = globals->member<V2iData>( "render:resolution" ); if( resolutionData ) { camera->parameters()["resolution"] = resolutionData->copy(); } camera->addStandardParameters(); // apply the shutter camera->parameters()["shutter"] = new V2fData( shutter( globals ) ); // and output camera->render( renderer ); }
void updateViewportCameraAndOverlay() { if( !m_viewportCameraDirty ) { return; } if( !m_lookThroughCamera ) { m_overlay->setResolutionGate( Box2f() ); m_overlay->setVisible( false ); return; } // The camera will have a resolution and screen window set from the scene // globals. We need to adjust them to fit the viewport appropriately, placing // the resolution gate centrally with a border around it. Start by figuring // out where we'll draw the resolution gate in raster space. IECore::CameraPtr camera = m_lookThroughCamera->copy(); const float borderPixels = 40; const V2f viewport = m_view->viewportGadget()->getViewport(); const V2f insetViewport( max( viewport.x - borderPixels * 2.0f, min( viewport.x, 50.0f ) ), max( viewport.y - borderPixels * 2.0f, min( viewport.y, 50.0f ) ) ); const float insetViewportAspectRatio = insetViewport.x / insetViewport.y; const V2f resolution = camera->parametersData()->member<V2iData>( "resolution" )->readable(); const float pixelAspectRatio = camera->parametersData()->member<FloatData>( "pixelAspectRatio" )->readable(); V2f resolutionGateSize = resolution; resolutionGateSize.x *= pixelAspectRatio; const float resolutionGateAspectRatio = resolutionGateSize.x / resolutionGateSize.y; if( resolutionGateAspectRatio > insetViewportAspectRatio ) { // fit horizontally resolutionGateSize *= insetViewport.x / resolutionGateSize.x; } else { // fit vertically resolutionGateSize *= insetViewport.y / resolutionGateSize.y; } const V2f offset = ( viewport - resolutionGateSize ) / 2.0f; m_overlay->setResolutionGate( Box2f( V2f( offset ), V2f( resolutionGateSize + offset ) ) ); m_overlay->setCropWindow( camera->parametersData()->member<Box2fData>( "cropWindow" )->readable() ); m_overlay->setCaption( boost::str( boost::format( "%dx%d, %.3f, %s" ) % resolution.x % resolution.y % pixelAspectRatio % camera->getName() ) ); m_overlay->setVisible( true ); // Now modify the camera, so that the view through the resolution gate we've calculated // represents the rendered image - this means extending the resolution and screen // window to account for the border area outside the resolution gate. Box2f &screenWindow = camera->parametersData()->member<Box2fData>( "screenWindow" )->writable(); const V2f newScreenWindowSize = screenWindow.size() * viewport / resolutionGateSize; const V2f screenWindowCenter = screenWindow.center(); screenWindow.min = screenWindowCenter - newScreenWindowSize / 2.0f; screenWindow.max = screenWindowCenter + newScreenWindowSize / 2.0f; camera->parameters()["resolution"] = new V2iData( m_view->viewportGadget()->getViewport() ); m_view->viewportGadget()->setCamera( camera.get() ); m_view->viewportGadget()->setCameraEditable( false ); }
void SceneView::updateLookThrough() { Context::Scope scopedContext( getContext() ); const ScenePlug *scene = preprocessedInPlug<ScenePlug>(); ConstCompoundObjectPtr globals = scene->globalsPlug()->getValue(); string cameraPathString; IECore::CameraPtr camera; if( lookThroughEnabledPlug()->getValue() ) { cameraPathString = lookThroughCameraPlug()->getValue(); if( cameraPathString.empty() ) { if( const StringData *cameraPathData = globals->member<StringData>( "render:camera" ) ) { cameraPathString = cameraPathData->readable(); } } if( !cameraPathString.empty() ) { ScenePlug::ScenePath cameraPath; ScenePlug::stringToPath( cameraPathString, cameraPath ); try { ConstCameraPtr constCamera = runTimeCast<const IECore::Camera>( scene->object( cameraPath ) ); if( constCamera ) { camera = constCamera->copy(); camera->setTransform( new MatrixTransform( scene->fullTransform( cameraPath ) ) ); // if the camera has an existing screen window, remove it. // if we didn't, it would conflict with the resolution we set // below, yielding squashed/stretched images. /// \todo Properly specify how cameras are represented in Gaffer /// (the Cortex representation is very renderer-centric, with no /// real world parameters like film back) so that this isn't necessary, /// and add nice overlays for resolution gate etc. camera->parameters().erase( "screenWindow" ); } } catch( ... ) { // if an invalid path has been entered for the camera, computation will fail. // we can just ignore that and fall through to lock to the current camera instead. cameraPathString = ""; } } if( !camera ) { // we couldn't find a render camera to lock to, but we can lock to the current // camera instead. camera = viewportGadget()->getCamera()->copy(); } } if( camera ) { camera->parameters()["resolution"] = new V2iData( viewportGadget()->getViewport() ); viewportGadget()->setCamera( camera ); viewportGadget()->setCameraEditable( false ); StringVectorDataPtr invisiblePaths = new StringVectorData(); invisiblePaths->writable().push_back( cameraPathString ); hideFilter()->pathsPlug()->setValue( invisiblePaths ); } else { viewportGadget()->setCameraEditable( true ); hideFilter()->pathsPlug()->setToDefault(); } }