459 lines
15 KiB
C++
459 lines
15 KiB
C++
#include "file/token.h"
|
|
#include "file/stream.h"
|
|
|
|
#include "shaderMaterial/shaderMaterialGeoParamValueTexture.h"
|
|
#include "shaderMaterial/shaderMaterialGeoParamDescriptionTexture.h"
|
|
#include "rageShaderMaterialMayaParam.h"
|
|
#include "rageShaderMaterialMaya.h"
|
|
#include "rageShaderMaya65.h"
|
|
|
|
#define REQUIRE_IOSTREAM
|
|
#pragma warning(push)
|
|
#pragma warning(disable : 4668)
|
|
#include <maya/MPlug.h>
|
|
#include <maya/MPlugArray.h>
|
|
#include <maya/MFnAttribute.h>
|
|
#include <maya/MItDependencyNodes.h>
|
|
#include <maya/MSelectionList.h>
|
|
#include <maya/MDGModifier.h>
|
|
#pragma warning(pop)
|
|
|
|
using namespace rage;
|
|
|
|
extern bool g_bDisplayMGlobalExecuteCommands;
|
|
|
|
|
|
bool rageShaderMaterialMaya::AddToMayaNode(MObject obNode, const rageShaderMaterial& obMaterial, bool* DeletedExistingDataDuringCreation)
|
|
{
|
|
MFnDependencyNode obFnThis(obNode);
|
|
|
|
Assert(DeletedExistingDataDuringCreation);
|
|
|
|
(*DeletedExistingDataDuringCreation) = false;
|
|
|
|
if (!obFnThis.isLocked() && !obFnThis.isFromReferencedFile())
|
|
{
|
|
if (obFnThis.attributeCount())
|
|
{
|
|
bool attribsAreEqual = true;
|
|
// Check the shader attributes
|
|
for (int i=0; i<obMaterial.GetShaderParamCount(); i++)
|
|
{
|
|
if (!rageShaderMaterialMayaParam::IsAttributeSameValue(obNode, obMaterial.GetShaderParam(i)))
|
|
{
|
|
attribsAreEqual = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (attribsAreEqual)
|
|
{
|
|
//All the same so exit
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
if (MFnDependencyNode(obNode).isLocked())
|
|
{
|
|
//message that says we are locked so no connections changed
|
|
Displayf("message that says we are locked so no connections changed");
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Texture overide support
|
|
MPlug obTextureOveridePlug = obFnThis.findPlug("TextureOveride");
|
|
bool bUseExistingTextureNodes;
|
|
obTextureOveridePlug.getValue(bUseExistingTextureNodes);
|
|
|
|
// Delete all the old attrs
|
|
for(unsigned int i=0; i<obFnThis.attributeCount(); i++ )
|
|
{
|
|
bool bDeleteAttribute = false;
|
|
MFnAttribute obFnAttribute(obFnThis.attribute(i));
|
|
if(obFnAttribute.isDynamic())
|
|
{
|
|
// It is a dynamic attribute, so maybe delete it
|
|
// Is it a child attribute?
|
|
bool bChildAttribute = (obFnAttribute.parent() != MObject::kNullObj);
|
|
if(!bChildAttribute)
|
|
{
|
|
// It is a dynamic attribute and not a child attribute, so maybe delete it
|
|
if(bUseExistingTextureNodes && obFnAttribute.isUsedAsColor())
|
|
{
|
|
// It is a dynamic attribute, not a child attribute, it is a texture attribute and might have to retain it
|
|
// Does a param with the same name exist in the given material
|
|
bDeleteAttribute = true;
|
|
MString strExistingParamName = obFnAttribute.name();
|
|
for (int j=0; j<obMaterial.GetParamCount(); j++)
|
|
{
|
|
// Set the values
|
|
const shaderMaterialGeoParamValue * param = obMaterial.GetParam(j);
|
|
// Displayf("(\"%s\" == \"%s\") = %d", strExistingParamName.asChar(), param->GetName(), (strExistingParamName == MString(param->GetName())));
|
|
if(strExistingParamName == MString(param->GetParamDescription()->GetUIName()))
|
|
{
|
|
// It still exists, so don't kill it
|
|
bDeleteAttribute = false;
|
|
break;
|
|
}
|
|
}
|
|
if(bDeleteAttribute)
|
|
{
|
|
// Displayf("Going to delete %s", obFnAttribute.name().asChar());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// It is a dynamic attribute, not a child attribute and I do not have to retain the existing textures, so delete it!
|
|
bDeleteAttribute = true;
|
|
}
|
|
}
|
|
}
|
|
if(bDeleteAttribute)
|
|
{
|
|
//(*DeletedExistingDataDuringCreation) = true;
|
|
// Safe to delete
|
|
//Displayf("Deleting %s", obFnAttribute.name().asChar());
|
|
MStatus obStatus = obFnThis.removeAttribute(obFnThis.attribute(i), MFnDependencyNode::kLocalDynamicAttr);
|
|
if(obStatus != MS::kSuccess)
|
|
{
|
|
Displayf("An error occured removing attribute %s from node %s : %s %s %d", obFnAttribute.name().asChar(), obFnThis.name().asChar(), obStatus.errorString().asChar(), __FILE__, __LINE__);
|
|
return false;
|
|
}
|
|
i--;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add the new shader attributes
|
|
for (int i=0; i<obMaterial.GetShaderParamCount(); i++)
|
|
{
|
|
MPlug obExistingPlug = obFnThis.findPlug(obMaterial.GetShaderParam(i)->GetParamDescription()->GetUIName());
|
|
if(obExistingPlug.isNull())
|
|
{
|
|
//Displayf("Add Attribute [%s]", obMaterial.GetShaderParam(i)->GetParamDescription()->GetUIName());
|
|
// Don't exist, so add me
|
|
//if (!rageShaderMaya::getIgnoreReferencedNodesDuringWireUpTextures())
|
|
//{
|
|
rageShaderMaterialMayaParam::AddAttributesToMayaNode(obNode, obMaterial.GetShaderParam(i));
|
|
//}
|
|
}
|
|
else
|
|
{
|
|
//Displayf("Not going to add %s because already exists", obExistingPlug.name().asChar());
|
|
}
|
|
}
|
|
|
|
// Restore the locked-ness
|
|
return true;
|
|
}
|
|
|
|
bool rageShaderMaterialMaya::RemoveFromMayaNode(MObject obNode, const rageShaderMaterial& /*obMaterial*/)
|
|
{
|
|
MFnDependencyNode obFnThis(obNode);
|
|
if (obFnThis.isLocked())
|
|
{
|
|
//nothing we can do
|
|
return true;
|
|
}
|
|
|
|
MPlug obTextureOveridePlug = obFnThis.findPlug("TextureOveride");
|
|
bool bUseExistingTextureNodes;
|
|
obTextureOveridePlug.getValue(bUseExistingTextureNodes);
|
|
|
|
// Delete all the attrs of the material
|
|
for(unsigned int i=0; i<obFnThis.attributeCount(); i++ )
|
|
{
|
|
bool bDeleteAttribute = false;
|
|
MFnAttribute obFnAttribute(obFnThis.attribute(i));
|
|
if(obFnAttribute.isDynamic())
|
|
{
|
|
// It is a dynamic attribute, so maybe delete it
|
|
// Is it a child attribute?
|
|
bool bChildAttribute = (obFnAttribute.parent() != MObject::kNullObj);
|
|
if(!bChildAttribute)
|
|
{
|
|
if(bUseExistingTextureNodes && obFnAttribute.isUsedAsColor())
|
|
{
|
|
bDeleteAttribute = false;
|
|
}
|
|
else
|
|
{
|
|
bDeleteAttribute = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(bDeleteAttribute)
|
|
{
|
|
// Safe to delete
|
|
//Displayf("Deleting %s", obFnAttribute.name().asChar());
|
|
MStatus obStatus = obFnThis.removeAttribute(obFnThis.attribute(i), MFnDependencyNode::kLocalDynamicAttr);
|
|
if(obStatus != MS::kSuccess)
|
|
{
|
|
Errorf("An error occured removing attribute %s from node %s : %s %s %d", obFnAttribute.name().asChar(), obFnThis.name().asChar(), obStatus.errorString().asChar(), __FILE__, __LINE__);
|
|
return false;
|
|
}
|
|
i--;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool rageShaderMaterialMaya::WireUpTextureNode(MObject obNode, const shaderMaterialGeoParamValue& obParam)
|
|
{
|
|
// Initialize the dependency object
|
|
MFnDependencyNode obFnShaderNode(obNode);
|
|
//Displayf("Node %s", obFnShaderNode.name().asChar());
|
|
if (obFnShaderNode.isLocked())
|
|
{
|
|
//Displayf("Node %s is locked no texture connection attempted\n", obFnShaderNode.name().asChar());
|
|
//early out cause we cant change anything that is locked.
|
|
return true;
|
|
}
|
|
|
|
if (obFnShaderNode.isFromReferencedFile())
|
|
{
|
|
//Displayf("Node %s is from referenced file, no texture connection attempted\n", obFnShaderNode.name().asChar());
|
|
//early out cause we cant change anything that is from a referenced file.
|
|
return true;
|
|
}
|
|
|
|
// Got a valid texture param
|
|
shaderMaterialGeoParamValueTexture* pobTextureParam = (shaderMaterialGeoParamValueTexture*) &obParam;
|
|
const shaderMaterialGeoParamDescriptionTexture* textureDesc = (const shaderMaterialGeoParamDescriptionTexture*)pobTextureParam->GetParamDescription();
|
|
|
|
Assert(textureDesc);
|
|
|
|
// Get texture name
|
|
const char * pcTextureFilename = pobTextureParam->GetValue();
|
|
|
|
if (!pcTextureFilename)
|
|
{
|
|
Errorf("No texture name from RSM: %s PARAM: %s\n", obFnShaderNode.name().asChar(), obParam.GetName());
|
|
return false;
|
|
}
|
|
|
|
if (stricmp(pcTextureFilename, "none"))
|
|
{
|
|
//Displayf("Using Texture: %s from RSM: %s PARAM: %s", pcTextureFilename, obFnShaderNode.name().asChar(), obParam.GetName());
|
|
|
|
MItDependencyNodes depIterator( MFn::kFileTexture);
|
|
// Do I already have a file node matching that texture file name?
|
|
MObject obFileNode = MObject::kNullObj;
|
|
MString strFileNodeName = "";
|
|
MStatus obStatus;
|
|
for (; !depIterator.isDone(); depIterator.next() )
|
|
{
|
|
MFnDependencyNode node( depIterator.item() );
|
|
if (rageShaderMaya::getIgnoreReferencedNodesDuringWireUpTextures() && node.isFromReferencedFile())
|
|
{
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
MPlug plug = node.findPlug("fileTextureName");
|
|
if (!plug.isNull())
|
|
{
|
|
MString textureFileName;
|
|
plug.getValue(textureFileName);
|
|
|
|
//Displayf("Comparing %s and %s (%s)", pcTextureFilename, textureFileName.asChar());
|
|
|
|
if (stricmp(fiAssetManager::FileName(textureFileName.asChar()), fiAssetManager::FileName(pcTextureFilename))==0)
|
|
{
|
|
//check the full path to make sure it is the same.
|
|
if (stricmp(textureFileName.asChar(), pcTextureFilename)==0)
|
|
{
|
|
strFileNodeName = node.name();
|
|
obFileNode = depIterator.item();
|
|
//Displayf("Found file node: %s", strFileNodeName.asChar());
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(strFileNodeName == "")
|
|
{
|
|
// Unable to find an existing filename that works, so make one
|
|
// Can't find a good node, so create the maya texture file node
|
|
MGlobal::executeCommand("shadingNode -asTexture file", strFileNodeName, g_bDisplayMGlobalExecuteCommands);
|
|
|
|
// Convert node name into actual API node
|
|
MSelectionList list;
|
|
list.add(strFileNodeName);
|
|
list.getDependNode(0, obFileNode);
|
|
|
|
// Set the filename of the new node
|
|
MFnDependencyNode obFnFileNode(obFileNode);
|
|
MPlug obFileTextureNamePlug = obFnFileNode.findPlug("fileTextureName");
|
|
obFileTextureNamePlug.setValue(pcTextureFilename);
|
|
|
|
//Displayf("Create File node with texture %s", pcTextureFilename);
|
|
}
|
|
|
|
// Get plugs for connections
|
|
MFnDependencyNode obFnFileNode( obFileNode );
|
|
MPlug obOutColorPlug = obFnFileNode.findPlug("outColor", &obStatus);
|
|
if(obOutColorPlug.isNull())
|
|
{
|
|
// Oh dear
|
|
MGlobal::displayError("Unable to find outColor attribute on \""+ obFnFileNode.name() +"\"");
|
|
return false;
|
|
}
|
|
CHECK_STATUS( obStatus );
|
|
|
|
MString strTextureParamUIName = pobTextureParam->GetParamDescription()->GetUIName();
|
|
MString strSafeTextureParamUIName = rageShaderMaterialMayaParam::GetCleanVersionOfString(strTextureParamUIName.asChar());
|
|
MPlug obInColorPlug = obFnShaderNode.findPlug(strSafeTextureParamUIName, &obStatus);
|
|
if(obInColorPlug.isNull())
|
|
{
|
|
// Oh dear
|
|
MGlobal::displayError("Unable to find \""+ strSafeTextureParamUIName +"\" attribute on \""+ obFnShaderNode.name() +"\"");
|
|
return false;
|
|
}
|
|
CHECK_STATUS( obStatus );
|
|
|
|
|
|
// Make sure I'm not already connected
|
|
MPlugArray aobPlugsConnectedToOutColor;
|
|
obOutColorPlug.connectedTo(aobPlugsConnectedToOutColor, true, true, &obStatus);
|
|
CHECK_STATUS( obStatus );
|
|
|
|
MPlugArray aobPlugsConnectedToInColor;
|
|
obInColorPlug.connectedTo(aobPlugsConnectedToInColor, true, true, &obStatus);
|
|
CHECK_STATUS( obStatus );
|
|
|
|
//Displayf("aobPlugsConnectedToInColor.length() = %d", aobPlugsConnectedToInColor.length());
|
|
//for(unsigned i=0; i<aobPlugsConnectedToInColor.length(); i++)
|
|
//{
|
|
// Displayf("aobPlugsConnectedToInColor[%d] = %s\n", i, aobPlugsConnectedToInColor[i].name().asChar());
|
|
//}
|
|
|
|
//Displayf("aobPlugsConnectedToOutColor.length() = %d", aobPlugsConnectedToOutColor.length());
|
|
//for(unsigned i=0; i<aobPlugsConnectedToOutColor.length(); i++)
|
|
//{
|
|
// Displayf("aobPlugsConnectedToOutColor[%d] = %s\n", i, aobPlugsConnectedToOutColor[i].name().asChar());
|
|
//}
|
|
|
|
MString plugName = obFnShaderNode.name();
|
|
plugName += ".";
|
|
plugName += rageShaderMaterialMayaParam::GetCleanVersionOfString(textureDesc->GetUIName());
|
|
bool bAlreadyConnected = false;
|
|
for(unsigned i=0; i<aobPlugsConnectedToOutColor.length(); i++)
|
|
{
|
|
if (!stricmp(plugName.asChar(), aobPlugsConnectedToOutColor[i].name().asChar()))
|
|
{
|
|
MPlugArray aobPlugsConnectedToOutColorPlug;
|
|
aobPlugsConnectedToOutColor[i].connectedTo(aobPlugsConnectedToOutColorPlug, true, true, &obStatus);
|
|
|
|
//Displayf("aobPlugsConnectedToOutColorPlug.length() = %d", aobPlugsConnectedToOutColorPlug.length());
|
|
//for(unsigned j=0; j<aobPlugsConnectedToOutColorPlug.length(); j++)
|
|
//{
|
|
// Displayf("aobPlugsConnectedToOutColorPlug[%d] = %s\n", j, aobPlugsConnectedToOutColorPlug[j].name().asChar());
|
|
//}
|
|
|
|
for(unsigned j=0; j<aobPlugsConnectedToOutColorPlug.length(); j++)
|
|
{
|
|
for(unsigned k=0; k<aobPlugsConnectedToInColor.length(); k++)
|
|
{
|
|
//Displayf("Comparing %s and %s\n", aobPlugsConnectedToInColor[k].name().asChar(), aobPlugsConnectedToOutColorPlug[j].name().asChar());
|
|
if(aobPlugsConnectedToInColor[k] == aobPlugsConnectedToOutColorPlug[j])
|
|
{
|
|
// Already connected so forget about it
|
|
//Displayf("\nAlready connected\n");
|
|
bAlreadyConnected = true;
|
|
break;
|
|
}
|
|
}
|
|
if (bAlreadyConnected)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (bAlreadyConnected)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(!bAlreadyConnected)
|
|
{
|
|
MDGModifier obModifier;
|
|
|
|
if (obInColorPlug.isLocked())
|
|
{
|
|
//Displayf("Atrribute %s is locked no texture connection attempted\n", obInColorPlug.name().asChar());
|
|
//early out cause we cant change anything that is locked.
|
|
return true;
|
|
}
|
|
|
|
if (obOutColorPlug.isLocked())
|
|
{
|
|
//Displayf("Atrribute %s is locked no texture connection attempted\n", obOutColorPlug.name().asChar());
|
|
//early out cause we cant change anything that is locked.
|
|
return true;
|
|
}
|
|
|
|
MFnAttribute obA1( obInColorPlug.attribute() );
|
|
if (!obA1.isWritable())
|
|
{
|
|
//Displayf("Atrribute %s from plug %s is not writable no texture connection attempted\n", obA1.name().asChar(), obInColorPlug.name().asChar());
|
|
//early out cause we cant change anything that is locked.
|
|
return true;
|
|
}
|
|
|
|
|
|
//Having to force this connection seems wrong, but we are running into an error case
|
|
// which is that the file nodes' outColor attribute (obOutColorPlug) is not writable
|
|
// which is causing the connection to error resulting in the connection not happening.
|
|
//By forcing the connection we get the desired effect of shared file nodes.
|
|
//The command bellow forces the connection between the file node and the RSM without an error.
|
|
//The code above this is not changed because we still want all checks to happen to protect
|
|
// referenced in RSM nodes and other "locked" cases.
|
|
//Executing this script line is the same as doing the drag drop step to link a file node
|
|
// to an RSM.
|
|
|
|
//connectAttr -force DiffuseTexture2.outColor p_gen_basketIndian01_.DiffuseTexture;
|
|
MString command = "connectAttr -force ";
|
|
command += obOutColorPlug.name();
|
|
command += " ";
|
|
command += obInColorPlug.name();
|
|
command += ";";
|
|
|
|
// Connect the attributes
|
|
//Displayf("%d Connecting %s -> %s", (int)__LINE__, obOutColorPlug.name().asChar(), obInColorPlug.name().asChar());
|
|
CHECK_STATUS(obModifier.commandToExecute(command));
|
|
MStatus obStatus = obModifier.doIt();
|
|
CHECK_STATUS(obStatus);
|
|
if(obStatus != MS::kSuccess)
|
|
{
|
|
// An error occured
|
|
Displayf("An error occurred connecting %s to %s\n", obOutColorPlug.name().asChar(), obInColorPlug.name().asChar());
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool rageShaderMaterialMaya::ExpandTextureNodes(MObject obNode, const rageShaderMaterial& obMaterial)
|
|
{
|
|
// Wire up all the nodes
|
|
for (int iParam=0; iParam<obMaterial.GetParamCount(); iParam++)
|
|
{
|
|
// Lets find all the texture pobParameters
|
|
const shaderMaterialGeoParamValue * pobParam = obMaterial.GetParam(iParam);
|
|
if (pobParam && pobParam->GetType() == grcEffect::VT_TEXTURE)
|
|
{
|
|
WireUpTextureNode(obNode, *pobParam);
|
|
}
|
|
}
|
|
return true;
|
|
}
|