MayaPluginForSpreticle/spReticleLoc.cpp

MayaPluginForSpreticle/spReticleLoc.cpp
//
// Copyright (c) 2009, Sony Pictures Imageworks
// 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 the
// names of its 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.
//
/*
* @file spReticleLoc.cpp
* This plug-in creates a custom locator to display a customizable reticle.
* The reticle has the ability to display any number of aspect ratios as
* well as pan-and-scan, projection masks, filmback data, etc. The look of
* the reticle is customizable in regards to color and transparency for
* masks, lines and text.There is also an option to specify whether the
* reticle should respect the show/hide locator display options. Finally,
* the reticle can be filtered to only display on cameras which contain
* the attribute useSpReticle, set to true.
*/
#include <stdio.h>
#include <maya/MString.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MFnPlugin.h>
#include <maya/MViewport2Renderer.h>
#include <maya/MItDag.h>
#include <maya/MUintArray.h>
#include <maya/MPointArray.h>
// Viewport 2.0 includes
#include <maya/MDrawRegistry.h>
#include <maya/MPxDrawOverride.h>
#include "spReticleLoc.h"
#define McheckStatus(stat,msg) \
if (!stat) { \
stat.perror(msg); \
return stat; \
}
#define McheckVoid(stat,msg) \
if (!stat) { \
stat.perror(msg); \
return; \
}
MTypeId spReticleLoc::id( 0x00000502 );
MString spReticleLoc::drawDbClassification("drawdb/geometry/spReticleLoc");
MString spReticleLoc::drawRegistrantId("spReticleLocPlugin");
MObject spReticleLoc::DrawingEnabled;
MObject spReticleLoc::EnableTextDrawing;
MObject spReticleLoc::FilmbackAperture;
MObject spReticleLoc::HorizontalFilmAperture;
MObject spReticleLoc::VerticalFilmAperture;
MObject spReticleLoc::SoundTrackWidth;
MObject spReticleLoc::DisplayFilmGate;
MObject spReticleLoc::ProjectionGate;
MObject spReticleLoc::HorizontalProjectionGate;
MObject spReticleLoc::VerticalProjectionGate;
MObject spReticleLoc::DisplayProjectionGate;
MObject spReticleLoc::SafeAction;
MObject spReticleLoc::HorizontalSafeAction;
MObject spReticleLoc::VerticalSafeAction;
MObject spReticleLoc::DisplaySafeAction;
MObject spReticleLoc::SafeTitle;
MObject spReticleLoc::HorizontalSafeTitle;
MObject spReticleLoc::VerticalSafeTitle;
MObject spReticleLoc::DisplaySafeTitle;
MObject spReticleLoc::AspectRatios;
MObject spReticleLoc::AspectRatio;
MObject spReticleLoc::DisplayMode;
MObject spReticleLoc::AspectMaskColor;
MObject spReticleLoc::AspectMaskTrans;
MObject spReticleLoc::AspectLineColor;
MObject spReticleLoc::AspectLineTrans;
MObject spReticleLoc::AspectDisplaySafeAction;
MObject spReticleLoc::AspectDisplaySafeTitle;
MObject spReticleLoc::PanScanAttr;
MObject spReticleLoc::PanScanAspectRatio;
MObject spReticleLoc::PanScanDisplayMode;
MObject spReticleLoc::PanScanDisplaySafeTitle;
MObject spReticleLoc::PanScanDisplaySafeAction;
MObject spReticleLoc::PanScanRatio;
MObject spReticleLoc::PanScanOffset;
MObject spReticleLoc::PanScanMaskColor;
MObject spReticleLoc::PanScanMaskTrans;
MObject spReticleLoc::PanScanLineColor;
MObject spReticleLoc::PanScanLineTrans;
MObject spReticleLoc::FilmGateColor;
MObject spReticleLoc::FilmGateTrans;
MObject spReticleLoc::ProjGateColor;
MObject spReticleLoc::ProjGateTrans;
MObject spReticleLoc::HideLocator;
MObject spReticleLoc::UseSpReticle;
MObject spReticleLoc::DisplayLineH;
MObject spReticleLoc::DisplayLineV;
MObject spReticleLoc::DisplayThirdsH;
MObject spReticleLoc::DisplayThirdsV;
MObject spReticleLoc::DisplayCrosshair;
MObject spReticleLoc::MiscTextColor;
MObject spReticleLoc::MiscTextTrans;
MObject spReticleLoc::LineColor;
MObject spReticleLoc::LineTrans;
MObject spReticleLoc::Time;
MObject spReticleLoc::DriveCameraAperture;
MObject spReticleLoc::MaximumDistance;
MObject spReticleLoc::UseOverscan;
MObject spReticleLoc::Pad;
MObject spReticleLoc::UsePad;
MObject spReticleLoc::PadAmount;
MObject spReticleLoc::PadAmountX;
MObject spReticleLoc::PadAmountY;
MObject spReticleLoc::PadDisplayMode;
MObject spReticleLoc::PadMaskColor;
MObject spReticleLoc::PadMaskTrans;
MObject spReticleLoc::PadLineColor;
MObject spReticleLoc::PadLineTrans;
MObject spReticleLoc::Text;
MObject spReticleLoc::TextType;
MObject spReticleLoc::TextStr;
MObject spReticleLoc::TextAlign;
MObject spReticleLoc::TextPos;
MObject spReticleLoc::TextPosX;
MObject spReticleLoc::TextPosY;
MObject spReticleLoc::TextPosRel;
MObject spReticleLoc::TextLevel;
MObject spReticleLoc::TextARLevel;
MObject spReticleLoc::TextColor;
MObject spReticleLoc::TextTrans;
MObject spReticleLoc::Tag;
spReticleLoc::spReticleLoc() {}
spReticleLoc::~spReticleLoc() {}
// This function takes in a screen x and y value and converts it to values
// on the near and far clipping planes.
//
MPoint spReticleLoc::getPoint( float x, float y, M3dView & view, MMatrix& wim )
{
MPoint p, ncp, fcp;
view.viewToWorld(short(x), short(y), ncp, fcp);
MVector v = fcp - ncp;
v.normalize();
p = (ncp + v) * wim;
return p;
}
// This method will retrieve the individual r,g,b and alpha values from
// various plugs and store them in an MColor object.
//
MStatus spReticleLoc::getColor(MObject colorObj, MObject transObj, MColor & color)
{
MPlug p,c;
MStatus stat;
p = MPlug( thisNode, colorObj );
// Get red
c = p.child(0, &stat);
McheckStatus (stat, ("spReticleLoc::getColor getting red plug from "+p.name() ) );
McheckStatus ( c.getValue ( color.r ), ("spReticleLoc::getColor getting red from "+p.name() ) );
// Get green
c = p.child(1,&stat);
McheckStatus (stat, ("spReticleLoc::getColor getting green plug from "+p.name() ) );
McheckStatus ( c.getValue ( color.g ), ("spReticleLoc::getColor getting green from "+p.name() ) );
// Get blue
c = p.child(2, &stat);
McheckStatus (stat, ("spReticleLoc::getColor getting blue plug from "+p.name() ) );
McheckStatus ( c.getValue ( color.b ), ("spReticleLoc::getColor getting blue from "+p.name() ) );
p = MPlug( thisNode, transObj );
McheckStatus ( p.getValue ( color.a ), ("spReticleLoc::getColor gettings transparency from "+p.name() ) );
return MS::kSuccess;
}
//This method returns the specified matrix.
//
MMatrix spReticleLoc::getMatrix( MString matrixStr )
{
MStatus stat;
MMatrix matrix;
// Extract the matrix attribute that is inherited from 'dagNode'
MFnDependencyNode fnThisNode( thisNode );
MObject matrixAttribute = fnThisNode.attribute( matrixStr, &stat );
if (!stat)
{
stat.perror("spReticleLoc::getMatrix getting attribute : "+matrixStr);
return matrix.identity;
}
MPlug matrixPlug( thisNode, matrixAttribute);
if (matrixPlug.isNull())
{
stat.perror("spReticleLoc::getting plug for attribute : "+matrixStr);
return matrix.identity;
}
// If matrix is an array so we must specify which element the plug refers to
if (matrixPlug.isArray())
{
matrixPlug = matrixPlug.elementByLogicalIndex (0, &stat);
if (!stat)
{
stat.perror("spReticleLoc::getMatrix setting logical index to 0 for "+matrixStr);
return matrix.identity;
}
}
// Get the value of the matrix attribute
MObject matObject;
stat = matrixPlug.getValue(matObject);
if (!stat)
{
stat.perror("spReticleLoc::getMatrix getting value for "+matrixStr);
return matrix.identity;
}
MFnMatrixData matrixData(matObject, &stat);
if (!stat)
{
stat.perror("spReticleLoc::getMatrix getting MfnMatrixData");
return matrix.identity;
}
matrix = matrixData.matrix( &stat );
if (!stat)
{
stat.perror("spReticleLoc::getMatrix getting matrix");
return matrix.identity;
}
return matrix;
}
// This method outputs to cerr the attributes of an Aspect_Ratio
// class instance.
//
void spReticleLoc::printAspectRatio(Aspect_Ratio & ar)
{
cerr << "-------------------------------------------------" << endl;
cerr << "aspect ratio : " << ar.aspectRatio << endl;
cerr << "displayMode : " << ar.displayMode << endl;
cerr << "maskColor : " << ar.aspectGeom.maskColor << endl;
cerr << "lineColor : " << ar.aspectGeom.lineColor << endl;
}
// This method outputs to cerr the attributes of an PanScan class instance.
//
void spReticleLoc::printPanScan(PanScan & ps)
{
printAspectRatio( ps );
cerr << "panScanRatio : " << ps.panScanRatio << endl;
cerr << "panScanOffset : " << ps.panScanOffset << endl;
cerr << "displaySafeTitle : " << ps.displaySafeTitle << endl;
cerr << "displaySafeAction : " << ps.displaySafeAction << endl;
}
// This method outputs to cerr the attributes of an TextData class instance.
//
void spReticleLoc::printText(TextData & td)
{
cerr << "-------------------------------------------------" << endl;
cerr << "text type : " << td.textType << endl;
cerr << "text string : " << td.textStr << endl;
cerr << "text align : " << td.textAlign << endl;
cerr << "text pos : " << td.textPosX << ", " << td.textPosY << endl;
cerr << "text pos rel : " << td.textPosRel << endl;
cerr << "text level : " << td.textLevel << endl;
cerr << "text ar level : " << td.textARLevel << endl;
}
// This method outputs to cerr the attributes of an Geom class instance.
//
void spReticleLoc::printGeom(Geom & g)
{
cerr << "-------------------------------------------------" << endl;
cerr << "x : " << g.x << endl;
cerr << "y : " << g.y << endl;
cerr << "x1 : " << g.x1 << endl;
cerr << "x2 : " << g.x2 << endl;
cerr << "y1 : " << g.y1 << endl;
cerr << "y2 : " << g.y2 << endl;
cerr << "mc : " << g.maskColor << endl;
cerr << "lc : " << g.lineColor << endl;
cerr << "iv : " << g.isValid << endl;
}
// This method outputs to cerr the various options that have been specified.
//
void spReticleLoc::printOptions(Options& opt)
{
cerr << "-------------------------------------------------" << endl;
cerr << "useSpRet : " << opt.useSpRet << endl;
cerr << "displayLineH : " << opt.displayLineH << endl;
cerr << "displayLineV : " << opt.displayLineV << endl;
cerr << "displayThirdsH : " << opt.displayThirdsH << endl;
cerr << "displayThirdsV : " << opt.displayThirdsV << endl;
cerr << "displayCrosshair : " << opt.displayCrosshair << endl;
cerr << "driveCameraAperture : " << opt.driveCameraAperture << endl;
cerr << "maximumDistance : " << opt.maximumDistance << endl;
cerr << "useOverscan : " << opt.useOverscan << endl;
}
// This method gets the pad data.
//
MStatus spReticleLoc::getPadData( spReticleLocData& drawData )
{
MPlug p;
MStatus stat;
// Get the pad attribute;
p = MPlug ( thisNode, UsePad );
McheckStatus ( p.getValue ( drawData.pad.usePad ), "spReticleLoc::getPadData pad");
// Get the padAmountX attribute;
p = MPlug ( thisNode, PadAmountX );
McheckStatus ( p.getValue ( drawData.pad.padAmountX ), "spReticleLoc::getPadData padAmountX");
// Get the padAmountY attribute;
p = MPlug ( thisNode, PadAmountY );
McheckStatus ( p.getValue ( drawData.pad.padAmountY ), "spReticleLoc::getPadData padAmountX");
// Set whether the filmback is padded
drawData.pad.isPadded = (drawData.pad.padAmountX != 0 && drawData.pad.padAmountY != 0);
if (drawData.pad.usePad && drawData.pad.isPadded)
{
// Get the pad display mode
p = MPlug ( thisNode, PadDisplayMode );
McheckStatus ( p.getValue ( drawData.pad.displayMode ), "spReticleLoc::getPadData padDisplayMode");
// Get the pad mask color
stat = getColor( PadMaskColor, PadMaskTrans, drawData.pad.padGeom.maskColor );
McheckStatus ( stat, "spReticleLoc::getPadData get padMaskColor");
// Get the pad line color
stat = getColor(PadLineColor, PadLineTrans, drawData.pad.padGeom.lineColor );
McheckStatus ( stat, "spReticleLoc::getPadData get padLineColor");
}
return MS::kSuccess;
}
// This method retrieves all of the data related to the filmback from
// various plugs.
//
MStatus spReticleLoc::getFilmbackData( spReticleLocData& drawData )
{
MPlug p;
MStatus stat;
//Get horizontal film aperture
p = MPlug( thisNode, HorizontalFilmAperture );
McheckStatus ( p.getValue ( drawData.filmback.horizontalFilmAperture ), "spReticleLoc::getFilmbackData get horizontalFilmAperture");
//Get vertical film aperture
p = MPlug( thisNode, VerticalFilmAperture );
McheckStatus ( p.getValue ( drawData.filmback.verticalFilmAperture ), "spReticleLoc::getFilmbackData get verticalFilmAperture");
//Get vertical film aperture
p = MPlug( thisNode, SoundTrackWidth );
McheckStatus ( p.getValue ( drawData.filmback.soundTrackWidth ), "spReticleLoc::getFilmbackData get soundTrackWidth");
//Get whether to display the film gate
p = MPlug( thisNode,DisplayFilmGate );
McheckStatus ( p.getValue ( drawData.filmback.displayFilmGate ), "spReticleLoc::getFilmbackData get displayFilmGate");
//Get the filmback line color
stat = getColor( FilmGateColor,FilmGateTrans, drawData.filmback.filmbackGeom.lineColor );
McheckStatus ( stat, "spReticleLoc::getFilmbackData get filmGateColor");
return MS::kSuccess;
}
// This method retrieves all of the data related to the projection mask from
// various plugs and then calls calcProjGeom to calculate the various
// projection geometry instances.
//
MStatus spReticleLoc::getProjectionData( spReticleLocData& drawData )
{
MPlug p;
MStatus stat;
//Get whether to display the projection gate
p = MPlug( thisNode, DisplayProjectionGate );
McheckStatus ( p.getValue ( drawData.filmback.displayProjGate ), "spReticleLoc::getProjectionData get displayProjectionGate");
if ( drawData.filmback.displayProjGate )
{
//Get horizontal projection gate
p = MPlug( thisNode, HorizontalProjectionGate );
McheckStatus ( p.getValue ( drawData.filmback.horizontalProjectionGate ), "spReticleLoc::getProjectionData get horizontalProjectionGate");
//Get vertical projection gate
p = MPlug( thisNode, VerticalProjectionGate );
McheckStatus ( p.getValue ( drawData.filmback.verticalProjectionGate ), "spReticleLoc::getProjectionData get verticalProjectionGate");
//Get the projection gate line color
stat = getColor( ProjGateColor, ProjGateTrans, drawData.filmback.projGeom.lineColor );
McheckStatus ( stat, "spReticleLoc::getProjectionData get projGateColor");
}
return MS::kSuccess;
}
// This method returns the data related to the filmback's safe action area.
//
MStatus spReticleLoc::getSafeActionData( spReticleLocData& drawData )
{
MPlug p;
//Get whether to display safe action
p = MPlug( thisNode,DisplaySafeAction );
McheckStatus ( p.getValue ( drawData.filmback.displaySafeAction ), "spReticleLoc::getSafeActionData get displaySafeAction");
//Get horizontal safe action
p = MPlug( thisNode, HorizontalSafeAction );
McheckStatus ( p.getValue ( drawData.filmback.horizontalSafeAction ), "spReticleLoc::getSafeActionData get horizontalSafeAction");
//Get vertical safe action
p = MPlug( thisNode,VerticalSafeAction );
McheckStatus ( p.getValue ( drawData.filmback.verticalSafeAction ), "spReticleLoc::getSafeActionData get verticalSafeAction");
//Set the safe action line color to the filmback line color
drawData.filmback.safeActionGeom.lineColor = drawData.filmback.filmbackGeom.lineColor;
return MS::kSuccess;
}
// This method returns the data relating to the filmback's safe title area.
//
MStatus spReticleLoc::getSafeTitleData( spReticleLocData& drawData )
{
MPlug p;
//Get whether to display safe title
p = MPlug( thisNode, DisplaySafeTitle );
McheckStatus ( p.getValue ( drawData.filmback.displaySafeTitle ), "spReticleLoc::getSafeTitleData get displaySafeTitle");
//Get horizontal safe title
p = MPlug( thisNode, HorizontalSafeTitle );
McheckStatus ( p.getValue ( drawData.filmback.horizontalSafeTitle ), "spReticleLoc::getSafeTitleData get horizontalSafeTitle");
//Get vertical safe title
p = MPlug( thisNode, VerticalSafeTitle );
McheckStatus ( p.getValue ( drawData.filmback.verticalSafeTitle ), "spReticleLoc::getSafeTitleData get verticalSafeTitle");
//Set the safe title line color to the filmback line color
drawData.filmback.safeTitleGeom.lineColor = drawData.filmback.filmbackGeom.lineColor;
return MS::kSuccess;
}
// This method gets the data for a specified aspect ratio. The aspectratios
// attribute is effectively a complex compound attribute where each index
// is the data for a specific aspect ratio.
//
MStatus spReticleLoc::getAspectRatioChildren(MPlug arPlug, Aspect_Ratio & ar)
{
MStatus stat;
MPlug p, c;
p = arPlug.child( 0 , &stat );
McheckStatus( p.getValue( ar.aspectRatio ), "spReticleLoc::getAspectRatioChildren - aspectRatio" );
p = arPlug.child( 1 , &stat );
McheckStatus( p.getValue( ar.displayMode ), "spReticleLoc::getAspectRatioChildren - displayMode" );
if (ar.displayMode != 0)
{
p = arPlug.child( 2 , &stat );
c = p.child( 0, &stat );
McheckStatus( c.getValue( ar.aspectGeom.maskColor.r ), "spReticleLoc::getAspectRatioChildren - aspectMaskColorR" );
c = p.child( 1, &stat );
McheckStatus( c.getValue( ar.aspectGeom.maskColor.g ), "spReticleLoc::getAspectRatioChildren - aspectMaskColorG" );
c = p.child( 2, &stat );
McheckStatus( c.getValue( ar.aspectGeom.maskColor.b ), "spReticleLoc::getAspectRatioChildren - aspectMaskColorB" );
p = arPlug.child( 3 , &stat );
McheckStatus( p.getValue( ar.aspectGeom.maskColor.a ), "spReticleLoc::getAspectRatioChildren - aspectMaskTrans" );
p = arPlug.child( 4 , &stat );
c = p.child( 0, &stat );
McheckStatus( c.getValue( ar.aspectGeom.lineColor.r ), "spReticleLoc::getAspectRatioChildren - aspectLineColorR" );
c = p.child( 1, &stat );
McheckStatus( c.getValue( ar.aspectGeom.lineColor.g ), "spReticleLoc::getAspectRatioChildren - aspectLineColorG" );
c = p.child( 2, &stat );
McheckStatus( c.getValue( ar.aspectGeom.lineColor.b ), "spReticleLoc::getAspectRatioChildren - aspectLineColorB" );
p = arPlug.child( 5 , &stat );
McheckStatus( p.getValue( ar.aspectGeom.lineColor.a ), "spReticleLoc::getAspectRatioChildren - aspectLineTrans" );
p = arPlug.child( 6 , &stat );
McheckStatus( p.getValue( ar.displaySafeAction ), "spReticleLoc::getAspectRatioChildren - displaySafeAction" );
p = arPlug.child( 7 , &stat );
McheckStatus( p.getValue( ar.displaySafeTitle ), "spReticleLoc::getAspectRatioChildren - displaySafeTitle" );
}
return MS::kSuccess;
}
bool spReticleLoc::aspectRatioSortPredicate(const Aspect_Ratio & lhs,
const Aspect_Ratio & rhs)
{
return lhs.aspectRatio < rhs.aspectRatio;
}
// This retrieves the data for all of the various aspect ratios.
//
MStatus spReticleLoc::getAspectRatioData( spReticleLocData& drawData )
{
// Get the aspectRatios data
MPlug arsPlug = MPlug( thisNode, AspectRatios );
int numPlugs = arsPlug.numElements();
MStatus stat;
// Clear the aspect ratio vector
drawData.ars.clear();
for (int i = 0; i < numPlugs; i++)
{
MPlug p = arsPlug.elementByPhysicalIndex( i, &stat );
McheckStatus( stat, "spReticleLoc::getAspectRatioData - cannot get index" );
Aspect_Ratio ar;
stat = getAspectRatioChildren( p, ar );
McheckStatus( stat, "spReticleLoc::getAspectRatioData - cannot get children" );
//printAspectRatio( ar );
drawData.ars.push_back( ar );
}
drawData.numAspectRatios = (int)drawData.ars.size();
// Sort aspect ratios
std::sort(drawData.ars.begin(),drawData.ars.end(),aspectRatioSortPredicate);
return MS::kSuccess;
}
bool spReticleLoc::needToUpdateAspectRatios( spReticleLocData& drawData )
{
MPlug arsPlug = MPlug( thisNode, AspectRatios );
return (drawData.ars.size() != arsPlug.numElements() );
}
// This method gets the data for a PanScan class instance.
//
MStatus spReticleLoc::getPanScanData( PanScan & ps )
{
MPlug psPlug( thisNode, PanScanAttr );
MStatus stat = getAspectRatioChildren( psPlug, ps );
McheckStatus( stat, "spReticleLoc::getPanScanData - cannot get children" );
if (ps.displayMode != 0)
{
MPlug p;
p = psPlug.child( 8 , &stat );
McheckStatus( p.getValue( ps.panScanRatio ), "spReticleLoc::getPanScanData - panScanRatio" );
p = psPlug.child( 9 , &stat );
McheckStatus( p.getValue( ps.panScanOffset ), "spReticleLoc::getPanScanData - panScanOffset" );
}
//printPanScan( ps );
return MS::kSuccess;
}
// This method gets the data for a specified text entry. The text attribute
// is a complex compound attribute where each index is the data for a specific
// text element.
//
MStatus spReticleLoc::getTextChildren(MPlug tPlug, TextData & td)
{
MStatus stat;
MPlug p, c;
p = tPlug.child( 0 , &stat );
McheckStatus( p.getValue( td.textType ), "spReticleLoc::getTextChildren - textType" );
p = tPlug.child( 1 , &stat );
McheckStatus( p.getValue( td.textStr ), "spReticleLoc::getTextChildren - textStr" );
p = tPlug.child( 2 , &stat );
McheckStatus( p.getValue( td.textAlign ), "spReticleLoc::getTextChildren - textAlign" );
p = tPlug.child( 3 , &stat );
c = p.child( 0, &stat );
McheckStatus( c.getValue( td.textPosX ), "spReticleLoc::getTextChildren - textPosX" );
c = p.child( 1, &stat );
McheckStatus( c.getValue( td.textPosY ), "spReticleLoc::getTextChildren - textPosY" );
p = tPlug.child( 4 , &stat );
McheckStatus( p.getValue( td.textPosRel ), "spReticleLoc::getTextChildren - textPosRel" );
p = tPlug.child( 5 , &stat );
McheckStatus( p.getValue( td.textLevel ), "spReticleLoc::getTextChildren - textLevel" );
p = tPlug.child( 6 , &stat );
McheckStatus( p.getValue( td.textARLevel ), "spReticleLoc::getTextChildren - textARLevel" );
p = tPlug.child( 7 , &stat );
c = p.child( 0, &stat );
McheckStatus( c.getValue( td.textColor.r ), "spReticleLoc::getTextChildren - textColorR" );
c = p.child( 1, &stat );
McheckStatus( c.getValue( td.textColor.g ), "spReticleLoc::getTextChildren - textColorG" );
c = p.child( 2, &stat );
McheckStatus( c.getValue( td.textColor.b ), "spReticleLoc::getTextChildren - textColorB" );
p = tPlug.child( 8 , &stat );
McheckStatus( p.getValue( td.textColor.a ), "spReticleLoc::getTextChildren - textTrans" );
return MS::kSuccess;
}
MStatus spReticleLoc::getTextData( spReticleLocData& drawData )
{
// Clear the text vector
drawData.text.clear();
MStatus stat;
MPlug p,tp,cp;
p = MPlug( thisNode, Text );
int numPlugs = p.numElements();
for (int i = 0; i < numPlugs && i < 10; i++ )
{
TextData td;
tp = p.elementByPhysicalIndex( i, &stat );
McheckStatus( stat, "spReticleLoc::getTextData - cannot get index" );
stat = getTextChildren( tp, td );
McheckStatus( stat, "spReticleLoc::getTextData - cannot get children" );
//printText( td );
drawData.text.push_back( td );
}
return MS::kSuccess;
}
void spReticleLoc::getCustomTextElement(spReticleLocData& drawData)
{
TextData td;
char buff[255];
double maximumDist = drawData.maximumDist ;
Options options = drawData.options ;
Camera cameraData = drawData.cameraData ;
int numAspectRatios = drawData.numAspectRatios ;
Geom portGeom = drawData.portGeom ;
std::vector<TextData> text = drawData.text ;
std::vector<Aspect_Ratio> ars = drawData.ars ;
PadOptions pad = drawData.pad ;
Filmback filmback = drawData.filmback ;
PanScan panScan = drawData.panScan ;
MString nodeName = drawData.nodeName ;
drawData.textWhenDraw.clear();
MFnCamera camera;
camera.setObject(cameraData.cameraPath);
for (int i = 0; i < (int)text.size(); i++)
{
td = text[i];
MColor textColor = options.textColor;
switch (td.textType)
{
case 0: //String
break;
case 1: //Lens
if (td.textStr == "")
td.textStr = MString("%1.2f mm");
sprintf(buff,td.textStr.asChar(),camera.focalLength() );
td.textStr = MString(buff);
break;
case 2: //Camera
if (td.textStr == "")
td.textStr = camera.name();
else
{
sprintf(buff,td.textStr.asChar(),camera.name().asChar() );
td.textStr = MString(buff);
}
break;
case 3: //Frame
{
MTime time;
MPlug p = MPlug ( thisNode, Time );
if (p.isNull() == false && p.isConnected() == false)
{
MString cmd = "connectAttr time1.o "+p.name();
}
McheckVoid ( p.getValue ( time ), "spReticleLoc::drawCustomTextElements get time");
if (td.textStr == "")
td.textStr = MString("%04.0f");
sprintf(buff,td.textStr.asChar(),time.value() );
td.textStr = MString(buff);
break;
}
case 4: //Aspect Ratio
{
int level = td.textARLevel;
if (level < 0 || level >= numAspectRatios)
{
MGlobal::displayError( nodeName + " invalid text level (" + level + ") for text item " + i);
continue;
}
if (td.textStr == "")
td.textStr = MString("%1.3f");
sprintf(buff,td.textStr.asChar(),ars[level].aspectRatio );
td.textStr = MString(buff);
break;
}
case 5: //Maximum Distance
if (options.maximumDistance <= 0)
continue;
if (td.textStr == "")
td.textStr = MString("max. dist %1.0f");
textColor = (maximumDist >= options.maximumDistance) ? MColor(1,1,1,0) : textColor;
sprintf(buff, td.textStr.asChar(), maximumDist );
td.textStr = MString(buff);
break;
case 6: //Projection Gate
{
if (!filmback.displayProjGate)
continue;
double aspectRatio = (filmback.horizontalProjectionGate/filmback.verticalProjectionGate);
if (td.textStr == "")
td.textStr = MString("%1.3f");
sprintf(buff, td.textStr.asChar(), aspectRatio);
td.textStr = MString(buff);
break;
}
case 7: //Show
{
if (td.textStr == "")
td.textStr = MString("%s");
sprintf(buff, td.textStr.asChar(), getenv("SHOW"));
td.textStr = MString(buff);
break;
}
case 8: //Show
{
if (td.textStr == "")
td.textStr = MString("%s");
sprintf(buff, td.textStr.asChar(), getenv("SHOT"));
td.textStr = MString(buff);
break;
}
case 9: //Show/Shot
{
if (td.textStr == "")
td.textStr = MString("%s/%s");
sprintf(buff, td.textStr.asChar(), getenv("SHOW"),getenv("SHOT"));
td.textStr = MString(buff);
break;
}
case 10: //Frame Start
{
if (td.textStr == "")
td.textStr = MString("%s");
sprintf(buff, td.textStr.asChar(), getenv("FS"));
td.textStr = MString(buff);
break;
}
case 11: //Frame End
{
if (td.textStr == "")
td.textStr = MString("%s");
sprintf(buff, td.textStr.asChar(), getenv("FE"));
td.textStr = MString(buff);
break;
}
case 12: //Frame Range
{
if (td.textStr == "")
td.textStr = MString("%s-%s");
sprintf(buff, td.textStr.asChar(), getenv("FS"), getenv("FE"));
td.textStr = MString(buff);
break;
}
case 13: //User
{
if (td.textStr == "")
td.textStr = MString("%s");
sprintf(buff, td.textStr.asChar(), getenv("USER"));
td.textStr = MString(buff);
break;
}
case 14: //Current File
{
if (td.textStr == "")
td.textStr = MString("%s");
sprintf(buff, td.textStr.asChar(), MFileIO::currentFile().asChar() );
td.textStr = MString(buff);
break;
}
case 15: //Path
{
if (td.textStr == "")
td.textStr = MString("%s");
sprintf(buff, td.textStr.asChar(), fo.path().asChar() );
td.textStr = MString(buff);
break;
}
case 16: //Path
{
if (td.textStr == "")
td.textStr = MString("%s");
sprintf(buff, td.textStr.asChar(), fo.name().asChar() );
td.textStr = MString(buff);
break;
}
case 17: //Pan Scan Aspect Ratio
if (td.textStr == "")
td.textStr = MString("%1.2f");
sprintf(buff, td.textStr.asChar(), panScan.panScanRatio );
td.textStr = MString(buff);
break;
case 18: //Pan Scan Offset
if (td.textStr == "")
td.textStr = MString("%1.2f");
sprintf(buff, td.textStr.asChar(), panScan.panScanOffset );
td.textStr = MString(buff);
break;
case 19: //Safe Action
if (td.textStr == "")
td.textStr = "safe action";
break;
case 20: //Safe Title
if (td.textStr == "")
td.textStr = "safe title";
break;
default:
MGlobal::displayError( nodeName + " invalid text type for text item " + i);
continue;
}
// Determine the level geometry
Geom g;
switch (td.textLevel)
{
case 0:
g = portGeom;
break;
case 1:
g = pad.padGeom;
break;
case 2:
{
switch (td.textType)
{
case 19:
if (!filmback.safeActionGeom.isValid)
drawData.calcFilmbackSafeActionGeom();
g = filmback.safeActionGeom;
break;
case 20:
if (!filmback.safeTitleGeom.isValid)
drawData.calcFilmbackSafeTitleGeom();
g = filmback.safeTitleGeom;
break;
default:
g = filmback.filmbackGeom;
break;
}
}
break;
case 3:
if (!filmback.displayProjGate)
{
MGlobal::displayError( nodeName + " cannot anchor text item " + i + " to undisplayed projection mask");
continue;
}
g = filmback.projGeom;
break;
case 4:
{
int level = td.textARLevel;
if (level < 0 || level >= numAspectRatios)
{
MGlobal::displayError( nodeName + " invalid aspect ratio level (" + td.textARLevel + ") for text item " + i);
continue;
}
if (!ars[level].aspectGeom.isValid)
continue;
switch (td.textType)
{
case 19:
if (!ars[level].safeActionGeom.isValid)
drawData.calcSafeActionGeom(ars[level]);
g = ars[level].safeActionGeom;
break;
case 20:
if (!ars[level].safeTitleGeom.isValid)
drawData.calcSafeTitleGeom(ars[level]);
g = ars[level].safeTitleGeom;
break;
default:
g = ars[level].aspectGeom;
break;
}
}
break;
case 5:
{
if (!panScan.aspectGeom.isValid)
drawData.calcPanScanGeom( panScan );
switch (td.textType)
{
case 19:
if (!panScan.safeActionGeom.isValid)
drawData.calcSafeActionGeom(panScan);
g = panScan.safeActionGeom;
break;
case 20:
if (!panScan.safeTitleGeom.isValid)
drawData.calcSafeTitleGeom(panScan);
g = panScan.safeTitleGeom;
break;
default:
g = panScan.aspectGeom;
break;
}
}
break;
default:
MGlobal::displayError( nodeName + " invalid text anchor for text item " + i);
break;
}
// Determine the position
double x,y;
switch (td.textPosRel)
{
case 0: //Bottom Left
x = g.x1;
y = g.y1;
break;
case 1: //Bottom Center
x = (g.x1 + g.x2 ) / 2;
y = g.y1;
break;
case 2: //Bottom Right
x = g.x2;
y = g.y1;
break;
case 3: //Middle Left
x = g.x1;
y = (g.y1 + g.y2 ) / 2;
break;
case 4: //Center
x = (g.x1 + g.x2 ) / 2;
y = (g.y1 + g.y2 ) / 2;
break;
case 5: //Middle Right
x = g.x2;
y = (g.y1 + g.y2 ) / 2;
break;
case 6: //Top Left
x = g.x1;
y = g.y2;
break;
case 7: //Top Center
x = (g.x1 + g.x2 ) / 2;
y = g.y2;
break;
case 8: //Top Right
x = g.x2;
y = g.y2;
break;
default:
MGlobal::displayError( nodeName + " invalid text relative position (" + td.textPosRel + ") for text item " + i);
continue;
}
// Add text position as offset
x += td.textPosX;
y += td.textPosY;
TextData newTd = td;
newTd.textPosX = x;
newTd.textPosY = y;
drawData.textWhenDraw.push_back(newTd);
}
}
bool spReticleLoc::needToUpdateTextData( spReticleLocData& drawData )
{
MPlug p = MPlug( thisNode, Text );
return ( drawData.text.size() != p.numElements() );
}
// This method retrieves all of the options settings.
//
MStatus spReticleLoc::getOptions( Options& options )
{
MPlug p;
MStatus stat;
// Check to see if drawing is enabled
p = MPlug ( thisNode, DrawingEnabled );
McheckStatus ( p.getValue ( options.drawingEnabled ), "spReticleLoc::getOptions drawingEnabled" );
if (options.drawingEnabled)
{
// Check to see if the text should be rendered;
p = MPlug ( thisNode, EnableTextDrawing );
McheckStatus ( p.getValue( options.enableTextDrawing), "spReticleLoc::getOptions enableTextDrawing" );
// Check to see if locator should filter for useSpReticle attribute
// on the camera;
p = MPlug ( thisNode, UseSpReticle );
McheckStatus ( p.getValue ( options.useSpRet ), "spReticleLoc::getOptions useSpReticle");
// Display horizontal line option;
p = MPlug ( thisNode, DisplayLineH );
McheckStatus ( p.getValue ( options.displayLineH ), "spReticleLoc::getOptions displayLineH");
// Display vertical line option;
p = MPlug ( thisNode, DisplayLineV );
McheckStatus ( p.getValue ( options.displayLineV ), "spReticleLoc::getOptions displayLineV");
// Display horizontal thirds option;
p = MPlug ( thisNode, DisplayThirdsH );
McheckStatus ( p.getValue ( options.displayThirdsH ), "spReticleLoc::getOptions displayThirdsH");
// Display vertical thirds option;
p = MPlug ( thisNode, DisplayThirdsV );
McheckStatus ( p.getValue ( options.displayThirdsV ), "spReticleLoc::getOptions displayThirdsV");
// Display crosshair option;
p = MPlug ( thisNode, DisplayCrosshair );
McheckStatus ( p.getValue ( options.displayCrosshair ), "spReticleLoc::getOptions displayCrosshair");
// Text Color;
stat = getColor (MiscTextColor, MiscTextTrans, options.textColor );
McheckStatus ( stat, "spReticleLoc::getOptions textColor");
// Line Color;
stat = getColor ( LineColor, LineTrans, options.lineColor );
McheckStatus ( stat, "spReticleLoc::getOptions lineColor");
// Get whether to drive a camera or not;
p = MPlug ( thisNode, DriveCameraAperture );
McheckStatus ( p.getValue ( options.driveCameraAperture ), "spReticleLoc::getOptions driveCameraAperture");
// Get the maximum distance attribute;
p = MPlug ( thisNode, MaximumDistance );
McheckStatus ( p.getValue ( options.maximumDistance ), "spReticleLoc::getOptions maximumDistance");
// Get whether to respect overscan or not;
p = MPlug ( thisNode, UseOverscan );
McheckStatus ( p.getValue ( options.useOverscan ), "spReticleLoc::getOptions useOverscan");
}
// Print the options to cerr
//printOptions(drawData.options);
return MS::kSuccess;
}
bool spReticleLoc::setInternalValueInContext(const MPlug & plug,
const MDataHandle & dataHandle, MDGContext & ctx)
{
if (plug == worldInverseMatrix || plug == isTemplated)
return false;
needRefresh = true;
return false;
}
// Given two Geom instances, this calculates the mask area between them.
//
void spReticleLoc::drawMask( Geom g1, Geom g2, MColor color, bool sides, double ncp )
{
double z = -ncp;
// Turn off z-depth test
glDisable( GL_DEPTH_TEST );
glDepthMask( GL_FALSE );
glBegin( GL_QUADS );
glColor4f( color.r, color.g, color.b, 1-color.a );
// Bottom Mask
glVertex3d( g1.x1, g1.y1, z );
glVertex3d( g1.x2, g1.y1, z );
glVertex3d( g2.x2, g2.y1, z );
glVertex3d( g2.x1, g2.y1, z );
// Top Mask
glVertex3d( g2.x1, g2.y2, z );
glVertex3d( g2.x2, g2.y2, z );
glVertex3d( g1.x2, g1.y2, z );
glVertex3d( g1.x1, g1.y2, z );
if (sides)
{
// Left side mask
glVertex3d( g1.x1, g1.y1, z );
glVertex3d( g2.x1, g2.y1, z );
glVertex3d( g2.x1, g2.y2, z );
glVertex3d( g1.x1, g1.y2, z );
// right side mask
glVertex3d( g2.x2, g2.y1, z );
glVertex3d( g1.x2, g1.y1, z );
glVertex3d( g1.x2, g1.y2, z );
glVertex3d( g2.x2, g2.y2, z );
}
glEnd();
// Turn on z-depth test
glDepthMask( GL_TRUE );
glEnable( GL_DEPTH_TEST );
}
// This draws a single line between the specified points.
//
void spReticleLoc::drawLine( double x1, double x2, double y1, double y2, MColor color, bool stipple, double ncp )
{
double z = -ncp;
// Turn off z-depth test
glDisable( GL_DEPTH_TEST );
glDepthMask( GL_FALSE );
if (stipple)
{
glEnable (GL_LINE_STIPPLE);
glLineStipple(2,0x00FF);
}
glBegin( GL_LINES );
glColor4f( color.r, color.g, color.b, 1-color.a );
glVertex3d( x1, y1, z );
glVertex3d( x2, y2, z );
glEnd();
if (stipple)
glDisable (GL_LINE_STIPPLE);
// Turn on z-depth test
glDepthMask( GL_TRUE );
glEnable( GL_DEPTH_TEST );
}
// Given a Geom instance, this will draw a line connecting the points.
// The argument side determines whether the sides will be drawn (the top
// will always be drawn). The stipple argument specifies whether the line
// should be solid or dashed/stippled.
//
void spReticleLoc::drawLines( Geom g, MColor color, bool sides, bool stipple, double ncp )
{
double z = -ncp;
//Turn off z-depth test
glDisable( GL_DEPTH_TEST );
glDepthMask( GL_FALSE );
if (stipple)
{
glEnable (GL_LINE_STIPPLE);
glLineStipple(2,0x00FF);
}
GLenum mode = ( sides ) ? GL_LINE_LOOP : GL_LINES;
glBegin( mode );
glColor4f( color.r, color.g, color.b, 1-color.a );
glVertex3d( g.x1, g.y1, z );
glVertex3d( g.x2, g.y1, z );
glVertex3d( g.x2, g.y2, z );
glVertex3d( g.x1, g.y2, z );
glEnd( );
if (stipple)
glDisable (GL_LINE_STIPPLE);
//Turn on z-depth test
glDepthMask( GL_TRUE );
glEnable( GL_DEPTH_TEST );
}
// This function uses Maya's built-in function to draw text. At somepoint
// I hope to use glut or glFT to draw text.
//
void spReticleLoc::drawText( MString text, double tx, double ty,
MColor textColor, M3dView::TextPosition textAlign,
M3dView & view, MMatrix wim )
{
// Turn off z-depth test
glDisable( GL_DEPTH_TEST );
glDepthMask( GL_FALSE );
MPoint textPos = getPoint((float)tx, (float)ty, view, wim);
glColor4f( textColor.r, textColor.g, textColor.b, 1-textColor.a );
view.drawText(text, textPos, textAlign);
glFlush(); // added by sjt@sjt.is (May 2010).
// Turn on z-depth test
glDepthMask( GL_TRUE );
glEnable( GL_DEPTH_TEST );
}
void spReticleLoc::drawCustomTextElements( std::vector<TextData> textWhenDraw, MMatrix wim, M3dView & view )
{
for(unsigned int i = 0; i < textWhenDraw.size(); ++i)
{
TextData td = textWhenDraw[i];
// Actually draw the text
drawText( td.textStr, td.textPosX, td.textPosY, td.textColor, (M3dView::TextPosition)td.textAlign, view, wim);
}
}
// This is the main function which draws the locator. It is called
// by Maya whenever a 3D view needs to be refreshed.
//
void spReticleLoc::draw(M3dView & view, const MDagPath & path,
{
// Get the dagPath, node and function set for the currently displaying camera
MDagPath cameraPath;
view.getCamera(cameraPath);
spReticleLocData drawData;
getDrawData(drawData,cameraPath,double(view.portHeight()),double(view.portWidth()));
// Drawing not enabled, return
if (!drawData.options.drawingEnabled)
return;
// If camera is orthographic, then return
if (drawData.cameraData.isOrtho)
return;
// If camera is not set to use reticle then return
if(drawData.options.useSpRet){
if (!drawData.useReticle)
return;
}
//get cached data
double ncp =drawData.ncp;
double maximumDist =drawData.maximumDist;
Options options =drawData.options;
MMatrix wim =drawData.wim;
int numAspectRatios =drawData.numAspectRatios;
Geom portGeom =drawData.portGeom;
std::vector<Aspect_Ratio> ars =drawData.ars;
PadOptions pad =drawData.pad;
Filmback filmback =drawData.filmback;
PanScan panScan =drawData.panScan;
std::vector<TextData> textWhenDraw =drawData.textWhenDraw;
//CameraData camera =drawDa
// Begin drawing locator
view.beginGL();
// Get current line settings
//glLineWidth(1);
// Store all of the openGL attribute settings
glPushAttrib( GL_ALL_ATTRIB_BITS );
// Go into 2D ortho mode
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glMatrixMode( GL_PROJECTION );
glPushMatrix();
glLoadIdentity();
glOrtho(
0.0, (GLdouble) view.portWidth(),
0.0, (GLdouble) view.portHeight(),
drawData.cameraData.nearClippingPlane, drawData.cameraData.farClippingPlane
//0.0, camera.farClippingPlane()
);
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
// Turn on openGL blending for transparency
glEnable(GL_BLEND);
// Store the current blend types
GLint blendAttrs[2];
glGetIntegerv(GL_BLEND_SRC, & blendAttrs[0]);
glGetIntegerv(GL_BLEND_DST, & blendAttrs[1]);
// Set the blending function
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// create variable to store what the first geometry object to draw aspect ratios to
Geom aspectContainerGeom;
// Draw the padGeomMask
if (pad.usePad && pad.isPadded)
{
if (pad.displayMode == 2)
drawMask(portGeom, pad.padGeom, pad.padGeom.maskColor, true, ncp);
aspectContainerGeom = pad.padGeom;
}
else
{
aspectContainerGeom = portGeom;
}
// Draw the masks first
Aspect_Ratio ar;
for (int i = 0; i < numAspectRatios; i++ )
{
ar = ars[i];
// Draw the masks as Quads
if (ar.displayMode == 2)
{
Geom g = (i == 0)?aspectContainerGeom:ars[i-1].aspectGeom;
MColor maskColor = ar.aspectGeom.maskColor;
// Draw the mask in red if over the max distance
if (options.maximumDistance > 0 &&
fabs(maximumDist) >= options.maximumDistance)
{
if (i == 0)
{
maskColor = MColor(1,0,0,maskColor.a);
}
else
{
maskColor *= MColor(1.5,0.5,0.5,1);
}
}
drawMask(g, ar.aspectGeom, maskColor, i == 0, ncp);
}
}
// Draw lines
for (int i = 0; i < numAspectRatios; i++ )
{
ar = ars[i];
if (ar.displayMode != 0)
{
bool sides = (i == 0 || ar.aspectGeom.x != ars[i].aspectGeom.x);
drawLines(ar.aspectGeom, ar.aspectGeom.lineColor, sides, 0, ncp);
// Draw safe action
if (ar.displaySafeAction)
drawLines( ar.safeActionGeom, ar.safeActionGeom.lineColor, 1, 1, ncp);
// Draw safe title
if (ar.displaySafeTitle)
drawLines( ar.safeTitleGeom, ar.safeTitleGeom.lineColor, 1, 1, ncp);
}
}
// Draw the panScan
if ( panScan.displayMode != 0 )
{
if (panScan.displayMode == 2)
drawMask(ars[0].aspectGeom, panScan.aspectGeom, panScan.aspectGeom.maskColor, true, ncp);
drawLines(panScan.aspectGeom, panScan.aspectGeom.lineColor, 1, 0, ncp);
// Draw safe action
if (panScan.displaySafeAction)
{
drawLines( panScan.safeActionGeom, panScan.safeActionGeom.lineColor, 1, 1, ncp);
}
// Draw safe title
if (panScan.displaySafeTitle)
{
drawLines( panScan.safeTitleGeom, panScan.safeTitleGeom.lineColor, 1, 1, ncp);
}
}
// Draw the filmback
if ( filmback.displayFilmGate )
{
// Draw filmback
drawLines(filmback.filmbackGeom, filmback.filmbackGeom.lineColor, 1, 0, ncp);
// Draw Sound Area Line
if ( filmback.soundTrackWidth != 0 )
drawLine(filmback.imageGeom.x1, filmback.imageGeom.x1, filmback.imageGeom.y1, filmback.imageGeom.y2, filmback.imageGeom.lineColor, 0, ncp);
}
// Draw filmback safe action
if (filmback.displaySafeAction)
{
drawLines( filmback.safeActionGeom, filmback.safeActionGeom.lineColor, 1, 1, ncp);
}
// Draw filmback safe title
if (filmback.displaySafeTitle)
{
drawLines( filmback.safeTitleGeom, filmback.safeTitleGeom.lineColor, 1, 1, ncp);
}
// Draw the projection gate
if ( filmback.displayProjGate )
{
drawLines(filmback.projGeom, filmback.projGeom.lineColor, 1, 1, ncp);
}
// Display horizontal line
if ( options.displayLineH )
{
drawLine( filmback.imageGeom.x1, filmback.imageGeom.x2, portGeom.y, portGeom.y, options.lineColor, 0, ncp);
}
// Display vertical line
if ( options.displayLineV )
{
double cx = ( filmback.imageGeom.x1 + filmback.imageGeom.x2 ) / 2;
drawLine( cx, cx, filmback.imageGeom.y1, filmback.imageGeom.y2, options.lineColor, 0, ncp);
}
// Display Horizontal Thirds
if ( options.displayThirdsH)
{
Geom g = (numAspectRatios > 0)?ars[0].aspectGeom:portGeom;
double y1 = g.y1+ ( ( g.y2 - g.y1 ) * 0.33 );
double y2 = g.y1+ ( ( g.y2 - g.y1 ) * 0.66 );
drawLine( g.x1, g.x2, y1, y1, options.lineColor, 0, ncp);
drawLine( g.x1, g.x2, y2, y2, options.lineColor, 0, ncp);
}
// Display Vertical Thirds
if ( options.displayThirdsV)
{
Geom g = (numAspectRatios > 0)?ars[0].aspectGeom:portGeom;
double x1 = g.x1+ ( ( g.x2 - g.x1 ) * 0.33 );
double x2 = g.x1+ ( ( g.x2 - g.x1 ) * 0.66 );
drawLine( x1, x1, g.y1, g.y2, options.lineColor, 0, ncp);
drawLine( x2, x2, g.y1, g.y2, options.lineColor, 0, ncp);
}
// Display crosshair
if ( options.displayCrosshair )
{
double cx = ( filmback.imageGeom.x1 + filmback.imageGeom.x2 ) / 2;
drawLine( cx-25, cx-5, portGeom.y, portGeom.y, options.lineColor, 0 ,ncp);
drawLine( cx+25, cx+5, portGeom.y, portGeom.y, options.lineColor, 0 ,ncp);
drawLine( cx, cx, portGeom.y-25, portGeom.y-5, options.lineColor, 0 ,ncp);
drawLine( cx, cx, portGeom.y+25, portGeom.y+5, options.lineColor, 0 ,ncp);
}
// Display the pad area
if (pad.usePad && pad.isPadded && pad.displayMode > 0)
{
drawLines(pad.padGeom, pad.padGeom.lineColor, 1, 0, ncp);
}
// Draw custom text elements
if ( options.enableTextDrawing)
drawCustomTextElements(textWhenDraw,wim,view);
// Turn off blending
glDisable(GL_BLEND);
// Restore blend settings
glBlendFunc(blendAttrs[0], blendAttrs[1]);
// Re-enable z-depth testing.
// Note: Moved up to drawMask() due to hack because of Maya
//glDepthMask( GL_TRUE );
// Restore matrix
glMatrixMode( GL_PROJECTION );
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
// Restore all attributes
glPopAttrib();
// End of openGL calls
view.endGL();
}
// Make a huge bounding box
//
MBoundingBox spReticleLoc::boundingBox() const
{
return MBoundingBox(MPoint(-1000000,-1000000,-1000000),
MPoint(1000000,1000000,1000000));
}
// This function returns whether this locator should be effected by the
// Display locators toggle in Maya. It is dependent upon the hideLocator
// option.
//
bool spReticleLoc::excludeAsLocator() const
{
// Check to see locator should be hidden with other locators
MObject thisNode = thisMObject();
MPlug p(thisNode, HideLocator);
bool hideLocator;
MStatus stat = p.getValue(hideLocator);
if (!stat)
stat.perror("spReticleLoc::excludeAsLocator hideLocator");
return hideLocator;
}
// This method is called just after a particular instance of the node has
// been created. It automatically sources the proper scripts and sets the
// loadDefault argument to 1, indicating that the first time the locator
// is drawn that it should first load the default settings for the locator.
// This functionality allows either the show or facility to set standards
// on the locator.
//
void spReticleLoc::postConstructor()
{
// Tell Maya to draw this in the transparent queue
#if MAYA_API_VERSION < 850
#ifndef WIN32
setTranspHandler( (TranspHandler)(&spReticleLoc::isTransparent) );
#endif
#endif
// Load defaults
loadDefault = 1;
// Set Refresh
needRefresh = true;
}
void * spReticleLoc::creator()
{
return new spReticleLoc();
}
MStatus spReticleLoc::initialize()
{
MStatus stat;
// Define a default empty string
MString defaultString("");
MFnStringData defaultTextData;
MObject defaultTextAttr = defaultTextData.create(defaultString);
DrawingEnabled = nAttr.create( "drawingEnabled", "en", MFnNumericData::kBoolean, 1, &stat );
McheckStatus(stat,"create drawingEnabled attribute");
nAttr.setInternal(true);
EnableTextDrawing = nAttr.create( "enableTextDrawing", "etd", MFnNumericData::kBoolean, 1, &stat );
McheckStatus(stat,"create enableTextDrawing attribute");
nAttr.setInternal(true);
HorizontalFilmAperture = nAttr.create( "horizontalFilmAperture", "hfa", MFnNumericData::kFloat, 0.864, &stat );
McheckStatus(stat,"create horizontalFilmAperture attribute");
nAttr.setInternal(true);
VerticalFilmAperture = nAttr.create( "verticalFilmAperture", "vfa", MFnNumericData::kFloat, 0.630, &stat );
McheckStatus(stat,"create verticalFilmAperture attribute");
nAttr.setInternal(true);
FilmbackAperture = nAttr.create( "filmbackAperture", "cap", HorizontalFilmAperture, VerticalFilmAperture, MObject::kNullObj, &stat );
nAttr.setDefault( 0.864, 0.630 );
SoundTrackWidth = nAttr.create( "soundTrackWidth", "stw", MFnNumericData::kFloat, 0.0, &stat );
McheckStatus(stat,"create soundTrackWidth attribute");
nAttr.setInternal(true);
DisplayFilmGate = nAttr.create( "displayFilmGate", "dfg", MFnNumericData::kBoolean, false, &stat );
McheckStatus(stat,"create displayFilmGate attribute");
nAttr.setInternal(true);
HorizontalProjectionGate = nAttr.create( "horizontalProjectionGate", "hpg", MFnNumericData::kFloat, 0.825, &stat );
McheckStatus(stat,"create horizontalProjectionGate attribute");
nAttr.setInternal(true);
VerticalProjectionGate = nAttr.create( "verticalProjectionGate", "vpg", MFnNumericData::kFloat, 0.446, &stat );
McheckStatus(stat,"create verticalProjectionGate attribute");
nAttr.setInternal(true);
ProjectionGate = nAttr.create( "projectionGate", "pg", HorizontalProjectionGate, VerticalProjectionGate, MObject::kNullObj, &stat );
nAttr.setDefault( 0.825, 0.446 );
DisplayProjectionGate = nAttr.create( "displayProjGate", "dpg", MFnNumericData::kBoolean, false, &stat );
McheckStatus(stat,"create displayProjGate attribute");
nAttr.setInternal(true);
HorizontalSafeAction = nAttr.create( "horizontalSafeAction", "hsa", MFnNumericData::kFloat, 0.713, &stat );
McheckStatus(stat,"create horizontalSafeAction attribute");
nAttr.setInternal(true);
VerticalSafeAction = nAttr.create( "verticalSafeAction", "vsa", MFnNumericData::kFloat, 0.535, &stat );
McheckStatus(stat,"create verticalSafeAction attribute");
nAttr.setInternal(true);
SafeAction = nAttr.create( "safeAction", "sa", HorizontalSafeAction, VerticalSafeAction, MObject::kNullObj, &stat );
nAttr.setDefault( 0.713, 0.535 );
DisplaySafeAction = nAttr.create( "displaySafeAction", "dsa", MFnNumericData::kBoolean, false, &stat );
McheckStatus(stat,"create displaySafeAction attribute");
nAttr.setInternal(true);
HorizontalSafeTitle = nAttr.create( "horizontalSafeTitle", "hst", MFnNumericData::kFloat, 0.630, &stat );
McheckStatus(stat,"create horizontalSafeTitle attribute");
nAttr.setInternal(true);
VerticalSafeTitle = nAttr.create( "verticalSafeTitle", "vst", MFnNumericData::kFloat, 0.475, &stat );
McheckStatus(stat,"create verticalSafeTitle attribute");
nAttr.setInternal(true);
SafeTitle = nAttr.create( "safeTitle", "st", HorizontalSafeTitle, VerticalSafeTitle, MObject::kNullObj, &stat );
nAttr.setDefault( 0.630, 0.475 );
DisplaySafeTitle = nAttr.create( "displaySafeTitle", "dst", MFnNumericData::kBoolean, false, &stat );
McheckStatus(stat,"create displaySafeTitle attribute");
nAttr.setInternal(true);
AspectRatio = nAttr.create( "aspectRatio", "ar", MFnNumericData::kFloat, 1.85, &stat );
McheckStatus(stat,"create aspectRatio attribute");
nAttr.setInternal(true);
DisplayMode = eAttr.create( "displayMode", "dm", 2, &stat );
McheckStatus(stat, "create displayMode attribute");
eAttr.addField("none", 0);
eAttr.addField("lines", 1);
eAttr.addField("Transparent Mask", 2);
eAttr.setInternal(true);
AspectMaskColor = nAttr.createColor( "aspectMaskColor", "amc", &stat );
nAttr.setDefault( 0.0, 0.0, 0.0 );
nAttr.setUsedAsColor( true );
nAttr.setInternal(true);
AspectMaskTrans = nAttr.create( "aspectMaskTrans", "amt", MFnNumericData::kFloat, 0.75, &stat );
McheckStatus(stat,"create aspectMaskTrans attribute");
nAttr.setMin(0.0);
nAttr.setMax(1.0);
nAttr.setInternal(true);
AspectLineColor = nAttr.createColor( "aspectLineColor", "alc", &stat );
nAttr.setDefault( 0.8, 0.8, 0.8 );
nAttr.setUsedAsColor( true );
nAttr.setInternal(true);
AspectLineTrans = nAttr.create( "aspectLineTrans", "alt", MFnNumericData::kFloat, 0.0, &stat );
McheckStatus(stat,"create aspectLineTrans attribute");
nAttr.setMin(0.0);
nAttr.setMax(1.0);
nAttr.setInternal(true);
AspectDisplaySafeTitle = nAttr.create( "aspectDisplaySafeTitle", "adst", MFnNumericData::kBoolean, false, &stat );
McheckStatus(stat,"create aspectDisplaySafeTitle attribute");
nAttr.setInternal(true);
AspectDisplaySafeAction = nAttr.create( "aspectDisplaySafeAction", "adsa", MFnNumericData::kBoolean, false, &stat );
McheckStatus(stat,"create aspectDisplaySafeAction attribute");
nAttr.setInternal(true);
AspectRatios = cAttr.create( "aspectRatios", "ars", &stat );
McheckStatus(stat,"create aspectRatios attribute");
cAttr.addChild( AspectRatio );
cAttr.addChild( DisplayMode );
cAttr.addChild( AspectMaskColor );
cAttr.addChild( AspectMaskTrans );
cAttr.addChild( AspectLineColor );
cAttr.addChild( AspectLineTrans );
cAttr.addChild( AspectDisplaySafeAction );
cAttr.addChild( AspectDisplaySafeTitle );
cAttr.setArray( true );
cAttr.setIndexMatters( true );
PanScanAspectRatio = nAttr.create( "panScanAspectRatio", "psar", MFnNumericData::kFloat, -1, &stat );
McheckStatus(stat,"create panScanAspectRatio attribute");
nAttr.setInternal(true);
PanScanDisplayMode = eAttr.create( "panScanDisplayMode", "psdm", 0, &stat );
McheckStatus(stat, "create panScanDisplayMode attribute");
eAttr.addField("none", 0);
eAttr.addField("lines", 1);
eAttr.addField("Transparent Mask", 2);
eAttr.setInternal(true);
PanScanDisplaySafeTitle = nAttr.create( "panScanDisplaySafeTitle", "psdst", MFnNumericData::kBoolean, false, &stat );
McheckStatus(stat,"create panScanDisplaySafeTitle attribute");
nAttr.setInternal(true);
PanScanDisplaySafeAction = nAttr.create( "panScanDisplaySafeAction", "psdsa", MFnNumericData::kBoolean, false, &stat );
McheckStatus(stat,"create panScanDisplaySafeAction attribute");
nAttr.setInternal(true);
PanScanMaskColor = nAttr.createColor( "panScanMaskColor", "psmc", &stat );
nAttr.setDefault( 1.0, 1.0, 0.8 );
nAttr.setUsedAsColor( true );
nAttr.setInternal(true);
PanScanMaskTrans = nAttr.create( "panScanMaskTrans", "psmt", MFnNumericData::kFloat, 0.85, &stat );
McheckStatus(stat,"create panScanMaskTrans attribute");
nAttr.setMin(0.0);
nAttr.setMax(1.0);
nAttr.setInternal(true);
PanScanLineColor = nAttr.createColor( "panScanLineColor", "pslc", &stat );
nAttr.setDefault( 1.0, 1.0, 0.0 );
nAttr.setUsedAsColor( true );
nAttr.setInternal(true);
PanScanLineTrans = nAttr.create( "panScanLineTrans", "pslt", MFnNumericData::kFloat, 0.5, &stat );
McheckStatus(stat,"create panScanLineTrans attribute");
nAttr.setMin(0.0);
nAttr.setMax(1.0);
nAttr.setInternal(true);
PanScanRatio = nAttr.create( "panScanRatio", "psr", MFnNumericData::kFloat, 1.33, &stat );
McheckStatus(stat, "create panScanRatio attribute");
nAttr.setKeyable(true);
nAttr.setMin(0);
nAttr.setInternal(true);
PanScanOffset = nAttr.create( "panScanOffset", "pso", MFnNumericData::kFloat, 0.0, &stat );
McheckStatus(stat, "create panScanOffset attribute");
nAttr.setKeyable(true);
nAttr.setMin(-1.0);
nAttr.setMax(1.0);
nAttr.setInternal(true);
PanScanAttr = cAttr.create( "panScan", "ps", &stat );
McheckStatus(stat,"create panScan attribute");
cAttr.addChild( PanScanAspectRatio );
cAttr.addChild( PanScanDisplayMode );
cAttr.addChild( PanScanMaskColor );
cAttr.addChild( PanScanMaskTrans );
cAttr.addChild( PanScanLineColor );
cAttr.addChild( PanScanLineTrans );
cAttr.addChild( PanScanDisplaySafeAction );
cAttr.addChild( PanScanDisplaySafeTitle );
cAttr.addChild( PanScanRatio );
cAttr.addChild( PanScanOffset );
TextType = eAttr.create( "textType", "ttyp", 0, &stat );
McheckStatus(stat, "create textType attribute");
eAttr.addField("String", 0);
eAttr.addField("Lens", 1);
eAttr.addField("Camera", 2);
eAttr.addField("Frame", 3);
eAttr.addField("Aspect Ratio", 4);
eAttr.addField("Max. Distance", 5);
eAttr.addField("Proj. Gate", 6);
eAttr.addField("Show", 7);
eAttr.addField("Shot", 8);
eAttr.addField("Show/Shot",9);
eAttr.addField("Frame Start", 10);
eAttr.addField("Frame End", 11);
eAttr.addField("Frame Range",12);
eAttr.addField("User",13);
eAttr.addField("Current File",14);
eAttr.addField("File Path",15);
eAttr.addField("File Name",16);
eAttr.addField("Pan/Scan Aspect Ratio",17);
eAttr.addField("Pan/Scan Offset",18);
eAttr.addField("safe action",19);
eAttr.addField("safe title",20);
eAttr.setInternal(true);
TextStr = tAttr.create( "textStr", "tstr", MFnStringData::kString );
McheckStatus(stat,"create textStr attribute");
tAttr.setConnectable(false);
tAttr.setDefault(defaultTextAttr);
tAttr.setInternal(true);
TextAlign = eAttr.create( "textAlign", "ta", 0, &stat );
McheckStatus(stat, "create textAlign attribute");
eAttr.addField("Left", 0);
eAttr.addField("Center", 1);
eAttr.addField("Right", 2);
eAttr.setInternal(true);
TextPosX = nAttr.create( "textPosX", "tpx", MFnNumericData::kFloat, 0.0, &stat );
McheckStatus(stat, "create textPosX attribute");
nAttr.setInternal(true);
TextPosY = nAttr.create( "textPosY", "tpy", MFnNumericData::kFloat, 0.0, &stat );
McheckStatus(stat, "create textPosX attribute");
nAttr.setInternal(true);
TextPos = nAttr.create( "textPos", "tp", TextPosX, TextPosY, MObject::kNullObj, &stat );
McheckStatus(stat, "create textPos attribute");
nAttr.setDefault( 0.0, 0.0 );
TextPosRel = eAttr.create( "textPosRel", "tpr", 0, &stat );
McheckStatus(stat, "create textPosRel attribute");
eAttr.addField("Bottom Left", 0);
eAttr.addField("Bottom Center", 1);
eAttr.addField("Bottom Right", 2);
eAttr.addField("Middle Left", 3);
eAttr.addField("Center", 4);
eAttr.addField("Middle Right", 5);
eAttr.addField("Top Left", 6);
eAttr.addField("Top Center", 7);
eAttr.addField("Top Right", 8);
eAttr.setInternal(true);
TextLevel = eAttr.create( "textLevel", "tl", 0, &stat );
McheckStatus(stat, "create textLevel attribute");
eAttr.addField("Window", 0);
eAttr.addField("Pad/Filmback", 1);
eAttr.addField("Filmback", 2);
eAttr.addField("Proj. Mask", 3);
eAttr.addField("Aspect Ratio", 4);
eAttr.addField("Pan/Scan",5);
eAttr.setInternal(true);
TextARLevel = nAttr.create( "textARLevel", "tarl", MFnNumericData::kInt, 0, &stat );
McheckStatus(stat, "create textARLevel attribute");
nAttr.setInternal(true);
TextColor = nAttr.createColor( "textColor", "tc", &stat );
McheckStatus(stat,"create textColor attribute");
nAttr.setDefault( 1.0, 1.0, 1.0 );
nAttr.setUsedAsColor( true );
nAttr.setInternal(true);
TextTrans = nAttr.create( "textTrans", "tt", MFnNumericData::kFloat, 0.5, &stat );
McheckStatus(stat,"create textTrans attribute");
nAttr.setMin(0.0);
nAttr.setMax(1.0);
nAttr.setInternal(true);
Text = cAttr.create( "text", "txt", &stat );
McheckStatus(stat,"create text attribute");
cAttr.addChild( TextType );
cAttr.addChild( TextStr );
cAttr.addChild( TextAlign );
cAttr.addChild( TextPos );
cAttr.addChild( TextPosRel );
cAttr.addChild( TextLevel );
cAttr.addChild( TextARLevel );
cAttr.addChild( TextColor );
cAttr.addChild( TextTrans );
cAttr.setArray( true );
cAttr.setIndexMatters( true );
MiscTextColor = nAttr.createColor( "miscTextColor", "mtc", &stat );
McheckStatus(stat,"create miscTextColor attribute");
nAttr.setDefault( 1.0, 1.0, 1.0 );
nAttr.setUsedAsColor( true );
nAttr.setInternal(true);
MiscTextTrans = nAttr.create( "miscTextTrans", "mtt", MFnNumericData::kFloat, 0.5, &stat );
McheckStatus(stat,"create miscTextTrans attribute");
nAttr.setMin(0.0);
nAttr.setMax(1.0);
nAttr.setInternal(true);
LineColor = nAttr.createColor( "lineColor", "lc", &stat );
nAttr.setDefault( 1.0, 1.0, 0.0 );
nAttr.setUsedAsColor( true );
nAttr.setInternal(true);
LineTrans = nAttr.create( "lineTrans", "lt", MFnNumericData::kFloat, 0.5, &stat );
McheckStatus(stat,"create lineTrans attribute");
nAttr.setMin(0.0);
nAttr.setMax(1.0);
nAttr.setInternal(true);
FilmGateColor = nAttr.createColor( "filmGateColor", "fg", &stat );
nAttr.setDefault( 1.0, 1.0, 1.0 );
nAttr.setUsedAsColor( true );
nAttr.setInternal(true);
FilmGateTrans = nAttr.create( "filmGateTrans", "fgt", MFnNumericData::kFloat, 0.25, &stat );
McheckStatus(stat,"create filmGateTrans attribute");
nAttr.setMin(0.0);
nAttr.setMax(1.0);
nAttr.setInternal(true);
ProjGateColor = nAttr.createColor( "projGateColor", "pgc", &stat );
nAttr.setDefault( 1.0, 1.0, 1.0 );
nAttr.setUsedAsColor( true );
nAttr.setInternal(true);
ProjGateTrans = nAttr.create( "projGateTrans", "pgt", MFnNumericData::kFloat, 0.25, &stat );
McheckStatus(stat,"create projGateTrans attribute");
nAttr.setMin(0.0);
nAttr.setMax(1.0);
nAttr.setInternal(true);
HideLocator = nAttr.create( "hideLocator", "hlc", MFnNumericData::kBoolean, false, &stat );
McheckStatus(stat,"create hideLocator attribute");
nAttr.setInternal(true);
UseSpReticle = nAttr.create( "useSpReticle", "ur", MFnNumericData::kBoolean, false, &stat );
McheckStatus(stat,"create useSpReticle attribute");
nAttr.setInternal(true);
DisplayLineH = nAttr.create( "displayLineH", "dlh", MFnNumericData::kBoolean, false, &stat );
McheckStatus(stat,"create displayLineH attribute");
nAttr.setInternal(true);
DisplayLineV = nAttr.create( "displayLineV", "dlv", MFnNumericData::kBoolean, false, &stat );
McheckStatus(stat,"create displayLineV attribute");
nAttr.setInternal(true);
DisplayThirdsH = nAttr.create( "displayThirdsH", "dth", MFnNumericData::kBoolean, false, &stat );
McheckStatus(stat,"create displayThirdsH attribute");
nAttr.setInternal(true);
DisplayThirdsV = nAttr.create( "displayThirdsV", "dtv", MFnNumericData::kBoolean, false, &stat );
McheckStatus(stat,"create displayThirdsV attribute");
nAttr.setInternal(true);
DisplayCrosshair = nAttr.create( "displayCrosshair", "dlc", MFnNumericData::kBoolean, false, &stat );
McheckStatus(stat,"create displayCrosshair attribute");
nAttr.setInternal(true);
Time = uAttr.create( "time", "tm", MFnUnitAttribute::kTime, 0.0, &stat );
McheckStatus(stat,"create time attribute");
DriveCameraAperture = nAttr.create( "driveCameraAperture", "dca", MFnNumericData::kBoolean, false, &stat );
McheckStatus(stat,"create driveCameraAperture attribute");
nAttr.setInternal(true);
MaximumDistance = nAttr.create( "maximumDistance", "mad", MFnNumericData::kFloat, 10000, &stat );
McheckStatus(stat,"create maximumDistance attribute");
nAttr.setInternal(true);
UseOverscan = nAttr.create( "useOverscan", "uo", MFnNumericData::kBoolean, false, &stat );
McheckStatus(stat,"create useOverscan attribute");
nAttr.setInternal(true);
UsePad = nAttr.create( "usePad", "up", MFnNumericData::kBoolean, false, &stat );
McheckStatus(stat,"create usePad attribute");
nAttr.setInternal(true);
PadAmountX = nAttr.create( "padAmountX", "pax", MFnNumericData::kFloat, 0.0, &stat );
McheckStatus(stat,"create padAmountX attribute");
nAttr.setInternal(true);
PadAmountY = nAttr.create( "padAmountY", "pay", MFnNumericData::kFloat, 0.0, &stat );
McheckStatus(stat,"create padAmountY attribute");
nAttr.setInternal(true);
PadAmount = nAttr.create( "padAmount", "paa", PadAmountX, PadAmountY, MObject::kNullObj, &stat );
nAttr.setDefault( 0.0, 0.0 );
PadDisplayMode = eAttr.create( "padDisplayMode", "pdm", 2, &stat );
McheckStatus(stat, "create panScanDisplayMode attribute");
eAttr.addField("none", 0);
eAttr.addField("lines", 1);
eAttr.addField("Transparent Mask", 2);
eAttr.setInternal(true);
PadMaskColor = nAttr.createColor( "padMaskColor", "pmc", &stat );
McheckStatus(stat,"create padMaskColor attribute");
nAttr.setDefault( 0.0, 0.0, 0.0 );
nAttr.setUsedAsColor( true );
nAttr.setInternal(true);
PadMaskTrans = nAttr.create( "padMaskTrans", "pmt", MFnNumericData::kFloat, 0.25, &stat );
McheckStatus(stat,"create padMaskTrans attribute");
nAttr.setMin(0.0);
nAttr.setMax(1.0);
nAttr.setInternal(true);
PadLineColor = nAttr.createColor( "padLineColor", "plc", &stat );
McheckStatus(stat,"create padLineColor attribute");
nAttr.setDefault( 1.0, 0.0, 0.0 );
nAttr.setUsedAsColor( true );
nAttr.setInternal(true);
PadLineTrans = nAttr.create( "padLineTrans", "plt", MFnNumericData::kFloat, 0.0, &stat );
McheckStatus(stat,"create padLineTrans attribute");
nAttr.setMin(0.0);
nAttr.setMax(1.0);
nAttr.setInternal(true);
Pad = cAttr.create( "pad", "pad", &stat );
McheckStatus(stat,"create pad attribute");
cAttr.addChild( UsePad );
cAttr.addChild( PadAmount );
cAttr.addChild( PadDisplayMode );
cAttr.addChild( PadMaskColor );
cAttr.addChild( PadMaskTrans );
cAttr.addChild( PadLineColor );
cAttr.addChild( PadLineTrans );
Tag = tAttr.create( "type", "typ", MFnStringData::kString );
McheckStatus(stat,"create tag attribute");
tAttr.setHidden(true);
tAttr.setConnectable(false);
tAttr.setDefault(defaultTextAttr);
stat = addAttribute(EnableTextDrawing);
McheckStatus(stat,"addAttribute enableTextDrawing");
stat = addAttribute (DrawingEnabled);
McheckStatus(stat,"addAttribute drawingEnabled");
stat = addAttribute (FilmbackAperture);
McheckStatus(stat,"addAttribute filmbackAperture");
stat = addAttribute (SoundTrackWidth);
McheckStatus(stat,"addAttribute soundTrackWidth");
stat = addAttribute (DisplayFilmGate);
McheckStatus(stat,"addAttribute displayFilmGate");
stat = addAttribute (ProjectionGate);
McheckStatus(stat,"addAttribute projectionGate");
stat = addAttribute (DisplayProjectionGate);
McheckStatus(stat,"addAttribute displayProjectionGate");
stat = addAttribute (SafeAction);
McheckStatus(stat,"addAttribute safeAction");
stat = addAttribute (DisplaySafeAction);
McheckStatus(stat,"addAttribute displaySafeAction");
stat = addAttribute (SafeTitle);
McheckStatus(stat,"addAttribute safeTitle");
stat = addAttribute (DisplaySafeTitle);
McheckStatus(stat,"addAttribute displaySafeTitle");
stat = addAttribute (PanScanAttr);
McheckStatus(stat,"addAttribute panScan");
stat = addAttribute (AspectRatios);
McheckStatus(stat,"addAttribute aspectRatios");
stat = addAttribute (Text);
McheckStatus(stat,"addAttribute text");
stat = addAttribute (MiscTextColor);
McheckStatus(stat,"addAttribute miscTextColor");
stat = addAttribute (MiscTextTrans);
McheckStatus(stat,"addAttribute miscTextTrans");
stat = addAttribute (LineColor);
McheckStatus(stat,"addAttribute lineColor");
stat = addAttribute (LineTrans);
McheckStatus(stat,"addAttribute lineTrans");
stat = addAttribute (FilmGateColor);
McheckStatus(stat,"addAttribute filmGateColor");
stat = addAttribute (FilmGateTrans);
McheckStatus(stat,"addAttribute filmGateTrans");
stat = addAttribute (ProjGateColor);
McheckStatus(stat,"addAttribute projGateColor");
stat = addAttribute (ProjGateTrans);
McheckStatus(stat,"addAttribute projGateTrans");
stat = addAttribute (HideLocator);
McheckStatus(stat,"addAttribute hideLocator");
stat = addAttribute (UseSpReticle);
McheckStatus(stat,"addAttribute useSpReticle");
stat = addAttribute (DisplayLineH);
McheckStatus(stat,"addAttribute displayLineH");
stat = addAttribute (DisplayLineV);
McheckStatus(stat,"addAttribute displayLineV");
stat = addAttribute (DisplayThirdsH);
McheckStatus(stat,"addAttribute displayThirdsH");
stat = addAttribute (DisplayThirdsV);
McheckStatus(stat,"addAttribute displayThirdsV");
stat = addAttribute (DisplayCrosshair);
McheckStatus(stat,"addAttribute displayCrosshair");
stat = addAttribute (Time);
McheckStatus(stat,"addAttribute time");
stat = addAttribute (DriveCameraAperture);
McheckStatus(stat,"addAttribute driveCameraAperture");
stat = addAttribute (MaximumDistance);
McheckStatus(stat,"addAttribute maximumDistance");
stat = addAttribute (UseOverscan);
McheckStatus(stat,"addAttribute useOverscan");
stat = addAttribute (Pad);
McheckStatus(stat,"addAttribute pad");
stat = addAttribute (Tag);
McheckStatus(stat,"addAttribute tag");
return MS::kSuccess;
}
MStatus initializePlugin(MObject obj)
{
MFnPlugin plugin(obj, "SPI", "1.6", "Any");
MStatus status = plugin.registerNode( "spReticleLoc", spReticleLoc::id,
&spReticleLoc::creator, &spReticleLoc::initialize,
&spReticleLoc::drawDbClassification);
if (!status)
{
status.perror("registerNode");
return status;
}
spReticleLoc::drawDbClassification,
spReticleLoc::drawRegistrantId,
spReticleLocDrawOverride::Creator);
if (!status) {
status.perror("registerDrawOverrideCreator");
return status;
}
return status;
}
MStatus uninitializePlugin(MObject obj)
{
MFnPlugin plugin( obj );
spReticleLoc::drawDbClassification,
spReticleLoc::drawRegistrantId);
if (!status) {
status.perror("deregisterGeometryOverrideCreator");
return status;
}
status = plugin.deregisterNode( spReticleLoc::id );
if (!status)
{
status.perror("deregisterNode");
return status;
}
return status;
}
void spReticleLoc::getDrawData( spReticleLocData& drawData, const MDagPath &cameraPath, const double& portHeight, const double& portWidth )
{
//clear the data
drawData = spReticleLocData();
MStatus stat;
MPlug p;
thisNode = thisMObject();
//set node name
drawData.nodeName = name();
// Initialize maximumDist
drawData.maximumDist = 0;
// If this is the first time it's being draw, load the default values
if (loadDefault == 1)
{
MString tag;
p = MPlug ( thisNode,Tag );
McheckVoid ( p.getValue ( tag ), "spReticleLoc::draw get tag");
MString cmd = "if (exists(\"spReticleLocSetDefault\")) spReticleLocSetDefault(\""+ name()+"\",\""+tag+"\")";
loadDefault = 0;
}
//Get options
if(needRefresh)
getOptions(drawData.options);
// Drawing not enabled, return
if (!drawData.options.drawingEnabled)
return;
// Set the MFnCamera to the current camera
MFnCamera camera;
camera.setObject( cameraPath );
drawData.cameraData.nearClippingPlane = camera.nearClippingPlane();
drawData.cameraData.farClippingPlane = camera.farClippingPlane();
drawData.cameraData.isOrtho = camera.isOrtho();
drawData.cameraData.cameraPath = cameraPath;
// If camera is orthographic, then return
if (drawData.cameraData.isOrtho)
return;
// Using useSpReticle Filter, check camera for attribute
if (drawData.options.useSpRet)
{
//Default value to false
drawData.useReticle = false;
// Find the useSpReticle plug on the camera node
MPlug useReticlePlug = camera.findPlug("useSpReticle", &stat);
// If the plug is valid (not null) get the current value
if (!useReticlePlug.isNull())
{
McheckVoid ( useReticlePlug.getValue( drawData.useReticle ), "spReticleLoc::draw get useSpReticle plug");
}
// If camera is not set to use reticle then return
if (!drawData.useReticle)
return;
}
// Get the camera position
MMatrix wm = cameraPath.inclusiveMatrix();
// Find the largest component
if (drawData.options.maximumDistance > 0)
{
// original: largest value
//maximumDist = std::max(wm[3][0],std::max(wm[3][1],wm[3][2]));
// largest absolute value (if negative, returns positive number)
//maximumDist = std::max(fabs(wm[3][0]),std::max(fabs(wm[3][1]),fabs(wm[3][2])));
// largest value (if negative, returns negative number)
double maxDist = std::max(wm[3][0],std::max(wm[3][1],wm[3][2]));
double minDist = std::min(wm[3][0],std::min(wm[3][1],wm[3][2]));
drawData.maximumDist = (fabs(maxDist) > fabs(minDist)) ? maxDist : minDist;
}
// Get the camera's overscan value
drawData.overscan = (drawData.options.useOverscan) ? 1.0 : camera.overscan();
drawData.ncp = camera.nearClippingPlane() + 0.001;
drawData.portHeight = portHeight;
drawData.portWidth = portWidth;
// Get the worldInverseMatrix
drawData.wim = getMatrix("worldInverseMatrix");
drawData.calcPortGeom();
// Update text data
if (needToUpdateTextData(drawData) || needRefresh)
{
// Get the text data
getTextData(drawData);
}
// Update aspect ratios
if (needToUpdateAspectRatios(drawData) || needRefresh)
{
// Get the aspect ratio data
getAspectRatioData(drawData);
}
// Check to see if we need to refresh the data
if (needRefresh)
{
// Get the pad attribute data
getPadData(drawData);
// Get the filmback attribute data
getFilmbackData(drawData);
// Get the projection gate attribute data
getProjectionData(drawData);
// Get safe title and safe action data
getSafeActionData(drawData);
getSafeTitleData(drawData);
// Get pan and scan data
getPanScanData(drawData.panScan );
// Hold this copy
drawData.oFilmback = drawData.filmback;
// Reset need refresh
//needRefresh = false;
}
drawData.doCompute();
// Draw custom text elements
if ( drawData.options.enableTextDrawing)
getCustomTextElement(drawData);
}
// This method calculates the geometry of the current window. This data is
// stored in a instance of the Geom class.
//
void spReticleLocData::calcPortGeom()
{
portGeom.x1 = 0;
portGeom.x2 = portWidth;
portGeom.y1 = 0;
portGeom.y2 = portHeight;
portGeom.x = portWidth / 2;
portGeom.y = portHeight / 2;
portGeom.isValid = true;
}
// This method calculates the geometry for the filmback. There are multiple
// Geom instances that are used for displaying all of the filmback options.
// This method takes the filmback data and calculates the appropriate settings
// for the filmback Geom instances.
//
void spReticleLocData::calcFilmbackGeom()
{
filmback = oFilmback;
MFnCamera camera;
camera.setObject(cameraData.cameraPath);
// See if we are using the camera's filmback data
bool useCameraFilmback = filmback.horizontalFilmAperture == -1;
// If the horizontalFilmAperture equals -1, then use the cameras settings
if (useCameraFilmback)
{
filmback.horizontalFilmAperture = camera.horizontalFilmAperture();
filmback.verticalFilmAperture = camera.verticalFilmAperture();
}
double hfa = filmback.horizontalFilmAperture;
double vfa = filmback.verticalFilmAperture;
double aspectRatio = hfa/vfa;
double nonPaddedAspectRatio = aspectRatio;
// Remove pad from filmback and aspect ratio
if (pad.usePad && pad.isPadded)
{
filmback.horizontalFilmAperture -= pad.padAmountX;
filmback.verticalFilmAperture -= pad.padAmountY;
nonPaddedAspectRatio = filmback.horizontalFilmAperture / filmback.verticalFilmAperture;
if (! pad.usePad)
{
hfa = filmback.horizontalFilmAperture;
vfa = filmback.verticalFilmAperture;
aspectRatio = nonPaddedAspectRatio;
}
}
// If drive camera aperture is on, then set camera values
if (!useCameraFilmback && options.driveCameraAperture)
{
if (camera.horizontalFilmAperture() != hfa)
McheckVoid( camera.setHorizontalFilmAperture(hfa), "spReticleLoc::calcFilmbackGeom - setting "+camera.name()+".horizontalFilmAperture");
if (camera.verticalFilmAperture() != vfa)
McheckVoid( camera.setVerticalFilmAperture(vfa), "spReticleLoc::calcFilmbackGeom - setting "+camera.name()+".verticalFilmAperture");
}
double portAspectRatio = double(portWidth)/double(portHeight);
bool portHoriz = portAspectRatio > aspectRatio;
MFnCamera::FilmFit filmFit = camera.filmFit();
if (filmFit == MFnCamera::kFillFilmFit)
{
if (portHoriz)
else
}
{
if (portHoriz)
else
}
switch ( filmFit )
{
filmback.filmbackGeom.x = (portWidth / overscan);
if (pad.usePad && pad.isPadded)
{
pad.padGeom.x = filmback.filmbackGeom.x;
pad.padGeom.y = pad.padGeom.x / aspectRatio;
filmback.filmbackGeom.x /= hfa / filmback.horizontalFilmAperture;
}
filmback.filmbackGeom.y = filmback.filmbackGeom.x / nonPaddedAspectRatio;
break;
filmback.filmbackGeom.y = (portHeight / overscan);
if (pad.usePad && pad.isPadded)
{
pad.padGeom.y = filmback.filmbackGeom.y;
pad.padGeom.x = pad.padGeom.y * aspectRatio;
filmback.filmbackGeom.y /= vfa / filmback.verticalFilmAperture;
}
filmback.filmbackGeom.x = filmback.filmbackGeom.y * nonPaddedAspectRatio;
break;
default:
MGlobal::displayError( nodeName + " invalid camera film fit (" + filmFit + ")");
break;
}
// Account for lens squeeze
filmback.filmbackGeom.x *= camera.lensSqueezeRatio();
pad.padGeom.x *= camera.lensSqueezeRatio();
filmback.filmbackGeom.x1 = portGeom.x - (filmback.filmbackGeom.x / 2);
filmback.filmbackGeom.x2 = portGeom.x + (filmback.filmbackGeom.x / 2);
filmback.filmbackGeom.y1 = portGeom.y - (filmback.filmbackGeom.y / 2);
filmback.filmbackGeom.y2 = portGeom.y + (filmback.filmbackGeom.y / 2);
filmback.filmbackGeom.isValid = true;
// Calculate the image area
filmback.horizontalImageAperture = filmback.horizontalFilmAperture;
filmback.verticalImageAperture = filmback.verticalFilmAperture;
filmback.imageGeom = filmback.filmbackGeom;
// Adjust for sound track if necessary
if (filmback.soundTrackWidth != 0)
{
filmback.horizontalImageAperture -= filmback.soundTrackWidth;
filmback.imageGeom.x = filmback.filmbackGeom.x * (filmback.horizontalImageAperture/filmback.horizontalFilmAperture);
filmback.imageGeom.x1 = filmback.filmbackGeom.x1+(filmback.filmbackGeom.x-filmback.imageGeom.x);
}
// Calculate rest of the pad area
if (pad.usePad && pad.isPadded)
{
pad.padGeom.x1 = portGeom.x - (pad.padGeom.x / 2);
pad.padGeom.x2 = portGeom.x + (pad.padGeom.x / 2);
pad.padGeom.y1 = portGeom.y - (pad.padGeom.y / 2);
pad.padGeom.y2 = portGeom.y + (pad.padGeom.y / 2);
pad.padGeom.isValid = true;
}
else
{
pad.padGeom = filmback.filmbackGeom;
pad.padGeom.isValid = false;
}
filmback.safeActionGeom.isValid = false;
filmback.safeTitleGeom.isValid = false;
}
// This method calculates the safe action area for the filmback.
//
void spReticleLocData::calcFilmbackSafeActionGeom()
{
calcMaskGeom(filmback.safeActionGeom,filmback.horizontalSafeAction,filmback.verticalSafeAction,filmback.imageGeom,filmback.horizontalImageAperture,filmback.verticalImageAperture);
filmback.safeActionGeom.isValid = true;
}
// This method calculates the safe title area for the filmback.
//
void spReticleLocData::calcFilmbackSafeTitleGeom(){
calcMaskGeom(filmback.safeTitleGeom,filmback.horizontalSafeTitle,filmback.verticalSafeTitle,filmback.imageGeom,filmback.horizontalImageAperture,filmback.verticalImageAperture);
filmback.safeTitleGeom.isValid = true;
}
// This method calculates the actual mask x,y values for a given Geom
// instance.
//
void spReticleLocData::calcMaskGeom(Geom & g, double w, double h, Geom & gSrc,
double wSrc, double hSrc)
{
double pw = (w != -1)?((wSrc-w)/2)/wSrc:(1-wSrc)/2;
double ph = (h != -1)?((hSrc-h)/2)/hSrc:(1-hSrc)/2;
g.x = gSrc.x*pw;
g.y = gSrc.y*ph;
g.x1 = gSrc.x1+g.x;
g.x2 = gSrc.x2-g.x;
g.y1 = gSrc.y1+g.y;
g.y2 = gSrc.y2-g.y;
}
// Calculates the safe action geometry for an Aspect Ratio.
//
void spReticleLocData::calcSafeActionGeom( Aspect_Ratio & ar )
{
if ( ar.aspectGeom.isValid )
{
ar.safeActionGeom = ar.aspectGeom;
calcMaskGeom(ar.safeActionGeom, -1, -1, ar.aspectGeom, 0.9, 0.9);
ar.safeActionGeom.isValid = true;
}
else
{
ar.safeActionGeom.isValid = false;
}
}
// Calculates the safe title geometry for an Aspect Ratio.
//
void spReticleLocData::calcSafeTitleGeom( Aspect_Ratio & ar )
{
if (ar.aspectGeom.isValid)
{
ar.safeTitleGeom = ar.aspectGeom;
calcMaskGeom(ar.safeTitleGeom, -1, -1, ar.aspectGeom, 0.8, 0.8);
ar.safeTitleGeom.isValid = true;
}
else
{
ar.safeTitleGeom.isValid = false;
}
}
// This calculates the various Geom instances for a particular aspectRatio
// instance.
//
void spReticleLocData::calcAspectGeom( Aspect_Ratio & ar )
{
ar.aspectGeom.x = filmback.imageGeom.x;
ar.aspectGeom.y = ar.aspectGeom.x / ar.aspectRatio;
ar.aspectGeom.x1 = filmback.imageGeom.x1;
ar.aspectGeom.x2 = filmback.imageGeom.x2;
ar.aspectGeom.y1 = portGeom.y - (ar.aspectGeom.y / 2);
ar.aspectGeom.y2 = portGeom.y + (ar.aspectGeom.y / 2);
ar.aspectGeom.isValid = true;
ar.safeActionGeom.isValid = false;
ar.safeTitleGeom.isValid = false;
if (ar.displaySafeAction)
calcSafeActionGeom(ar);
if (ar.displaySafeTitle)
calcSafeTitleGeom(ar);
}
// This calculates the PanScan Geom instances.
//
void spReticleLocData::calcPanScanGeom( PanScan & ps )
{
if (ps.aspectRatio == -1)
ps.aspectRatio = filmback.horizontalFilmAperture / filmback.verticalFilmAperture;
ps.aspectGeom.y = filmback.imageGeom.x / ps.aspectRatio;
ps.aspectGeom.x = ps.aspectGeom.y * ps.panScanRatio;
ps.aspectGeom.x1 = filmback.imageGeom.x1+ ( ((ps.panScanOffset+1)/2)*(filmback.imageGeom.x-ps.aspectGeom.x) );
ps.aspectGeom.x2 = ps.aspectGeom.x1+ps.aspectGeom.x;
ps.aspectGeom.y1 = portGeom.y - (ps.aspectGeom.y / 2);
ps.aspectGeom.y2 = portGeom.y + (ps.aspectGeom.y / 2);
ps.aspectGeom.isValid = true;
ps.safeActionGeom.isValid = false;
ps.safeTitleGeom.isValid = false;
if (ps.displaySafeAction)
calcSafeActionGeom( ps );
if (ps.displaySafeTitle)
calcSafeTitleGeom( ps );
}
void spReticleLocData::doCompute()
{
// Peform the calculations necessary to define the filmback geometry.
calcFilmbackGeom();
// Calculate the projection gate geometry
if (filmback.displayProjGate)
calcMaskGeom(filmback.projGeom,filmback.horizontalProjectionGate,filmback.verticalProjectionGate,filmback.imageGeom,filmback.horizontalImageAperture,filmback.verticalImageAperture);
// Calculate the safe action geometry
if (filmback.displaySafeAction)
calcFilmbackSafeActionGeom();
// Calculate the safe title geometry
if (filmback.displaySafeTitle)
calcFilmbackSafeTitleGeom();
// Calculate the projection gate geometry
if (panScan.displayMode != 0)
calcPanScanGeom( panScan );
// Calculate the aspect ratio geometry
for (int i = 0; i < numAspectRatios; i++ )
{
// Only calculate the aspect geom if the display mode != 0
if (ars[i].displayMode != 0)
{
calcAspectGeom( ars[i] );
}
}
}
spReticleLocDrawOverride::spReticleLocDrawOverride( const MObject& obj )
: MHWRender::MPxDrawOverride(obj, NULL)
,mCustomBoxDraw(false)
{
}
spReticleLocDrawOverride::~spReticleLocDrawOverride()
{
}
MHWRender::DrawAPI spReticleLocDrawOverride::supportedDrawAPIs() const
{
// this plugin supports both GL and DX
}
bool spReticleLocDrawOverride::isBounded( const MDagPath& objPath, const MDagPath& cameraPath ) const
{
return true;
}
MBoundingBox spReticleLocDrawOverride::boundingBox( const MDagPath& objPath, const MDagPath& cameraPath ) const
{
return MBoundingBox(MPoint(-1000000,-1000000,-1000000),
MPoint(1000000,1000000,1000000));
}
MUserData* spReticleLocDrawOverride::prepareForDraw( const MDagPath& objPath, const MDagPath& cameraPath, const MHWRender::MFrameContext& frameContext, MUserData* oldData )
{
MStatus status;
//retrieve data cache (create if does not exist)
spReticleLocData* data = dynamic_cast<spReticleLocData*>(oldData);
if(!data) {
data = new spReticleLocData();
if(data == NULL) {
MGlobal::displayError("Fail to allocate draw data");
return NULL;
}
// Load defaults
loadDefault = 1;
// Set Refresh
needRefresh = true;
}
//compute data and cache it
//Get the view attributes that impact drawing
int oX,oy,portWidth,portHeight;
frameContext.getViewportDimensions(oX,oy,portWidth,portHeight);
//get DG node for later use
MObject spReticleNode = objPath.node(&status);
MFnDependencyNode depNodeFn(spReticleNode, &status );
spReticleLoc* pSpReticleNode = dynamic_cast<spReticleLoc*>(depNodeFn.userNode(&status));
if(status != MStatus::kSuccess || pSpReticleNode == NULL) {
MGlobal::displayError("Fail to get user node");
return data;
}
//get draw Data
pSpReticleNode->getDrawData(*data, cameraPath, portHeight,portWidth);
return data;
}
void spReticleLocDrawOverride::addUIDrawables( const MDagPath& objPath, MHWRender::MUIDrawManager& drawManager, const MHWRender::MFrameContext& frameContext, const MUserData* data )
{
const spReticleLocData* reticleData = dynamic_cast<const spReticleLocData*>(data);
if(!reticleData) {
return;
}
// Drawing not enabled, return
if (!reticleData->options.drawingEnabled)
return;
// If camera is orthographic, then return
if (reticleData->cameraData.isOrtho)
return;
// If camera is not set to use reticle then return
if(reticleData->options.useSpRet){
if (!reticleData->useReticle)
return;
}
//get cached data
Options options = reticleData->options ;
MMatrix wim = reticleData->wim ;
int numAspectRatios = reticleData->numAspectRatios ;
Geom portGeom = reticleData->portGeom ;
std::vector<Aspect_Ratio> ars = reticleData->ars ;
PadOptions pad = reticleData->pad ;
Filmback oFilmback = reticleData->oFilmback ;
Filmback filmback = reticleData->filmback ;
PanScan panScan = reticleData->panScan ;
std::vector<TextData> textWhenDraw = reticleData->textWhenDraw ;
double maximumDist = reticleData->maximumDist ;
//begin drawing 2d HUD
//draw mask
// create variable to store what the first geometry object to draw aspect ratios to
Geom aspectContainerGeom;
// Draw the padGeomMask
if (pad.usePad && pad.isPadded)
{
if (pad.displayMode == 2)
drawMask(portGeom, pad.padGeom, pad.padGeom.maskColor, true, drawManager);
aspectContainerGeom = pad.padGeom;
}
else
{
aspectContainerGeom = portGeom;
}
// Draw the masks first
Aspect_Ratio ar;
for (int i = 0; i < numAspectRatios; i++ )
{
ar = ars[i];
// Draw the masks as Quads
if (ar.displayMode == 2)
{
Geom g = (i == 0)?aspectContainerGeom:ars[i-1].aspectGeom;
MColor maskColor = ar.aspectGeom.maskColor;
// Draw the mask in red if over the max distance
if (options.maximumDistance > 0 &&
fabs(maximumDist) >= options.maximumDistance)
{
if (i == 0)
{
maskColor = MColor(1,0,0,maskColor.a);
}
else
{
maskColor *= MColor(1.5,0.5,0.5,1);
}
}
drawMask(g, ar.aspectGeom, maskColor, i == 0, drawManager);
}
}
// Draw lines
for (int i = 0; i < numAspectRatios; i++ )
{
ar = ars[i];
if (ar.displayMode != 0)
{
bool sides = (i == 0 || ar.aspectGeom.x != ars[i].aspectGeom.x);
drawLines(ar.aspectGeom, ar.aspectGeom.lineColor, sides, 0, drawManager);
// Draw safe action
if (ar.displaySafeAction)
drawLines( ar.safeActionGeom, ar.safeActionGeom.lineColor, 1, 1, drawManager);
// Draw safe title
if (ar.displaySafeTitle)
drawLines( ar.safeTitleGeom, ar.safeTitleGeom.lineColor, 1, 1, drawManager);
}
}
// Draw the panScan
if ( panScan.displayMode != 0 )
{
if (panScan.displayMode == 2){
drawMask(ars[0].aspectGeom, panScan.aspectGeom, panScan.aspectGeom.maskColor, true, drawManager);
}
drawLines(panScan.aspectGeom, panScan.aspectGeom.lineColor, 1, 0,drawManager);
// Draw safe action
if (panScan.displaySafeAction)
{
drawLines( panScan.safeActionGeom, panScan.safeActionGeom.lineColor, 1, 1,drawManager);
}
// Draw safe title
if (panScan.displaySafeTitle)
{
drawLines( panScan.safeTitleGeom, panScan.safeTitleGeom.lineColor, 1, 1,drawManager);
}
}
// Draw the filmback
if ( filmback.displayFilmGate )
{
// Draw filmback
drawLines(filmback.filmbackGeom, filmback.filmbackGeom.lineColor, 1, 0,drawManager);
// Draw Sound Area Line
if ( filmback.soundTrackWidth != 0 )
drawLine(filmback.imageGeom.x1, filmback.imageGeom.x1, filmback.imageGeom.y1, filmback.imageGeom.y2, filmback.imageGeom.lineColor, 0,drawManager);
}
// Draw filmback safe action
if (filmback.displaySafeAction)
{
drawLines( filmback.safeActionGeom, filmback.safeActionGeom.lineColor, 1, 1, drawManager);
}
// Draw filmback safe title
if (filmback.displaySafeTitle)
{
drawLines( filmback.safeTitleGeom, filmback.safeTitleGeom.lineColor, 1, 1,drawManager);
}
// Draw the projection gate
if ( filmback.displayProjGate )
{
drawLines(filmback.projGeom, filmback.projGeom.lineColor, 1, 1,drawManager);
}
// Display horizontal line
if ( options.displayLineH )
{
drawLine( filmback.imageGeom.x1, filmback.imageGeom.x2, portGeom.y, portGeom.y, options.lineColor, 0,drawManager );
}
// Display vertical line
if ( options.displayLineV )
{
double cx = ( filmback.imageGeom.x1 + filmback.imageGeom.x2 ) / 2;
drawLine( cx, cx, filmback.imageGeom.y1, filmback.imageGeom.y2, options.lineColor, 0, drawManager );
}
// Display Horizontal Thirds
if ( options.displayThirdsH)
{
Geom g = (numAspectRatios > 0)?ars[0].aspectGeom:portGeom;
double y1 = g.y1+ ( ( g.y2 - g.y1 ) * 0.33 );
double y2 = g.y1+ ( ( g.y2 - g.y1 ) * 0.66 );
drawLine( g.x1, g.x2, y1, y1, options.lineColor, 0, drawManager);
drawLine( g.x1, g.x2, y2, y2, options.lineColor, 0, drawManager);
}
// Display Vertical Thirds
if ( options.displayThirdsV)
{
Geom g = (numAspectRatios > 0)?ars[0].aspectGeom:portGeom;
double x1 = g.x1+ ( ( g.x2 - g.x1 ) * 0.33 );
double x2 = g.x1+ ( ( g.x2 - g.x1 ) * 0.66 );
drawLine( x1, x1, g.y1, g.y2, options.lineColor, 0, drawManager);
drawLine( x2, x2, g.y1, g.y2, options.lineColor, 0, drawManager);
}
// Display crosshair
if ( options.displayCrosshair )
{
double cx = ( filmback.imageGeom.x1 + filmback.imageGeom.x2 ) / 2;
drawLine( cx-25, cx-5, portGeom.y, portGeom.y, options.lineColor, 0, drawManager );
drawLine( cx+25, cx+5, portGeom.y, portGeom.y, options.lineColor, 0, drawManager );
drawLine( cx, cx, portGeom.y-25, portGeom.y-5, options.lineColor, 0, drawManager );
drawLine( cx, cx, portGeom.y+25, portGeom.y+5, options.lineColor, 0, drawManager );
}
// Display the pad area
if (pad.usePad && pad.isPadded && pad.displayMode > 0)
{
drawLines(pad.padGeom, pad.padGeom.lineColor, 1, 0, drawManager);
}
// Draw custom text elements
if ( options.enableTextDrawing){
drawCustomTextElements(textWhenDraw, drawManager);
}
}
void spReticleLocDrawOverride::drawMask( Geom g1, Geom g2, MColor color, bool sides, MHWRender::MUIDrawManager& drawManager )
{
drawManager.beginDrawable();
drawManager.setColor(MColor(color.r, color.g, color.b, 1 - color.a));
MUintArray index;
index.append(0);
index.append(1);
index.append(3);
index.append(2);
// Bottom Mask
MPointArray bottomMask;
bottomMask.append(MPoint( g1.x1, g1.y1, 0.0));
bottomMask.append(MPoint( g1.x2, g1.y1, 0.0));
bottomMask.append(MPoint( g2.x2, g2.y1, 0.0));
bottomMask.append(MPoint( g2.x1, g2.y1, 0.0));
drawManager.mesh2d(MHWRender::MUIDrawManager::kTriStrip,bottomMask,NULL,&index);
// Top Mask
MPointArray topMask;
topMask.append(MPoint( g2.x1, g2.y2, 0.0));
topMask.append(MPoint( g2.x2, g2.y2, 0.0));
topMask.append(MPoint( g1.x2, g1.y2, 0.0));
topMask.append(MPoint( g1.x1, g1.y2, 0.0));
drawManager.mesh2d(MHWRender::MUIDrawManager::kTriStrip,topMask,NULL,&index);
if (sides)
{
// Left side mask
MPointArray leftMask;
leftMask.append(MPoint( g1.x1, g1.y1, 0.0));
leftMask.append(MPoint( g2.x1, g2.y1, 0.0));
leftMask.append(MPoint( g2.x1, g2.y2, 0.0));
leftMask.append(MPoint( g1.x1, g1.y2, 0.0));
drawManager.mesh2d(MHWRender::MUIDrawManager::kTriStrip,leftMask,NULL,&index);
// right side mask
MPointArray rightMask;
rightMask.append(MPoint( g2.x2, g2.y1, 0.0));
rightMask.append(MPoint( g1.x2, g1.y1, 0.0));
rightMask.append(MPoint( g2.x2, g2.y2, 0.0));
rightMask.append(MPoint( g1.x2, g1.y2, 0.0));
drawManager.mesh2d(MHWRender::MUIDrawManager::kTriStrip,rightMask,NULL,&index);
}
drawManager.endDrawable();
}
void spReticleLocDrawOverride::drawLine( double x1, double x2, double y1, double y2, MColor color, bool stipple, MHWRender::MUIDrawManager& drawManager )
{
drawManager.beginDrawable();
drawManager.setColor(MColor(color.r,color.g,color.b,1-color.a));
if(stipple) {
drawManager.setLineStyle(2,0x00FF);
}
drawManager.line2d(MPoint(x1,y1),MPoint(x2,y2));
drawManager.endDrawable();
}
void spReticleLocDrawOverride::drawLines( Geom g, MColor color, bool sides, bool stipple, MHWRender::MUIDrawManager& drawManager )
{
drawManager.beginDrawable();
drawManager.setColor(MColor(color.r,color.g,color.b,1-color.a));
if(stipple) {
drawManager.setLineStyle(2,0x00FF);
}
if(sides) {
drawManager.rect2d(MPoint ((g.x1 + g.x2)/2, (g.y1 + g.y2)/2),
MVector(0.0,1.0),
fabs(g.x1-g.x2)/2,fabs(g.y1-g.y2)/2);
} else {
drawManager.line2d(MPoint(g.x1,g.y1),MPoint(g.x2,g.y1));
drawManager.line2d(MPoint(g.x2,g.y2),MPoint(g.x1,g.y2));
}
drawManager.endDrawable();
}
void spReticleLocDrawOverride::drawText( MString text, double tx, double ty, MColor color, MHWRender::MUIDrawManager::TextAlignment textAlignment, MHWRender::MUIDrawManager& drawManager )
{
drawManager.beginDrawable();
drawManager.setColor(color);
drawManager.text2d(MPoint(tx,ty),text,textAlignment);
drawManager.endDrawable();
}
void spReticleLocDrawOverride::drawCustomTextElements( std::vector<TextData> textWhenDraw, MHWRender::MUIDrawManager& drawManager )
{
for(unsigned int i = 0; i < textWhenDraw.size(); ++i) {
TextData td = textWhenDraw[i];
MColor color = td.textColor;
color.a = 1.0f - color.a; // Align to VP1 behavior
drawText( td.textStr, td.textPosX, td.textPosY, color, (MHWRender::MUIDrawManager::TextAlignment)td.textAlign, drawManager);
}
}