323 lines
11 KiB
C++
323 lines
11 KiB
C++
//-*****************************************************************************
|
|
//
|
|
// Copyright (c) 2009-2012,
|
|
// Sony Pictures Imageworks Inc. and
|
|
// Industrial Light & Magic, a division of Lucasfilm Entertainment Company Ltd.
|
|
//
|
|
// All rights reserved.
|
|
//
|
|
// Redistribution and use in source and binary forms, with or without
|
|
// modification, are permitted provided that the following conditions are
|
|
// met:
|
|
// * Redistributions of source code must retain the above copyright
|
|
// notice, this list of conditions and the following disclaimer.
|
|
// * Redistributions in binary form must reproduce the above
|
|
// copyright notice, this list of conditions and the following disclaimer
|
|
// in the documentation and/or other materials provided with the
|
|
// distribution.
|
|
// * Neither the name of Sony Pictures Imageworks, nor
|
|
// Industrial Light & Magic, nor the names of their contributors may be used
|
|
// to endorse or promote products derived from this software without specific
|
|
// prior written permission.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
//
|
|
//-*****************************************************************************
|
|
|
|
#include "MayaCameraWriter.h"
|
|
|
|
MayaCameraWriter::MayaCameraWriter(MDagPath & iDag,
|
|
Alembic::Abc::OObject & iParent, Alembic::Util::uint32_t iTimeIndex,
|
|
const JobArgs & iArgs) :
|
|
mIsAnimated(false),
|
|
mDagPath(iDag),
|
|
mUseRenderShutter(false),
|
|
mShutterOpen(0.0),
|
|
mShutterClose(0.0)
|
|
{
|
|
MStatus status = MS::kSuccess;
|
|
MFnCamera cam(iDag, &status);
|
|
if (!status)
|
|
{
|
|
MGlobal::displayError( "MFnCamera() failed for MayaCameraWriter" );
|
|
}
|
|
|
|
MString name = cam.name();
|
|
name = util::stripNamespaces(name, iArgs.stripNamespace);
|
|
|
|
Alembic::AbcGeom::OCamera obj(iParent, name.asChar(), iTimeIndex);
|
|
mSchema = obj.getSchema();
|
|
|
|
MObject cameraObj = iDag.node();
|
|
if (iTimeIndex != 0 && util::isAnimated(cameraObj))
|
|
{
|
|
mIsAnimated = true;
|
|
}
|
|
else
|
|
{
|
|
iTimeIndex = 0;
|
|
}
|
|
|
|
MObject renderObj;
|
|
MSelectionList sel;
|
|
sel.add("defaultRenderGlobals");
|
|
|
|
if (!sel.isEmpty())
|
|
{
|
|
sel.getDependNode(0, renderObj);
|
|
MFnDependencyNode dep(renderObj);
|
|
MPlug plug = dep.findPlug("motionBlurUseShutter", true);
|
|
if (plug.asBool())
|
|
{
|
|
MTime sec(1.0, MTime::kSeconds);
|
|
double val = sec.as(MTime::uiUnit());
|
|
|
|
mUseRenderShutter = true;
|
|
plug = dep.findPlug("motionBlurShutterOpen", true);
|
|
mShutterOpen = plug.asDouble() / val;
|
|
plug = dep.findPlug("motionBlurShutterClose", true);
|
|
mShutterClose = plug.asDouble() / val;
|
|
}
|
|
}
|
|
|
|
Alembic::Abc::OCompoundProperty cp;
|
|
Alembic::Abc::OCompoundProperty up;
|
|
if (AttributesWriter::hasAnyAttr(cam, iArgs))
|
|
{
|
|
cp = mSchema.getArbGeomParams();
|
|
up = mSchema.getUserProperties();
|
|
}
|
|
|
|
mAttrs = AttributesWriterPtr(new AttributesWriter(cp, up, obj, cam,
|
|
iTimeIndex, iArgs, true));
|
|
|
|
if (!mIsAnimated || iArgs.setFirstAnimShape)
|
|
{
|
|
write();
|
|
}
|
|
}
|
|
|
|
void MayaCameraWriter::write()
|
|
{
|
|
MFnCamera mfnCamera(mDagPath);
|
|
|
|
mSamp.setFocalLength(mfnCamera.focalLength());
|
|
mSamp.setLensSqueezeRatio(mfnCamera.lensSqueezeRatio());
|
|
mSamp.setHorizontalAperture(mfnCamera.horizontalFilmAperture() * 2.54);
|
|
mSamp.setVerticalAperture(mfnCamera.verticalFilmAperture() * 2.54);
|
|
mSamp.setHorizontalFilmOffset(mfnCamera.horizontalFilmOffset() * 2.54);
|
|
mSamp.setVerticalFilmOffset(mfnCamera.verticalFilmOffset() * 2.54);
|
|
double overscan = mfnCamera.overscan() - 1.0;
|
|
mSamp.setOverScanLeft(overscan);
|
|
mSamp.setOverScanRight(overscan);
|
|
mSamp.setOverScanTop(overscan);
|
|
mSamp.setOverScanBottom(overscan);
|
|
mSamp.setNearClippingPlane(mfnCamera.nearClippingPlane());
|
|
mSamp.setFarClippingPlane(mfnCamera.farClippingPlane());
|
|
mSamp.setFStop(mfnCamera.fStop());
|
|
mSamp.setFocusDistance(mfnCamera.focusDistance());
|
|
|
|
// should this be based on the shutterAngle? or the settings passed in?
|
|
|
|
if (mUseRenderShutter)
|
|
{
|
|
mSamp.setShutterOpen(mShutterOpen);
|
|
mSamp.setShutterClose(mShutterClose);
|
|
}
|
|
else
|
|
{
|
|
MTime sec(1.0, MTime::kSeconds);
|
|
mSamp.setShutterOpen(0.0);
|
|
mSamp.setShutterClose(
|
|
Alembic::AbcGeom::RadiansToDegrees(mfnCamera.shutterAngle()) /
|
|
( 360.0 * sec.as(MTime::uiUnit()) ));
|
|
}
|
|
|
|
// build up the film fit and post projection matrix
|
|
if (mSchema.getNumSamples() == 0)
|
|
{
|
|
// film fit first
|
|
std::string filmFitName = "filmFit";
|
|
mFilmFit = mfnCamera.filmFit();
|
|
switch (mFilmFit)
|
|
{
|
|
case MFnCamera::kFillFilmFit:
|
|
{
|
|
Alembic::AbcGeom::FilmBackXformOp fit(
|
|
Alembic::AbcGeom::kScaleFilmBackOperation, "filmFitFill");
|
|
mSamp.addOp(fit);
|
|
}
|
|
break;
|
|
|
|
case MFnCamera::kHorizontalFilmFit:
|
|
{
|
|
Alembic::AbcGeom::FilmBackXformOp fit(
|
|
Alembic::AbcGeom::kScaleFilmBackOperation, "filmFitHorz");
|
|
mSamp.addOp(fit);
|
|
|
|
Alembic::AbcGeom::FilmBackXformOp offset(
|
|
Alembic::AbcGeom::kTranslateFilmBackOperation,
|
|
"filmFitOffs");
|
|
mSamp.addOp(offset);
|
|
}
|
|
break;
|
|
|
|
case MFnCamera::kVerticalFilmFit:
|
|
{
|
|
Alembic::AbcGeom::FilmBackXformOp fit(
|
|
Alembic::AbcGeom::kScaleFilmBackOperation, "filmFitVert");
|
|
mSamp.addOp(fit);
|
|
|
|
Alembic::AbcGeom::FilmBackXformOp offset(
|
|
Alembic::AbcGeom::kTranslateFilmBackOperation,
|
|
"filmFitOffs");
|
|
mSamp.addOp(offset);
|
|
}
|
|
break;
|
|
|
|
case MFnCamera::kOverscanFilmFit:
|
|
{
|
|
Alembic::AbcGeom::FilmBackXformOp fit(
|
|
Alembic::AbcGeom::kScaleFilmBackOperation, "filmFitOver");
|
|
mSamp.addOp(fit);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
Alembic::AbcGeom::FilmBackXformOp preScale(
|
|
Alembic::AbcGeom::kScaleFilmBackOperation, "preScale");
|
|
mSamp.addOp(preScale);
|
|
|
|
Alembic::AbcGeom::FilmBackXformOp filmTranslate(
|
|
Alembic::AbcGeom::kTranslateFilmBackOperation, "filmTranslate");
|
|
mSamp.addOp(filmTranslate);
|
|
|
|
// skip film roll for now
|
|
|
|
Alembic::AbcGeom::FilmBackXformOp postScale(
|
|
Alembic::AbcGeom::kScaleFilmBackOperation, "postScale");
|
|
mSamp.addOp(postScale);
|
|
|
|
Alembic::AbcGeom::FilmBackXformOp cameraScale(
|
|
Alembic::AbcGeom::kScaleFilmBackOperation, "cameraScale");
|
|
mSamp.addOp(cameraScale);
|
|
|
|
}
|
|
|
|
std::size_t filmBackIndex = 0;
|
|
|
|
switch (mFilmFit)
|
|
{
|
|
case MFnCamera::kFillFilmFit:
|
|
{
|
|
if (mSamp.getLensSqueezeRatio() > 1.0)
|
|
{
|
|
mSamp[0].setChannelValue(0, 1.0/mSamp.getLensSqueezeRatio());
|
|
mSamp[0].setChannelValue(1, 1.0);
|
|
}
|
|
else
|
|
{
|
|
mSamp[0].setChannelValue(0, 1.0);
|
|
mSamp[0].setChannelValue(1, mSamp.getLensSqueezeRatio());
|
|
}
|
|
filmBackIndex = 1;
|
|
}
|
|
break;
|
|
|
|
case MFnCamera::kHorizontalFilmFit:
|
|
{
|
|
if (mSamp.getLensSqueezeRatio() > 1.0)
|
|
{
|
|
mSamp[0].setChannelValue(0, 1.0);
|
|
mSamp[0].setChannelValue(1, mSamp.getLensSqueezeRatio());
|
|
mSamp[1].setChannelValue(0, 0.0);
|
|
mSamp[1].setChannelValue(1, 2.0 *
|
|
mfnCamera.filmFitOffset()/
|
|
mfnCamera.horizontalFilmAperture() );
|
|
}
|
|
else
|
|
{
|
|
mSamp[0].setChannelValue(0, 1.0);
|
|
mSamp[0].setChannelValue(1, 1.0);
|
|
mSamp[1].setChannelValue(0, 0.0);
|
|
mSamp[1].setChannelValue(1, 0.0);
|
|
}
|
|
filmBackIndex = 2;
|
|
}
|
|
break;
|
|
|
|
case MFnCamera::kVerticalFilmFit:
|
|
{
|
|
if (1.0/mSamp.getLensSqueezeRatio() > 1.0)
|
|
{
|
|
mSamp[0].setChannelValue(0, 1.0/mSamp.getLensSqueezeRatio());
|
|
mSamp[0].setChannelValue(1, 1.0);
|
|
mSamp[1].setChannelValue(0, 2.0 *
|
|
mfnCamera.filmFitOffset() /
|
|
mfnCamera.horizontalFilmAperture() );
|
|
mSamp[1].setChannelValue(1, 0.0);
|
|
}
|
|
else
|
|
{
|
|
mSamp[0].setChannelValue(0, 1.0);
|
|
mSamp[0].setChannelValue(1, 1.0);
|
|
mSamp[1].setChannelValue(0, 0.0);
|
|
mSamp[1].setChannelValue(1, 0.0);
|
|
}
|
|
filmBackIndex = 2;
|
|
}
|
|
break;
|
|
|
|
case MFnCamera::kOverscanFilmFit:
|
|
{
|
|
if (mSamp.getLensSqueezeRatio() < 1.0)
|
|
{
|
|
mSamp[0].setChannelValue(0, 1.0);
|
|
mSamp[0].setChannelValue(1, mSamp.getLensSqueezeRatio());
|
|
}
|
|
else
|
|
{
|
|
mSamp[0].setChannelValue(0, 1.0/mSamp.getLensSqueezeRatio());
|
|
mSamp[0].setChannelValue(1, 1.0);
|
|
}
|
|
filmBackIndex = 1;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
mSamp[filmBackIndex].setChannelValue(0, 1.0/mfnCamera.preScale());
|
|
mSamp[filmBackIndex].setChannelValue(1, 1.0/mfnCamera.preScale());
|
|
|
|
mSamp[filmBackIndex+1].setChannelValue(0, mfnCamera.filmTranslateH());
|
|
mSamp[filmBackIndex+1].setChannelValue(1, mfnCamera.filmTranslateV());
|
|
|
|
mSamp[filmBackIndex+2].setChannelValue(0, 1.0/mfnCamera.postScale());
|
|
mSamp[filmBackIndex+2].setChannelValue(1, 1.0/mfnCamera.postScale());
|
|
|
|
mSamp[filmBackIndex+3].setChannelValue(0, mfnCamera.cameraScale());
|
|
mSamp[filmBackIndex+3].setChannelValue(1, mfnCamera.cameraScale());
|
|
|
|
mSchema.set(mSamp);
|
|
}
|
|
|
|
bool MayaCameraWriter::isAnimated() const
|
|
{
|
|
return mIsAnimated || (mAttrs != NULL && mAttrs->isAnimated());
|
|
}
|