//-***************************************************************************** // // 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()); }