| |
| |
| #include "toonz/tcamera.h" |
| #include "toonz/stage.h" |
| #include "tstream.h" |
| #include "texception.h" |
| |
| |
| |
| |
| TCamera::TCamera() |
| : m_size(12, 9), m_res(768, 576), m_xPrevalence(true) |
| { |
| } |
| |
| |
| |
| void TCamera::setSize(const TDimensionD &size, bool preserveDpi, bool preserveAR) |
| { |
| |
| double currAR = getAspectRatio(); |
| TPointD currDpi = getDpi(); |
| m_size.lx = size.lx; |
| if (preserveAR) |
| m_size.ly = m_size.lx / currAR; |
| else |
| m_size.ly = size.ly; |
| |
| if (!preserveDpi) |
| return; |
| |
| m_res.lx = troundp(currDpi.x * m_size.lx); |
| m_res.ly = troundp(currDpi.y * m_size.ly); |
| m_size.lx = m_res.lx / currDpi.x; |
| if (preserveAR) |
| { |
| double aux = m_size.lx / currAR - m_res.ly / currDpi.y; |
| m_size.ly = m_size.lx / currAR; |
| } else |
| m_size.ly = m_res.ly / currDpi.y; |
| } |
| |
| |
| |
| double TCamera::getAspectRatio() const |
| { |
| return m_size.lx / m_size.ly; |
| } |
| |
| |
| |
| void TCamera::setRes(const TDimension &res) |
| { |
| assert(res.lx > 0); |
| assert(res.ly > 0); |
| |
| if (m_res != res) { |
| m_res = res; |
| m_interestRect = TRect(); |
| } |
| } |
| |
| |
| |
| TPointD TCamera::getDpi() const |
| { |
| TPointD dpi; |
| if (m_size.lx > 0 && m_size.ly > 0) { |
| dpi.x = m_res.lx / m_size.lx; |
| dpi.y = m_res.ly / m_size.ly; |
| } |
| return dpi; |
| } |
| |
| |
| |
| bool TCamera::isPixelSquared() const |
| { |
| return areAlmostEqual(m_res.lx * m_size.ly, m_res.ly * m_size.lx); |
| } |
| |
| |
| |
| TAffine TCamera::getStageToCameraRef() const |
| { |
| return TAffine( |
| m_res.lx / (Stage::inch * m_size.lx), 0, 0.5 * m_res.lx, |
| 0, m_res.ly / (Stage::inch * m_size.ly), 0.5 * m_res.ly); |
| } |
| |
| |
| |
| TAffine TCamera::getCameraToStageRef() const |
| { |
| const double factor = Stage::inch; |
| |
| TDimensionD cameraSize = getSize(); |
| cameraSize.lx *= factor; |
| cameraSize.ly *= factor; |
| TPointD center(0.5 * cameraSize.lx, 0.5 * cameraSize.ly); |
| |
| return TAffine( |
| factor * m_size.lx / (double)m_res.lx, 0, -center.x, |
| 0, factor * m_size.ly / (double)m_res.ly, -center.y); |
| } |
| |
| |
| |
| TRectD TCamera::getStageRect() const |
| { |
| TDimensionD cameraSize = getSize(); |
| const double factor = Stage::inch; |
| cameraSize.lx *= factor; |
| cameraSize.ly *= factor; |
| TRectD rect(cameraSize); |
| rect -= 0.5 * (rect.getP00() + rect.getP11()); |
| return rect; |
| } |
| |
| |
| |
| void TCamera::setInterestRect(const TRect &rect) |
| { |
| |
| |
| |
| |
| |
| m_interestRect.x0 = tmax(rect.x0, 0); |
| m_interestRect.y0 = tmax(rect.y0, 0); |
| m_interestRect.x1 = tmin(rect.x1, m_res.lx - 1); |
| m_interestRect.y1 = tmin(rect.y1, m_res.ly - 1); |
| } |
| |
| |
| |
| TRectD TCamera::getInterestStageRect() const |
| { |
| return getCameraToStageRef() * TRectD(m_interestRect.x0, m_interestRect.y0, m_interestRect.x1 + 1, m_interestRect.y1 + 1); |
| } |
| |
| |
| |
| void TCamera::setInterestStageRect(const TRectD &rect) |
| { |
| TRectD cameraInterestRectD( |
| getStageToCameraRef() * rect); |
| |
| setInterestRect(TRect( |
| tfloor(cameraInterestRectD.x0), |
| tfloor(cameraInterestRectD.y0), |
| tceil(cameraInterestRectD.x1) - 1, |
| tceil(cameraInterestRectD.y1) - 1)); |
| } |
| |
| |
| |
| void TCamera::saveData(TOStream &os) const |
| { |
| os.child("cameraSize") << m_size.lx << m_size.ly; |
| os.child("cameraRes") << m_res.lx << m_res.ly; |
| os.child("cameraXPrevalence") << (int)m_xPrevalence; |
| os.child("interestRect") << m_interestRect.x0 << m_interestRect.y0 << m_interestRect.x1 << m_interestRect.y1; |
| } |
| |
| |
| |
| void TCamera::loadData(TIStream &is) |
| { |
| string tagName; |
| while (is.matchTag(tagName)) { |
| if (tagName == "cameraSize" || tagName == "size") |
| is >> m_size.lx >> m_size.ly; |
| else if (tagName == "cameraRes" || tagName == "res") |
| is >> m_res.lx >> m_res.ly; |
| else if (tagName == "cameraXPrevalence") { |
| int xPrevalence; |
| is >> xPrevalence; |
| m_xPrevalence = (bool)xPrevalence; |
| } else if (tagName == "interestRect") { |
| is >> m_interestRect.x0 >> m_interestRect.y0 >> m_interestRect.x1 >> m_interestRect.y1; |
| } else |
| throw TException("TCamera::loadData. unexpected tag: " + tagName); |
| is.matchEndTag(); |
| } |
| } |
| |