718 lines
19 KiB
C++
718 lines
19 KiB
C++
//
|
|
// rageShaderMaya65/rageShaderUpdate.cpp
|
|
//
|
|
// Copyright (C) 1999-2006 Rockstar Games. All Rights Reserved.
|
|
//
|
|
|
|
#include <process.h>
|
|
|
|
#define REQUIRE_IOSTREAM
|
|
#pragma warning(push)
|
|
#pragma warning(disable : 4668)
|
|
#include <maya/MDagPath.h>
|
|
#include <maya/MFnMesh.h>
|
|
#include <maya/MFnSet.h>
|
|
#include <maya/M3dView.h>
|
|
#include <maya/MItDag.h>
|
|
#include <maya/MPlug.h>
|
|
#include <maya/MPlugArray.h>
|
|
#include <maya/MMatrix.h>
|
|
#include <maya/MFloatPointArray.h>
|
|
#include <maya/MFloatVectorArray.h>
|
|
#include <maya/MGlobal.h>
|
|
#include <maya/MFnCamera.h>
|
|
#pragma warning(error: 4668)
|
|
|
|
//#pragma comment(lib, "../devil/libtiff.lib")
|
|
#pragma comment(lib, "../3rdParty/Devil/lib/DevIL.lib")
|
|
#pragma comment(lib, "../3rdParty/Devil/lib/ILUT.lib")
|
|
#pragma comment(lib, "../3rdParty/Devil/lib/ILU.lib")
|
|
#include <IL/il.h>
|
|
#include <IL/ilu.h>
|
|
|
|
#pragma comment(lib, "opengl32.lib")
|
|
// #pragma comment(lib, "cg.lib")
|
|
// #pragma comment(lib, "cgGL.lib")
|
|
// #pragma comment(lib, "Cloth.lib")
|
|
#pragma comment(lib, "Foundation.lib")
|
|
// #pragma comment(lib, "Image.lib")
|
|
// #pragma comment(lib, "IMF.lib")
|
|
// #pragma comment(lib, "libfbxfilesdk.lib")
|
|
// #pragma comment(lib, "libmocap.lib")
|
|
#pragma comment(lib, "OpenMaya.lib")
|
|
// #pragma comment(lib, "OpenMayaAnim.lib")
|
|
// #pragma comment(lib, "OpenMayaFX.lib")
|
|
#pragma comment(lib, "OpenMayaRender.lib")
|
|
#pragma comment(lib, "OpenMayaUI.lib")
|
|
|
|
#include "system/timer.h"
|
|
#include "system/wndproc.h"
|
|
#include "mesh/mesh.h"
|
|
#include "mesh/serialize.h"
|
|
#include "init/modulesettings.h"
|
|
#include "file/device.h"
|
|
#include "file/asset.h"
|
|
#include "file/stream.h"
|
|
#include "file/token.h"
|
|
#include "vector/vector2.h"
|
|
#include "vector/vector3.h"
|
|
#include "vector/vector4.h"
|
|
#include "vector/matrix34.h"
|
|
#include "vector/matrix44.h"
|
|
|
|
#include "rageShaderMaterial/rageShaderMaterial.h"
|
|
#include "rageShaderMaterial/rageShaderMaterialGroup.h"
|
|
#include "rageShaderMaterial/rageShaderMaterialParamTexture.h"
|
|
#include "rageShaderViewer/rageShaderViewer.h"
|
|
#include "rageShaderViewer/ModelMaterialPairManager.h"
|
|
#include "rageShaderViewer/ModelMaterialPair.h"
|
|
|
|
#include "rageShaderUpdateManager.h"
|
|
#include "rageShaderUpdateData.h"
|
|
|
|
using namespace rage;
|
|
|
|
#define CHECK_STATUS(x) \
|
|
{ \
|
|
MStatus _maya_status = (x); \
|
|
if ( MStatus::kSuccess != _maya_status ) \
|
|
{ \
|
|
MString obStrErrorMessage(__FILE__); \
|
|
obStrErrorMessage += ":"; \
|
|
obStrErrorMessage += __LINE__; \
|
|
obStrErrorMessage += ":"; \
|
|
_maya_status.perror (obStrErrorMessage); \
|
|
} \
|
|
} \
|
|
|
|
#define DEG2RAD (PI / 180.0f)
|
|
#define RAD2DEG (180.0f / PI)
|
|
|
|
///////////////////////////////////////////////////////
|
|
// DESCRIPTION:
|
|
// The init function responsible for initalizing this class
|
|
//
|
|
///////////////////////////////////////////////////////
|
|
|
|
rageShaderUpdateData::rageShaderUpdateData()
|
|
{
|
|
// Displayf("%p Initialising m_ModelIndex to -1", this);
|
|
m_pMaterial = NULL;
|
|
m_pobModelData = NULL;
|
|
Reset();
|
|
}
|
|
|
|
///////////////////////////////////////////////////////
|
|
// DESCRIPTION:
|
|
// The init function responsible for initalizing this class
|
|
//
|
|
///////////////////////////////////////////////////////
|
|
|
|
rageShaderUpdateData::~rageShaderUpdateData()
|
|
{
|
|
delete m_pMaterial;
|
|
m_pMaterial = NULL;
|
|
if (m_pobModelData && (ModelMaterialPairManager::GetInstance()))
|
|
{
|
|
// Displayf("%p Deleting the data at m_ModelIndex %d", this, m_ModelIndex);
|
|
ModelMaterialPairManager::GetInstance()->RemoveModelData(m_pobModelData);
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////
|
|
// DESCRIPTION:
|
|
// The init function responsible for initalizing this class
|
|
//
|
|
///////////////////////////////////////////////////////
|
|
|
|
void rageShaderUpdateData::Reset()
|
|
{
|
|
m_Locked = true;
|
|
|
|
MObject null;
|
|
delete m_pMaterial;
|
|
m_pMaterial = NULL;
|
|
m_Mesh.Reset();
|
|
m_Transform = M34_IDENTITY;
|
|
|
|
for (int i=0; i<rageShaderMaterialParam::LIGHTMAP_TYPE_COUNT; i++)
|
|
{
|
|
m_LightmapFileNames[i] = "none";
|
|
}
|
|
|
|
if (m_pobModelData && (ModelMaterialPairManager::GetInstance()))
|
|
{
|
|
// Displayf("%p Deleting the data at m_ModelIndex %d", this, m_ModelIndex);
|
|
ModelMaterialPairManager::GetInstance()->RemoveModelData(m_pobModelData);
|
|
m_pobModelData = NULL;
|
|
}
|
|
m_Valid = false;
|
|
|
|
m_MeshNeedsUpdate = false;
|
|
m_TransformNeedsUpdate = false;
|
|
m_ShadersNeedsUpdate = false;
|
|
m_NeedsDeleting = false;
|
|
|
|
m_Locked = false;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////
|
|
// DESCRIPTION:
|
|
// The init function responsible for initalizing this class
|
|
//
|
|
///////////////////////////////////////////////////////
|
|
|
|
void rageShaderUpdateData::InitShaderUpdateData(int nIndex, const MObject & shaderNode, const rageShaderMaterial* pMaterial, MObject& obMayaNode)
|
|
{
|
|
m_Locked = true;
|
|
|
|
m_Valid = true;
|
|
// Displayf("%p Setting m_ModelIndex from %d to %d", this, m_ModelIndex, nIndex);
|
|
m_ModelIndex = nIndex;
|
|
|
|
delete m_pMaterial;
|
|
m_pMaterial = new rageShaderMaterial();
|
|
m_pMaterial->Copy(*pMaterial);
|
|
|
|
for (int i=0; i<m_pMaterial->GetShaderParamCount(); i++)
|
|
{
|
|
rageShaderMaterialParam * param = m_pMaterial->GetShaderParam(i);
|
|
if (!param->GetUiHidden() && param->GetType() == grcEffect::VT_TEXTURE)
|
|
{
|
|
rageShaderMaterialParamTexture* pobTextureParam = (rageShaderMaterialParamTexture *)param;
|
|
exportTexture(pobTextureParam->GetData(), pobTextureParam->GetTextureOutputFormats());
|
|
}
|
|
}
|
|
|
|
fixupLightMaps(obMayaNode, m_LightmapFileNames);
|
|
|
|
convertMesh(obMayaNode, shaderNode, m_Mesh);
|
|
|
|
m_MeshNeedsUpdate = true;
|
|
m_ShadersNeedsUpdate = true;
|
|
m_NeedsDeleting = false;
|
|
|
|
m_Locked = false;
|
|
|
|
}
|
|
|
|
///////////////////////////////////////////////////////
|
|
// DESCRIPTION:
|
|
// The init function responsible for initalizing this class
|
|
//
|
|
///////////////////////////////////////////////////////
|
|
|
|
void rageShaderUpdateData::UpdateMesh(MObject & obMeshNode, const MObject & shaderNode)
|
|
{
|
|
m_Locked = true;
|
|
|
|
fixupLightMaps(obMeshNode, m_LightmapFileNames);
|
|
|
|
convertMesh(obMeshNode, shaderNode, m_Mesh);
|
|
|
|
m_MeshNeedsUpdate = true;
|
|
|
|
m_Locked = false;
|
|
|
|
}
|
|
|
|
///////////////////////////////////////////////////////
|
|
// DESCRIPTION:
|
|
// The init function responsible for initalizing this class
|
|
//
|
|
///////////////////////////////////////////////////////
|
|
|
|
void rageShaderUpdateData::UpdateTransform(const Matrix34 & m34)
|
|
{
|
|
m_Locked = true;
|
|
|
|
m_Transform = m34;
|
|
|
|
m_TransformNeedsUpdate = true;
|
|
|
|
m_Locked = false;
|
|
|
|
}
|
|
|
|
///////////////////////////////////////////////////////
|
|
// DESCRIPTION:
|
|
// The init function responsible for initalizing this class
|
|
//
|
|
///////////////////////////////////////////////////////
|
|
|
|
void rageShaderUpdateData::UpdateShaders(const rageShaderMaterial* pMaterial)
|
|
{
|
|
m_Locked = true;
|
|
|
|
delete m_pMaterial;
|
|
m_pMaterial = new rageShaderMaterial();
|
|
m_pMaterial->Copy(*pMaterial);
|
|
|
|
for (int i=0; i<GetMaterial()->GetShaderParamCount(); i++)
|
|
{
|
|
rageShaderMaterialParam * param = GetMaterial()->GetShaderParam(i);
|
|
if (!param->GetUiHidden() && param->GetType() == grcEffect::VT_TEXTURE)
|
|
{
|
|
rageShaderMaterialParamTexture* pobTextureParam = (rageShaderMaterialParamTexture *)param;
|
|
exportTexture(pobTextureParam->GetData(), pobTextureParam->GetTextureOutputFormats());
|
|
}
|
|
}
|
|
|
|
m_ShadersNeedsUpdate = true;
|
|
|
|
m_Locked = false;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////
|
|
// DESCRIPTION:
|
|
// The init function responsible for initalizing this class
|
|
//
|
|
///////////////////////////////////////////////////////
|
|
|
|
void rageShaderUpdateData::UpdateViewer()
|
|
{
|
|
m_Locked = true;
|
|
|
|
if (m_ShadersNeedsUpdate && !ModelMaterialPairManager::GetInstance()->IsLocked(m_ModelIndex))
|
|
{
|
|
for (int i=0; i<rageShaderMaterialParam::LIGHTMAP_TYPE_COUNT; i++)
|
|
{
|
|
m_pMaterial->SetLightmapData(m_LightmapFileNames[i], i);
|
|
}
|
|
|
|
if (m_pobModelData->UpdateShaders(GetMaterial()))
|
|
{
|
|
m_ShadersNeedsUpdate = false;
|
|
}
|
|
}
|
|
|
|
if (m_MeshNeedsUpdate && !m_pobModelData->IsLocked())
|
|
{
|
|
|
|
if (m_pobModelData->SetMeshAtIndex(m_Mesh))
|
|
{
|
|
m_MeshNeedsUpdate = false;
|
|
}
|
|
}
|
|
|
|
if (m_TransformNeedsUpdate)
|
|
{
|
|
if (m_pobModelData->UpdateMeshTransform(m_Transform))
|
|
{
|
|
m_TransformNeedsUpdate = false;
|
|
}
|
|
}
|
|
|
|
m_Locked = false;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////
|
|
// DESCRIPTION:
|
|
// The function
|
|
//
|
|
///////////////////////////////////////////////////////
|
|
|
|
void rageShaderUpdateData::RefreshViewer()
|
|
{
|
|
for (int i=0; i<rageShaderMaterialParam::LIGHTMAP_TYPE_COUNT; i++)
|
|
{
|
|
m_pMaterial->SetLightmapData(m_LightmapFileNames[i], i);
|
|
}
|
|
|
|
// Displayf("%p RefreshViewer() and m_ModelIndex = %d", this, m_ModelIndex);
|
|
if(m_ModelIndex < 0)
|
|
{
|
|
Displayf("Badness");
|
|
}
|
|
m_pobModelData->UpdateShaders(m_ModelIndex, m_pMaterial);
|
|
m_pobModelData->SetMeshAtIndex(m_ModelIndex, m_Mesh);
|
|
m_pobModelData->UpdateMeshTransform(m_ModelIndex, m_Transform);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////
|
|
// DESCRIPTION:
|
|
// The equals operator for the update data do easier first
|
|
//
|
|
///////////////////////////////////////////////////////
|
|
|
|
rageShaderUpdateData & rageShaderUpdateData::operator = (const rageShaderUpdateData &d)
|
|
{
|
|
m_Locked = true;
|
|
|
|
m_Valid = d.m_Valid;
|
|
m_MeshNeedsUpdate = d.m_MeshNeedsUpdate;
|
|
m_TransformNeedsUpdate = d.m_TransformNeedsUpdate;
|
|
m_ShadersNeedsUpdate = d.m_ShadersNeedsUpdate;
|
|
m_NeedsDeleting = d.m_NeedsDeleting;
|
|
m_pobModelData = d.m_pobModelData;
|
|
m_Mesh = d.m_Mesh;
|
|
m_Transform = d.m_Transform;
|
|
delete m_pMaterial;
|
|
m_pMaterial = new rageShaderMaterial();
|
|
m_pMaterial->Copy(*(d.GetMaterial()));
|
|
|
|
m_Locked = false;
|
|
|
|
return *this;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////
|
|
// DESCRIPTION:
|
|
// This function is a static function.
|
|
//
|
|
// The function exports out the given tif to the viewer diretory
|
|
//
|
|
///////////////////////////////////////////////////////
|
|
|
|
bool rageShaderUpdateData::exportTexture(const MString& strInputTifName, const MString& strExportFormat)
|
|
{
|
|
// As an optimisation bail early if I can.
|
|
if((strInputTifName=="") || (strInputTifName == "none") || (strInputTifName == "null"))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//static int iNoOfExportTextureCalls = 0;
|
|
//iNoOfExportTextureCalls++;
|
|
//MGlobal::displayInfo("rageShaderUpdateManager::exportTexture() %d", iNoOfExportTextureCalls);
|
|
|
|
char outputTextureName[128];
|
|
fiAssetManager::BaseName(outputTextureName, sizeof(outputTextureName), fiAssetManager::FileName(strInputTifName.asChar()));
|
|
|
|
char outputTextureFileName[512];
|
|
strcpy(outputTextureFileName, rageShaderUpdateManager::GetInstance()->GetRageShaderAssetDirectory());
|
|
strcat(outputTextureFileName, outputTextureName);
|
|
strcat(outputTextureFileName, ".dds");
|
|
|
|
// Check to see if the file exists
|
|
u64 time = fiDeviceLocal::GetInstance().GetFileTime(outputTextureFileName);
|
|
if (time && time >= fiDeviceLocal::GetInstance().GetFileTime(strInputTifName.asChar()))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Get the export format to use, by default, just use the first format for now
|
|
MStringArray astrPlatformAndFormatPairs;
|
|
strExportFormat.split(';', astrPlatformAndFormatPairs);
|
|
MStringArray astrPlatformAndFormat;
|
|
astrPlatformAndFormatPairs[0].split('=', astrPlatformAndFormat);
|
|
MString strDestinationFormat = astrPlatformAndFormat[astrPlatformAndFormat.length() - 1];
|
|
|
|
// Use the texture converter to convert it
|
|
MString strArguments("-f "+ strDestinationFormat +" \""+ strInputTifName +"\" \""+ MString(outputTextureFileName) +"\"");
|
|
MGlobal::displayInfo("rageTextureConvert.exe "+ strArguments);
|
|
_flushall();
|
|
// system(strCmd.asChar());
|
|
_spawnlp(_P_WAIT, "rageTextureConvert.exe", "rageTextureConvert.exe", strArguments.asChar(), NULL);
|
|
|
|
return false;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////
|
|
// DESCRIPTION:
|
|
// This function gets called by updateMesh()
|
|
//
|
|
// The function fixes all the lightmap texture pointers
|
|
//
|
|
///////////////////////////////////////////////////////
|
|
|
|
bool rageShaderUpdateData::fixupLightMaps(MObject& obMayaNode, ConstString * lightmapFileNames)
|
|
{
|
|
char command[1024];
|
|
MFnMesh obFnMeshNode(obMayaNode);
|
|
|
|
MStringArray bakeSet;
|
|
sprintf(command, "listConnections -type textureBakeSet %s", obFnMeshNode.fullPathName().asChar());
|
|
MGlobal::executeCommand(command, bakeSet);
|
|
|
|
if (bakeSet.length() > 0)
|
|
{
|
|
MString path;
|
|
sprintf(command, "getAttr %s.LightMapPath", bakeSet[0].asChar());
|
|
MGlobal::executeCommand(command, path);
|
|
|
|
MString name;
|
|
sprintf(command, "getAttr %s.prefix", bakeSet[0].asChar());
|
|
MGlobal::executeCommand(command, name);
|
|
|
|
// Copy the lightmaps to the output directory
|
|
char outputTextureFileName[1024];
|
|
for (int i=0; i<rageShaderMaterialParam::LIGHTMAP_TYPE_COUNT; i++)
|
|
{
|
|
lightmapFileNames[i] = rageShaderMaterial::GetLightMapFileName(path.asChar(), name.asChar(), i);
|
|
|
|
const char* pcRageShaderAssetDirectory = rageShaderUpdateManager::GetInstance()->GetRageShaderAssetDirectory();
|
|
const char* pcLightmapPathAndFileName = lightmapFileNames[i];
|
|
const char* pcLightmapFileName = fiAssetManager::FileName(pcLightmapPathAndFileName);
|
|
sprintf(outputTextureFileName, "%s%s", pcRageShaderAssetDirectory, pcLightmapFileName);
|
|
MGlobal::displayInfo(MString("Copying light map ")+ lightmapFileNames[i] +" to "+ outputTextureFileName);
|
|
int bSuccess = CopyFile(lightmapFileNames[i], outputTextureFileName, false);
|
|
if(!bSuccess)
|
|
{
|
|
LPVOID lpMsgBuf;
|
|
FormatMessage(
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
NULL,
|
|
GetLastError(),
|
|
0, // Default language
|
|
(LPTSTR) &lpMsgBuf,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
// Display the string.
|
|
MGlobal::displayInfo("Copy failed because "+ MString((LPTSTR)lpMsgBuf));
|
|
|
|
// Free the buffer.
|
|
LocalFree( lpMsgBuf );
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////
|
|
// DESCRIPTION:
|
|
// This function gets called by updateMesh()
|
|
//
|
|
// The function converts a maya MFnMesh object into a
|
|
// rage mshMesh object.
|
|
//
|
|
///////////////////////////////////////////////////////
|
|
|
|
bool rageShaderUpdateData::convertMesh(MObject& obMayaNode, const MObject & shaderNode, mshMesh & rageMesh)
|
|
{
|
|
// Reset the out mesh
|
|
rageMesh.Reset();
|
|
MFnMesh obFnMeshNode(obMayaNode);
|
|
|
|
MObjectArray shaders;
|
|
MIntArray indices;
|
|
if (obFnMeshNode.getConnectedShaders(0,shaders,indices) != MS::kSuccess)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
MStringArray uvsetnames;
|
|
obFnMeshNode.getUVSetNames(uvsetnames);
|
|
|
|
int uvSetCount = 0;
|
|
atArray <ConstString> uvSetNames;
|
|
atArray <ConstString> fixedUvSetNames;
|
|
uvSetNames.Resize(uvsetnames.length());
|
|
for (int i=0; i<uvSetNames.GetCount(); i++)
|
|
{
|
|
uvSetNames[i] = uvsetnames[i].asChar();
|
|
}
|
|
GetMaterial()->UpdateUvSetNames(uvSetNames, fixedUvSetNames);
|
|
uvSetCount = fixedUvSetNames.GetCount();
|
|
|
|
atArray <int> aMaterialDataIndices;
|
|
atArray <Vector2> aMaterialData;
|
|
|
|
for (int i=0; i<GetMaterial()->GetParamCount(); i++)
|
|
{
|
|
int index = GetMaterial()->GetParam(i)->GetMaterialDataUvSetIndex();
|
|
if (index >= 0)
|
|
{
|
|
if (aMaterialDataIndices.Find(index)>=0)
|
|
{
|
|
char buffer[256];
|
|
formatf(buffer, sizeof(buffer), "Invalid param %s more then one material id references uv set %d", GetMaterial()->GetParam(i)->GetUiName(), index);
|
|
MGlobal::displayError(buffer);
|
|
continue;
|
|
}
|
|
|
|
aMaterialDataIndices.Grow() = index;
|
|
GetMaterial()->GetParam(i)->SetMaterialData(aMaterialData.Grow());
|
|
uvSetCount = ((index+1) > uvSetCount) ? (index+1) : uvSetCount;
|
|
}
|
|
}
|
|
|
|
MStringArray asColorSetNames;
|
|
obFnMeshNode.getColorSetNames(asColorSetNames);
|
|
|
|
MColorArray colors0;
|
|
if (asColorSetNames.length() > 0)
|
|
obFnMeshNode.getFaceVertexColors(colors0, &asColorSetNames[0]);
|
|
|
|
MColorArray colors1;
|
|
if (asColorSetNames.length() > 1)
|
|
obFnMeshNode.getFaceVertexColors(colors1, &asColorSetNames[1]);
|
|
|
|
MColorArray colors2;
|
|
if (asColorSetNames.length() > 2)
|
|
obFnMeshNode.getFaceVertexColors(colors2, &asColorSetNames[2]);
|
|
|
|
// We only need one material per RAGE mesh
|
|
char mtlIndexName[32];
|
|
rageShaderMaterialGroup::SetMaterialIndex(mtlIndexName, 0);
|
|
|
|
mshMaterial & rageMtl = rageMesh.NewMtl();
|
|
rageMtl.Name = mtlIndexName;
|
|
|
|
for (int p=0; p<obFnMeshNode.numPolygons(); p++)
|
|
{
|
|
MIntArray vtxList;
|
|
obFnMeshNode.getPolygonVertices(p,vtxList);
|
|
|
|
if ((u32)p > indices.length() || indices[p] == -1)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (shaders[indices[p]] != shaderNode)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
MStatus status;
|
|
MFnDependencyNode shadingEngineNode(shaders[indices[p]], &status);
|
|
if (status.error())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
MFnSet shaderSet(shaders[indices[p]],&status);
|
|
if (status.error())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
MPlug surfaceShader = shaderSet.findPlug("surfaceShader");
|
|
if (surfaceShader.isNull())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
MPlugArray plugs;
|
|
surfaceShader.connectedTo(plugs, true, false);
|
|
if (plugs.length() == 0)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
MObject obj = plugs[0].node();
|
|
MFnDependencyNode shaderNode(obj, &status);
|
|
if (status.error())
|
|
{
|
|
continue;
|
|
}
|
|
|
|
mshPrimitive &prim = rageMtl.Prim.Append();
|
|
prim.Type = mshPOLYGON;
|
|
prim.Priority = rageMtl.Priority;
|
|
|
|
for (unsigned v=0; v<vtxList.length(); v++)
|
|
{
|
|
int idx = vtxList[v];
|
|
MPoint pos;
|
|
obFnMeshNode.getPoint(idx, pos, MSpace::kWorld);
|
|
|
|
Vector3 P((float)pos.x, (float)pos.y, (float)pos.z);
|
|
|
|
MVector MN;
|
|
obFnMeshNode.getFaceVertexNormal(p, idx, MN, MSpace::kWorld);
|
|
Vector3 N(float(MN.x),float(MN.y),float(MN.z));
|
|
|
|
// We are going to initalize the texture coords
|
|
atArray <Vector2> TC;
|
|
TC.Resize(uvSetCount);
|
|
for (int i=0; i<uvSetCount; i++)
|
|
{
|
|
bool foundData = false;
|
|
for (int j=0; j<aMaterialDataIndices.GetCount(); j++)
|
|
{
|
|
if (aMaterialDataIndices[j] == i)
|
|
{
|
|
TC[i] = aMaterialData[j];
|
|
foundData = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!foundData)
|
|
{
|
|
MString uvSetName = fixedUvSetNames[i];
|
|
float fXTexCoord;
|
|
float fYTexCoord;
|
|
obFnMeshNode.getPolygonUV(p,v,fXTexCoord,fYTexCoord,&uvSetName);
|
|
// Check the values make sense, sometime Maya gives me madness
|
|
if(!FPIsFinite(fXTexCoord)) fXTexCoord = 0.0f;
|
|
if(!FPIsFinite(fYTexCoord)) fYTexCoord = 0.0f;
|
|
TC[i].x = fXTexCoord;
|
|
TC[i].y = fYTexCoord;
|
|
}
|
|
}
|
|
|
|
int ci = -1;
|
|
Vector4 C0(1,1,1,1);
|
|
if (colors0.length())
|
|
{
|
|
obFnMeshNode.getFaceVertexColorIndex(p,v,ci, &asColorSetNames[0]);
|
|
if (ci != -1)
|
|
{
|
|
C0.x = colors0[ci].r;
|
|
C0.y = colors0[ci].g;
|
|
C0.z = colors0[ci].b;
|
|
C0.w = colors0[ci].a;
|
|
if (C0.x == -1 && C0.y == -1 && C0.z == -1 && C0.w == -1)
|
|
{
|
|
C0.Set(1,1,1,1);
|
|
}
|
|
}
|
|
}
|
|
|
|
Vector4 C1(1,1,1,1);
|
|
if (colors1.length())
|
|
{
|
|
obFnMeshNode.getFaceVertexColorIndex(p,v,ci, &asColorSetNames[1]);
|
|
if (ci != -1)
|
|
{
|
|
C1.x = colors1[ci].r;
|
|
C1.y = colors1[ci].g;
|
|
C1.z = colors1[ci].b;
|
|
C1.w = colors1[ci].a;
|
|
if (C1.x == -1 && C1.y == -1 && C1.z == -1 && C1.w == -1)
|
|
{
|
|
C1.Set(1,1,1,1);
|
|
}
|
|
}
|
|
}
|
|
|
|
Vector4 C2(1,1,1,1);
|
|
if (colors2.length())
|
|
{
|
|
obFnMeshNode.getFaceVertexColorIndex(p,v,ci, &asColorSetNames[2]);
|
|
if (ci != -1)
|
|
{
|
|
C2.x = colors2[ci].r;
|
|
C2.y = colors2[ci].g;
|
|
C2.z = colors2[ci].b;
|
|
C2.w = colors2[ci].a;
|
|
if (C2.x == -1 && C2.y == -1 && C2.z == -1 && C2.w == -1)
|
|
{
|
|
C2.Set(1,1,1,1);
|
|
}
|
|
}
|
|
}
|
|
|
|
mshBinding B;
|
|
B.Reset();
|
|
|
|
mshIndex vertIdx = rageMtl.AddVertex(P,B,N,C0,C1,C2, TC.GetCount(),(TC.GetCount()>0) ? &TC[0] : NULL);
|
|
prim.Idx.Append() = vertIdx;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|