added everything

This commit is contained in:
Metario
2017-04-17 06:17:10 -06:00
commit 9c6ff74f19
6121 changed files with 1625704 additions and 0 deletions

View File

@ -0,0 +1,262 @@
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#ifdef _MSC_VER
#pragma warning(disable : 4786)
#endif
#include <maya/MPxFileTranslator.h>
#include <maya/MObject.h>
#include <maya/MGlobal.h>
#include <maya/MString.h>
#include <maya/MFnPlugin.h>
#include <fstream>
#include "appConfig.h"
#include "mayaSceneEnum.h"
class exportDTS : public MPxFileTranslator {
public:
exportDTS ();
virtual ~exportDTS ();
virtual MStatus writer (
const MFileObject &file,
const MString &optionsString,
FileAccessMode mode
);
public:
virtual bool haveWriteMethod () const;
virtual MString defaultExtension () const;
virtual MFileKind identifyFile (
const MFileObject &,
const char *buffer,
short size
) const;
static MStatus writeTS(const MFileObject &file,
const MString &optionsString,
FileAccessMode mode,
bool seqOnly);
static void * creator ();
};
class exportDSQ : public MPxFileTranslator {
public:
exportDSQ ();
virtual ~exportDSQ ();
virtual MStatus writer (
const MFileObject &file,
const MString &optionsString,
FileAccessMode mode
);
public:
virtual bool haveWriteMethod () const;
virtual MString defaultExtension () const;
virtual MFileKind identifyFile (
const MFileObject &,
const char *buffer,
short size
) const;
static void * creator ();
};
//--------------------------------------------------------------------------------
// Export functionality
//--------------------------------------------------------------------------------
MStatus exportDTS::writeTS(const MFileObject &file,const MString &optionsString,FileAccessMode mode, bool seqOnly)
{
// start error logging, setup status for failure
MStatus status = MS::kFailure;
MGlobal::startErrorLogging();
MString fileNameStr = file.fullName();
const char * name = fileNameStr.asChar();
if (!DTS::AppConfig::SetDumpFile(name))
{
MGlobal::doErrorLogEntry(DTS::avar("Unable to create dumpfile for shape \"%s\".",name));
MGlobal::stopErrorLogging();
return status;
}
if (seqOnly)
{
DTS::AppConfig::SetExportOptimized(false);
DTS::AppConfig::PrintDump(-1,"Setting up for sequence export only (dsq) -- turning off optimized meshes");
}
else
{
DTS::AppConfig::SetExportOptimized(true);
DTS::AppConfig::PrintDump(-1,"Setting up for full export (dts) -- turning on optimized meshes");
}
// Get config file if it exists...
MString sourceFile;
MGlobal::executeCommand("file -q -sn;",sourceFile);
DTS::AppConfig::SearchConfigFile(sourceFile.asChar());
DTS::MayaSceneEnum mayaSceneEnum;
DTS::Shape * shape = mayaSceneEnum.processScene();
if (!DTS::AppConfig::IsExportError())
{
std::ofstream os;
// not sure why maya sometimes doesn't handle this, but on occassion
// we get multiple dts's in filename if user selects a dts file
// when saving. Get rid of the extra dts here. [Or dsq]
char * delMe = NULL;
const char * extraEXT = seqOnly ? ".dsq.dsq" : ".dts.dts";
if (strlen(name)>strlen(extraEXT) && !_stricmp(extraEXT,name + strlen(name) - strlen(extraEXT)))
{
delMe = new char [strlen(name)+1];
delMe[strlen(name)-4] = '\0';
name = delMe;
}
os.open(name,std::ofstream::binary);
if (!seqOnly)
shape->save(os);
else
shape->saveSequences(os);
os.close();
delete [] delMe;
}
DTS::AppConfig::CloseDumpFile();
delete shape;
if (DTS::AppConfig::IsExportError())
{
MGlobal::doErrorLogEntry(DTS::AppConfig::GetExportError());
const char * cmdPattern = "confirmDialog -t \"Error Exporting DTS Shape\" -m \"%s\"";
char * confirmDialog = new char[strlen(DTS::AppConfig::GetExportError()) + strlen(cmdPattern) + 1];
sprintf(confirmDialog,cmdPattern,DTS::AppConfig::GetExportError());
MGlobal::executeCommand(confirmDialog,true);
MGlobal::displayError(MString(DTS::AppConfig::GetExportError()));
}
else
status = MS::kSuccess;
// stop error logging, return status
MGlobal::stopErrorLogging();
return status;
}
//--------------------------------------------------------------------------------
// Plugin management
//--------------------------------------------------------------------------------
MStatus initializePlugin (MObject obj)
{
MStatus status;
MFnPlugin plugin(obj, "GarageGames", "0.9.6 beta");
status = plugin.registerFileTranslator ("exportDTS", "", exportDTS::creator);
status = plugin.registerFileTranslator ("exportDSQ", "", exportDSQ::creator);
return (status);
}
MStatus uninitializePlugin (MObject obj)
{
MFnPlugin plugin (obj);
plugin.deregisterFileTranslator ("exportDTS");
plugin.deregisterFileTranslator ("exportDSQ");
return (MS::kSuccess);
}
//--------------------------------------------------------------------------------
// Export DTS
//--------------------------------------------------------------------------------
bool exportDTS::haveWriteMethod () const
{
return (true);
}
MString exportDTS::defaultExtension () const
{
return (MString("dts"));
}
MPxFileTranslator::MFileKind exportDTS::identifyFile (const MFileObject &file, const char *buffer, short size) const
{
const char * name = file.name().asChar();
int nameLength = strlen(name);
if ((nameLength > 4) && !_stricmp(name+nameLength-4, ".dts"))
return (kIsMyFileType);
return (kNotMyFileType);
}
void * exportDTS::creator ()
{
return (new exportDTS);
}
exportDTS::exportDTS ()
{
}
exportDTS::~exportDTS ()
{
}
MStatus exportDTS::writer (const MFileObject &file,const MString &optionsString,FileAccessMode mode)
{
return writeTS(file,optionsString,mode,false);
}
//--------------------------------------------------------------------------------
// Export DSQ
//--------------------------------------------------------------------------------
bool exportDSQ::haveWriteMethod () const
{
return (true);
}
MString exportDSQ::defaultExtension () const
{
return (MString("dsq"));
}
MPxFileTranslator::MFileKind exportDSQ::identifyFile (const MFileObject &file, const char *buffer, short size) const
{
const char * name = file.name().asChar();
int nameLength = strlen(name);
if ((nameLength > 4) && !_stricmp(name+nameLength-4, ".dsq"))
return (kIsMyFileType);
return (kNotMyFileType);
}
void * exportDSQ::creator ()
{
return (new exportDSQ);
}
exportDSQ::exportDSQ ()
{
}
exportDSQ::~exportDSQ ()
{
}
MStatus exportDSQ::writer (const MFileObject &file,const MString &optionsString,FileAccessMode mode)
{
return exportDTS::writeTS(file,optionsString,mode,true);
}

View File

@ -0,0 +1,752 @@
//-----------------------------/------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#ifdef _MSC_VER
#pragma warning(disable : 4786)
#endif
#include "mayaAppMesh.h"
#include "mayaAppNode.h"
#include "appConfig.h"
#include "appIfl.h"
#include <maya/MFnDependencyNode.h>
#include <maya/MFnDagNode.h>
#include <maya/MGlobal.h>
#include <maya/MTime.h>
#include <maya/MDistance.h>
#include <maya/MMatrix.h>
#include <maya/MPlug.h>
#include <maya/MDGContext.h>
#include <maya/MAnimUtil.h>
#include <maya/MFnMesh.h>
#include <maya/MFnSet.h>
#include <maya/MItMeshPolygon.h>
#include <maya/MItMeshVertex.h>
#include <maya/MItDependencyGraph.h>
#include <maya/MItGeometry.h>
#include <maya/MFnSkinCluster.h>
#include <maya/MDagPathArray.h>
#include <maya/MFnReflectShader.h>
namespace DTS
{
bool getMeshAndSkin(MDagPath & path, MFnSkinCluster & skinCluster)
{
MStatus status;
// The following is the "correct" way to get the
// mesh and skinCluster in case the mesh is a skin,
// according to (and adapted from):
// http://www.greggman.com/pages/mayastuff.htm
// But we don't get the MeshFn from the input plug of the
// skinCluster as he does. Two reasons for this:
// 1) couldn't get it to work properly, not a valid MeshFn.
// 2) we want the final mesh, not the intermediate product.
// the deformed mesh comes into the visible mesh
// through its "inmesh" plug
MPlug inMeshPlug = MFnDagNode(path).findPlug("inMesh", &status);
if (status != MS::kSuccess || !inMeshPlug.isConnected())
return false; // no skin found
// walk the tree of stuff upstream from this plug
MItDependencyGraph dgIt(inMeshPlug,MFn::kInvalid,
MItDependencyGraph::kUpstream,
MItDependencyGraph::kDepthFirst,
MItDependencyGraph::kPlugLevel,
&status);
if (MS::kSuccess == status)
{
S32 count = 0;
dgIt.disablePruningOnFilter();
for ( ; ! dgIt.isDone(); dgIt.next() )
{
MObject thisNode = dgIt.thisNode();
// go until we find a skinCluster
if (thisNode.apiType() == MFn::kSkinClusterFilter)
{
skinCluster.setObject(thisNode);
return true; // found a skin
}
}
}
return false; // no skin found
}
MayaAppMesh::MayaAppMesh(MDagPath & nodePath, MDagPath & path)
{
mPath = path;
mNodePath = nodePath;
mName = NULL;
}
MayaAppMesh::~MayaAppMesh()
{
}
void MayaAppMesh::getSkinData()
{
MFnSkinCluster skinCluster;
if (!getMeshAndSkin(mPath,skinCluster))
return; // no skin, no sweat
MStatus status;
S32 i;
// get bones/influence array
MDagPathArray bones;
S32 numBones = skinCluster.influenceObjects(bones, &status);
if (!CheckMayaStatus(status))
return;
S32 bone;
for (bone=0; bone<numBones; bone++)
{
AppConfig::PrintDump(PDObjectStateDetails,avar("Adding bone %s\r\n",bones[bone].partialPathName().asChar()));
mBones.push_back(new MayaAppNode(bones[bone]));
mWeights.push_back(new std::vector<F32>);
}
MItGeometry gitr(mPath,&status);
if (!CheckMayaStatus(status))
return;
AppConfig::PrintDump(PDObjectStateDetails,avar("SkinPath: %s, # verts: %i, # bones: %i",
mPath.partialPathName().asChar(),gitr.count(),numBones));
for (; !gitr.isDone(); gitr.next())
{
while ( numBones && mWeights[0]->size() <= U32(gitr.index()))
for (i=0; i<numBones; i++)
mWeights[i]->push_back(0.0f);
MObject comp = gitr.component(&status);
if (!CheckMayaStatus(status))
return;
MFloatArray wts;
U32 weightCount;
status = skinCluster.getWeights(mPath,comp,wts,weightCount);
if (!CheckMayaStatus(status))
return;
if (weightCount != numBones)
{
AppConfig::SetExportError("maya3", "Assertion failed on skinned mesh");
return;
}
for (i=0; i<numBones; i++)
(*mWeights[i])[gitr.index()] = wts[i];
}
// make sure we have weights for all bones and verts
S32 numVerts = MFnMesh(mPath,&status).numVertices();
if (!CheckMayaStatus(status))
return;
while ( numBones && mWeights[0]->size() < U32(numVerts))
for (i=0; i<numBones; i++)
mWeights[i]->push_back(0.0f);
}
const char * MayaAppMesh::getName()
{
MStatus status;
if (!mName)
{
MFnDagNode fnNode(mNodePath,&status);
CheckMayaStatus(status);
const char * newname = fnNode.name(&status).asChar();
CheckMayaStatus(status);
if (newname)
{
mName = strnew(newname);
HandleMayaNegative(mName);
}
}
CheckMayaStatus(status);
return mName;
}
Matrix<4,4,F32> MayaAppMesh::getMeshTransform(const AppTime & time)
{
MStatus status;
MayaSetTime(time);
MMatrix mayaMat = mPath.inclusiveMatrix(&status);
CheckMayaStatus(status);
return MayaToDtsTransform(mayaMat);
}
F32 MayaAppMesh::getVisValue(const AppTime & time)
{
// Need to check for "visibility" plug, which is built into
// maya and is a bool, and "vis" plug, which is custom and
// assumed to be a float. We added the "vis" plug to allow
// non-bool vis values. The "vis" plug takes precedence.
MayaSetTime(time);
F32 val = 1.0f;
if (getFloat("vis",val))
return val;
bool ret = true;
getBool("visibility",ret);
return ret ? 1.0f : 0.0f;
}
bool MayaAppMesh::getFloat(const char * propName, F32 & defaultVal)
{
MStatus status;
MFnDagNode fnNode(mNodePath,&status);
CheckMayaStatus(status);
MPlug plug = fnNode.findPlug(MString(propName),&status);
if (status!=MStatus::kSuccess)
return false;
F32 val;
status = plug.getValue(val);
if (status == MStatus::kSuccess)
defaultVal = val;
return status==MStatus::kSuccess;
}
bool MayaAppMesh::getInt(const char * propName, S32 & defaultVal)
{
MStatus status;
MFnDagNode fnNode(mNodePath,&status);
CheckMayaStatus(status);
MPlug plug = fnNode.findPlug(MString(propName),&status);
if (status!=MStatus::kSuccess)
return false;
S32 val;
status = plug.getValue(val);
if (status == MStatus::kSuccess)
defaultVal = val;
return status==MStatus::kSuccess;
}
bool MayaAppMesh::getBool(const char * propName, bool & defaultVal)
{
MStatus status;
MFnDagNode fnNode(mNodePath,&status);
CheckMayaStatus(status);
MPlug plug = fnNode.findPlug(MString(propName),&status);
if (status!=MStatus::kSuccess)
return false;
bool val;
status = plug.getValue(val);
if (status == MStatus::kSuccess)
defaultVal = val;
return status==MStatus::kSuccess;
}
bool MayaAppMesh::getMaterial(S32 matIdx, Material & mat)
{
if (matIdx >= 0 && U32(matIdx) < mMaterials.size())
{
mat = mMaterials[matIdx];
return true;
}
return false;
}
bool MayaAppMesh::animatesVis(const AppSequenceData & seqData)
{
MStatus status;
// Need to check to see if either "visibility" or "vis" is animated.
// "visibility" is the built-in visibility mechanism, but it is
// only a bool. So we also look for custom "vis" which is assumed
// to be a float.
MFnDagNode fnNode(mNodePath,&status);
CheckMayaStatus(status);
MPlug plug = fnNode.findPlug(MString("visibility"),&status);
CheckMayaStatus(status);
if (status!=MStatus::kSuccess)
return false;
if (MAnimUtil::isAnimated(plug,false,&status))
return Parent::animatesVis(seqData);
CheckMayaStatus(status);
// don't animate "visibility", what about "vis"
MPlug plug2 = fnNode.findPlug(MString("vis"),&status);
if (status!=MStatus::kSuccess)
return false;
if (MAnimUtil::isAnimated(plug2,false,&status))
return Parent::animatesVis(seqData);
return false;
}
AppMeshLock MayaAppMesh::lockMesh(const AppTime & time, const Matrix<4,4,F32> & objectOffset)
{
S32 i;
MayaSetTime(time);
MStatus status;
MObject component = MObject::kNullObj; // not really sure what this is for...
MFnMesh fnMesh(mPath,&status);
if (!CheckMayaStatus(status))
return Parent::lockMesh(time,objectOffset);
MItMeshPolygon polyIter(mPath,component,&status);
if (!CheckMayaStatus(status))
return Parent::lockMesh(time,objectOffset);
S32 polyVertexCount = polyIter.polygonVertexCount();
if (polyVertexCount != 3)
{
AppConfig::SetExportError("maya5", "Non-triangle mesh not supported");
return Parent::lockMesh(time,objectOffset);
}
MItMeshVertex vtxIter(mPath,component,&status);
if (!CheckMayaStatus(status))
return Parent::lockMesh(time,objectOffset);
// Create transform based on objectOffset for transforming normals
Matrix<4,4,F32> normOffset = objectOffset;
normOffset[0][3] = 0.0f;
normOffset[1][3] = 0.0f;
normOffset[2][3] = 0.0f;
normOffset[3][0] = 0.0f;
normOffset[3][1] = 0.0f;
normOffset[3][2] = 0.0f;
normOffset[3][3] = 1.0f;
F32 normScale = 0.0f;
for (i=0; i<9; i++)
{
S32 j = i % 3;
normScale += normOffset[(i-j)/3][j];
}
normScale /= 3.0f;
normScale = 1.0f/normScale;
// Write out the vertex table
//
std::vector<Point3D> verts;
std::vector<Point2D> tverts;
for ( ; !vtxIter.isDone(); vtxIter.next() )
{
MPoint p = vtxIter.position( MSpace::kObject );
// convert from maya point to dts point...
// ...also, convert from internal units
// to the current ui units
Point3D pos;
MDistance dist; // starts as internal units
dist.setValue(p.x);
pos[0] = F32(dist.asMeters());
dist.setValue(p.y);
pos[1] = F32(dist.asMeters());
dist.setValue(p.z);
pos[2] = F32(dist.asMeters());
verts.push_back(objectOffset * pos);
}
MFloatArray uArray, vArray;
fnMesh.getUVs( uArray, vArray );
S32 uvLength = uArray.length();
for (i=0; i<uvLength; i++ )
{
Point2D tvert(uArray[i],1.0f-vArray[i]);
tverts.push_back(tvert);
}
for ( ; !polyIter.isDone(); polyIter.next() )
{
Primitive face;
face.firstElement = mIndices.size();
face.numElements = 3;
face.type = Primitive::Triangles|Primitive::Indexed|Primitive::NoMaterial;
for (S32 vtx=polyVertexCount-1; vtx>=0; vtx-- )
{
U16 vertId = polyIter.vertexIndex(vtx);
Point3D vert = verts[vertId];
// compute normal (TODO: handle non-uniform scale properly)
MVector mayaNorm;
status = polyIter.getNormal(vtx,mayaNorm,MSpace::kObject);
if (!CheckMayaStatus(status))
return Parent::lockMesh(time,objectOffset);
F32 norm0, norm1, norm2;
norm0 = F32(mayaNorm[0]);
norm1 = F32(mayaNorm[1]);
norm2 = F32(mayaNorm[2]);
Point3D norm(norm0, norm1, norm2);
norm = normOffset * norm;
norm *= normScale;
if (norm.length()>0.001f)
norm.normalize();
else
norm = Point3D(0,0,1);
// grab tvert
Point2D tvert(0,0);
if (fnMesh.numUVs() > 0)
{
if (polyIter.hasUVs())
{
S32 uvIndex;
if (polyIter.getUVIndex(vtx,uvIndex))
tvert = tverts[uvIndex];
}
}
mIndices.push_back(addVertex(vert,norm,tvert,vertId));
}
mFaces.push_back(face);
}
getMaterials();
// are we 2-sided?
bool twoSided = false;
getBool("twoSided",twoSided);
if (twoSided)
{
S32 numFaces = mFaces.size();
for (i=0; i<numFaces; i++)
{
S32 first = mFaces[i].firstElement;
Primitive face;
face.firstElement = mIndices.size();
face.numElements = 3;
face.type = mFaces[i].type;
Point3D vert = mVerts[mIndices[first + 0]];
Point2D tvert = mTVerts[mIndices[first + 0]];
Point3D norm = -mNormals[mIndices[first + 0]];
S32 vertId = mVertId[mIndices[first + 0]];
mIndices.push_back(addVertex(vert,norm,tvert,vertId));
vert = mVerts[mIndices[first + 2]];
tvert = mTVerts[mIndices[first + 2]];
norm = -mNormals[mIndices[first + 2]];
vertId = mVertId[mIndices[first + 2]];
mIndices.push_back(addVertex(vert,norm,tvert,vertId));
vert = mVerts[mIndices[first + 1]];
tvert = mTVerts[mIndices[first + 1]];
norm = -mNormals[mIndices[first + 1]];
vertId = mVertId[mIndices[first + 1]];
mIndices.push_back(addVertex(vert,norm,tvert,vertId));
mFaces.push_back(face);
}
}
return Parent::lockMesh(time,objectOffset);
}
void MayaAppMesh::getMaterials()
{
// Maya material extraction code pulled from
// findTexturesPerPolyCmd.cpp from Maya sample plugins.
MStatus status;
S32 instanceNum = 0;
if (mPath.isInstanced())
instanceNum = mPath.instanceNumber();
// Get a list of all sets pertaining to the selected shape and the
// members of those sets.
MFnMesh fnMesh(mPath);
MObjectArray sets;
MObjectArray comps;
if (!fnMesh.getConnectedSetsAndMembers(instanceNum, sets, comps, true))
{
AppConfig::SetExportError("maya6", "ERROR: getMaterials: MFnMesh::getConnectedSetsAndMembers\r\n");
return;
}
// This is a (hack) workaround. If we already have got at least one
// material, don't accept mesh iterators that include the whole mesh
// (would be an error anyway).
bool gotOne = false;
// Loop through all the sets. If the set is a polygonal set, find the
// shader attached to the and print out the texture file name for the
// set along with the polygons in the set.
//
for ( U32 i=0; i<sets.length(); i++ )
{
MObject set = sets[i];
MObject comp = comps[i];
MFnSet fnSet( set, &status );
if (MS::kFailure == status)
{
AppConfig::SetExportError("maya1", "ERROR: getMaterials: MFnSet::MFnSet\r\n");
return;
}
// Special (hack) case in which we have an iterator over everything
// yet we already have got at least one material...
if (gotOne && (comp.apiType() == MFn::kInvalid))
continue;
// Make sure the set is a polygonal set. If not, continue.
MItMeshPolygon piter(mPath, comp, &status);
if (MS::kFailure == status)
continue;
// Find the texture that is applied to this set. First, get the
// shading node connected to the set. Then, if there is an input
// attribute called "color", search upstream from it for a texture
// file node.
MObject shaderNode = findShader(set);
if (shaderNode == MObject::kNullObj)
continue;
MPlug colorPlug = MFnDependencyNode(shaderNode).findPlug("color", &status);
if (status == MS::kFailure)
continue;
MItDependencyGraph dgIt(colorPlug, MFn::kFileTexture,
MItDependencyGraph::kUpstream,
MItDependencyGraph::kBreadthFirst,
MItDependencyGraph::kNodeLevel,
&status);
if (status == MS::kFailure)
continue;
dgIt.disablePruningOnFilter();
// If no texture file node was found, just continue.
if (dgIt.isDone())
continue;
// Print out the texture node name and texture file that it references.
//
MObject textureNode = dgIt.thisNode();
MPlug filenamePlug = MFnDependencyNode(textureNode).findPlug("fileTextureName");
MString textureName;
filenamePlug.getValue(textureName);
// look for filename plug on transparency channel -- if it has one, material is translucent
bool hasTransparency = false;
MPlug transPlug = MFnDependencyNode(shaderNode).findPlug("transparency", &status);
if (status == MS::kFailure)
continue;
dgIt.resetTo(transPlug, MFn::kFileTexture,
MItDependencyGraph::kUpstream,
MItDependencyGraph::kBreadthFirst,
MItDependencyGraph::kNodeLevel);
dgIt.disablePruningOnFilter();
// If no texture file node was found, just continue.
if (!dgIt.isDone())
{
// Print out the texture node name and texture file that it references.
//
MObject textureNode = dgIt.thisNode();
MPlug filenamePlug = MFnDependencyNode(textureNode).findPlug("fileTextureName");
MString textureName;
filenamePlug.getValue(textureName);
if (textureName.length() != 0)
hasTransparency = true;
}
for (; !piter.isDone(); piter.next())
{
S32 faceIdx = piter.index();
if (mFaces[faceIdx].type & Primitive::NoMaterial)
{
mFaces[faceIdx].type ^= Primitive::NoMaterial;
mFaces[faceIdx].type |= mMaterials.size();
// we have at least one material now
gotOne = true;
}
else
AppConfig::SetExportError("maya7", "Mesh::getMaterials: face with multiple materials found");
}
Material mat;
mat.name = textureName.asChar();
mat.reflectance = -1;
mat.bump = -1;
mat.detail = -1;
mat.detailScale = 1.0f;
mat.reflection = 0.0f;
mat.flags = Material::SWrap|Material::TWrap|Material::NeverEnvMap;
MFnLambertShader lshader(shaderNode,&status);
if (status == MStatus::kSuccess)
{
F32 translucence = lshader.translucenceCoeff();
F32 selfIlluminating = lshader.glowIntensity();
if (translucence>0.1f || hasTransparency)
mat.flags |= Material::Translucent;
if (selfIlluminating>0.1f)
mat.flags |= Material::SelfIlluminating;
}
MFnReflectShader rshader(shaderNode,&status);
if (status == MStatus::kSuccess)
{
F32 reflectivity = rshader.reflectivity();
if (reflectivity>0.01f)
{
mat.reflection = reflectivity;
mat.flags ^= Material::NeverEnvMap;
}
}
// now get the texture placement node
status = dgIt.resetTo(colorPlug, MFn::kPlace2dTexture,
MItDependencyGraph::kUpstream,
MItDependencyGraph::kBreadthFirst,
MItDependencyGraph::kNodeLevel);
dgIt.disablePruningOnFilter();
if (status != MS::kFailure)
if (!dgIt.isDone())
{
MObject placeNode = dgIt.thisNode();
MStatus stat;
MFnDependencyNode fnNode(placeNode,&stat);
bool swrap = true;
bool twrap = true;
MPlug plug = fnNode.findPlug(MString("wrapU"),&stat);
plug.getValue(swrap);
plug = fnNode.findPlug(MString("wrapV"),&stat);
plug.getValue(swrap);
if (!swrap)
mat.flags ^= Material::SWrap;
if (!twrap)
mat.flags ^= Material::TWrap;
}
/*
Need to deal with these flags:
Additive = 0x00000008,
Subtractive = 0x00000010,
IFLMaterial = 0x08000000,
*/
//------------
// If this is an ifl, then create the ifl material if it doesn't exist and mark as ifl
const char * dot = strchr(textureName.asChar(),'.');
if (dot && !stricmp(dot+1,"ifl"))
{
mat.flags |= Material::IFLMaterial;
S32 matIdx = mMaterials.size();
while (mIfls.size() <= U32(matIdx))
mIfls.push_back(NULL);
if (!mIfls[matIdx])
mIfls[matIdx] = new AppIfl(mat.name.c_str());
}
mMaterials.push_back(mat);
}
}
MObject MayaAppMesh::findShader( MObject& setNode )
{
// Description: Find the shading node for the given shading group set node.
MFnDependencyNode fnNode(setNode);
MPlug shaderPlug = fnNode.findPlug("surfaceShader");
if (!shaderPlug.isNull())
{
MPlugArray connectedPlugs;
bool asSrc = false;
bool asDst = true;
shaderPlug.connectedTo( connectedPlugs, asDst, asSrc );
if (connectedPlugs.length() != 1)
AppConfig::SetExportError("maya4", "Error getting shader\r\n");
else
return connectedPlugs[0].node();
}
return MObject::kNullObj;
}
void MayaAppMesh::unlockMesh()
{
Parent::unlockMesh();
// no more cleanup...but if there were some to do, we'd do it here
}
void MayaSetTime(const AppTime & time)
{
MTime mayaTime(time.getF64(),MTime::kSeconds);
MGlobal::viewFrame(mayaTime);
}
Matrix<4,4,F32> MayaToDtsTransform(MMatrix & mayaMat)
{
Matrix<4,4,F32> mat;
for (S32 i=0; i<4; i++)
for (S32 j=0; j<4; j++)
mat[j][i] = F32(mayaMat[i][j]);
F64 scale;
MDistance dist; // starts as internal units
dist.setValue(1.0f);
scale = dist.asMeters();
mat[0][3] *= F32(scale);
mat[1][3] *= F32(scale);
mat[2][3] *= F32(scale);
return mat;
}
bool CheckMayaStatus(MStatus & status)
{
if (!bool(status))
{
AppConfig::SetExportError("maya2", avar("Maya error: %s",status.errorString().asChar()));
status = MStatus::kSuccess;
return false;
}
return true;
}
void HandleMayaNegative(char * name)
{
S32 pos = strlen(name);
while (pos)
{
--pos;
if (isdigit(name[pos]))
continue;
if (name[pos]=='_')
name[pos]='-';
break;
}
}
}; // namespace DTS

View File

@ -0,0 +1,58 @@
//-----------------------------/------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#ifndef DTSMAYAMESH_H_
#define DTSMAYAMESH_H_
#include "appMesh.h"
#include <maya/MDagPath.h>
namespace DTS
{
class MayaAppMesh : public AppMesh
{
typedef AppMesh Parent;
MDagPath mPath;
MDagPath mNodePath;
char * mName;
std::vector<Material> mMaterials;
void getSkinData();
void getMaterials();
MObject findShader( MObject& setNode );
public:
MayaAppMesh(MDagPath & nodePath, MDagPath & path);
~MayaAppMesh();
const char * getName();
Matrix<4,4,F32> getMeshTransform(const AppTime & time);
F32 getVisValue(const AppTime & time);
bool getFloat(const char * propName, F32 & defaultVal);
bool getInt(const char * propName, S32 & defaultVal);
bool getBool(const char * propName, bool & defaultVal);
bool getMaterial(S32 matIdx, Material &);
bool animatesVis(const AppSequenceData & seqData);
AppMeshLock lockMesh(const AppTime & time, const Matrix<4,4,F32> & objectOffset);
void unlockMesh();
};
extern void MayaSetTime(const AppTime & time);
extern Matrix<4,4,F32> MayaToDtsTransform(MMatrix & mayaMat);
extern bool CheckMayaStatus(MStatus & status);
extern void HandleMayaNegative(char * name);
}; // namespace DTS
#endif // DTSAPPMESH_H_

View File

@ -0,0 +1,241 @@
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#ifdef _MSC_VER
#pragma warning(disable : 4786)
#endif
#include "mayaAppNode.h"
#include "mayaAppMesh.h"
#include "appConfig.h"
#include "DTSUtil.h"
#include <maya/MFnDependencyNode.h>
#include <maya/MFnDagNode.h>
#include <maya/MFnTransform.h>
#include <maya/MGlobal.h>
#include <maya/MTime.h>
#include <maya/MPoint.h>
#include <maya/MMatrix.h>
#include <maya/MPlug.h>
#include <maya/MDGContext.h>
#include <maya/MAnimUtil.h>
namespace DTS
{
MayaAppNode::MayaAppNode(MDagPath & path)
{
mPath = path;
}
MayaAppNode::~MayaAppNode()
{
}
void MayaAppNode::buildMeshList()
{
MStatus status;
for (U32 i=0; i<mPath.childCount(&status); i++)
{
if (mPath.child(i,&status).hasFn(MFn::kMesh) && !mPath.child(i,&status).hasFn(MFn::kTransform))
{
CheckMayaStatus(status);
MDagPath path = mPath;
MObject meshNode = mPath.child(i,&status);
CheckMayaStatus(status);
status = path.push(meshNode);
CheckMayaStatus(status);
if (!MFnDagNode(path).isIntermediateObject(&status))
mMeshes.push_back(new MayaAppMesh(mPath,path));
CheckMayaStatus(status);
}
CheckMayaStatus(status);
}
CheckMayaStatus(status);
}
void MayaAppNode::buildChildList()
{
MStatus status;
for (U32 i=0; i<mPath.childCount(&status); i++)
{
if (!mPath.child(i,&status).hasFn(MFn::kMesh) && mPath.child(i,&status).hasFn(MFn::kTransform))
{
CheckMayaStatus(status);
MDagPath path = mPath;
MObject childNode = mPath.child(i,&status);
CheckMayaStatus(status);
status = path.push(childNode);
CheckMayaStatus(status);
mChildNodes.push_back(new MayaAppNode(path));
}
}
CheckMayaStatus(status);
}
Matrix<4,4,F32> MayaAppNode::getNodeTransform(const AppTime & time)
{
// we don't use the straight transform from maya because maya
// doesn't display origin of transform in the gui
// instead we adjust transform to use rotation pivot point as origin
// that means the node transforms are different than maya uses,
// but it's ok because the mesh transforms will be the same...
// ...so as long as the user doesn't animate the rotation pivot,
// it should all work out
MStatus status;
MayaSetTime(time);
// get local space pivot point
MStatus status1;
MStatus status2;
MStatus status3;
MFnTransform trans(mPath,&status1);
MPoint pivot = trans.transformation(&status2).rotatePivot(MSpace::kWorld,&status3);
CheckMayaStatus(status1);
CheckMayaStatus(status2);
CheckMayaStatus(status3);
// get world space transform
MMatrix mayaMat = mPath.inclusiveMatrix(&status);
CheckMayaStatus(status);
// compute world space pivot point and revise world space transform
MPoint wpivot = pivot * mayaMat;
mayaMat[3][0] = wpivot[0];
mayaMat[3][1] = wpivot[1];
mayaMat[3][2] = wpivot[2];
return MayaToDtsTransform(mayaMat);
}
bool MayaAppNode::isEqual(AppNode * node)
{
MayaAppNode * mayaNode = dynamic_cast<MayaAppNode*>(node);
return mayaNode && mayaNode->mPath == mPath;
}
bool MayaAppNode::animatesTransform(const AppSequenceData & seqData)
{
MStatus status;
bool ret = MAnimUtil::isAnimated (mPath, false, &status);
CheckMayaStatus(status);
return ret;
}
const char * MayaAppNode::getName()
{
MStatus status;
if (!mName)
{
MFnDagNode fnNode(mPath,&status);
CheckMayaStatus(status);
const char * newname = fnNode.name(&status).asChar();
if (newname)
{
mName = strnew(newname);
HandleMayaNegative(mName);
}
}
CheckMayaStatus(status);
return mName;
}
const char * MayaAppNode::getParentName()
{
MStatus status;
if (!mParentName)
{
MFnDagNode fnNode(mPath,&status);
CheckMayaStatus(status);
if (fnNode.parentCount(&status) > 0)
{
MObject parentNode = fnNode.parent(0,&status);
MFnDependencyNode fnParent(parentNode,&status);
const char * pname = fnParent.name(&status).asChar();
if (pname)
{
mParentName = strnew(pname);
HandleMayaNegative(mParentName);
}
}
}
CheckMayaStatus(status);
return mParentName;
}
bool MayaAppNode::getFloat(const char * propName, F32 & defaultVal)
{
MStatus status;
MFnDagNode fnNode(mPath,&status);
CheckMayaStatus(status);
MPlug plug = fnNode.findPlug(MString(propName),&status);
if (status!=MStatus::kSuccess)
return false;
F32 val;
status = plug.getValue(val);
if (status == MStatus::kSuccess)
defaultVal = val;
return status==MStatus::kSuccess;
}
bool MayaAppNode::getInt(const char * propName, S32 & defaultVal)
{
MStatus status;
MFnDagNode fnNode(mPath,&status);
CheckMayaStatus(status);
MPlug plug = fnNode.findPlug(MString(propName),&status);
if (status!=MStatus::kSuccess)
return false;
S32 val;
status = plug.getValue(val);
if (status == MStatus::kSuccess)
defaultVal = val;
return status==MStatus::kSuccess;
}
bool MayaAppNode::getBool(const char * propName, bool & defaultVal)
{
MStatus status;
MFnDagNode fnNode(mPath,&status);
CheckMayaStatus(status);
MPlug plug = fnNode.findPlug(MString(propName),&status);
if (status!=MStatus::kSuccess)
return false;
bool val;
status = plug.getValue(val);
if (status == MStatus::kSuccess)
defaultVal = val;
return status==MStatus::kSuccess;
}
bool MayaAppNode::isParentRoot()
{
MStatus status;
bool ret = false;
// not sure the best way to do this
// our parent is the root if our parent has no parent
MObject parentNode = mPath.node(&status);
MFnDagNode fnNode(parentNode,&status);
if (fnNode.parentCount(&status) > 0)
{
ret = !stricmp( MFnDagNode(fnNode.parent(0,&status)).name().asChar(), "world");
}
CheckMayaStatus(status);
return ret;
}
}; // namespace DTS

View File

@ -0,0 +1,47 @@
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#ifndef DTSMAYANODE_H_
#define DTSMAYANODE_H_
#include "appnode.h"
#include <maya/MDagPath.h>
namespace DTS
{
class MayaAppNode : public AppNode
{
typedef AppNode Parent;
MDagPath mPath;
void buildMeshList();
void buildChildList();
public:
MayaAppNode(MDagPath & path);
~MayaAppNode();
Matrix<4,4,F32> getNodeTransform(const AppTime & time);
bool isEqual(AppNode *);
bool animatesTransform(const AppSequenceData & seqData);
const char * getName();
const char * getParentName();
bool getFloat(const char * propName, F32 & defaultVal);
bool getInt(const char * propName, S32 & defaultVal);
bool getBool(const char * propName, bool & defaultVal);
bool isParentRoot();
};
}; // namespace DTS
#endif // DTSMAYANODE_H_

View File

@ -0,0 +1,40 @@
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#ifdef _MSC_VER
#pragma warning(disable : 4786)
#endif
#include "mayaSceneEnum.h"
#include "mayaAppNode.h"
#include <maya/MItDag.h>
#include <maya/MDagPath.h>
namespace DTS
{
void MayaSceneEnum::enumScene()
{
MItDag dagIt(MItDag::kBreadthFirst);
for (dagIt.next(); !dagIt.isDone(); dagIt.next())
{
MDagPath path;
if (dagIt.getPath (path) != MS::kSuccess)
continue;
if (path.hasFn(MFn::kMesh) && !path.hasFn(MFn::kTransform))
// don't want meshes...
continue;
MayaAppNode * mayaNode = new MayaAppNode(path);
if (!processNode(mayaNode))
delete mayaNode;
// could prune here (i.e., not explore depth) but might find
// bounds in tree so go ahead and plum the depths of the dag
}
}
}; // namespace DTS

View File

@ -0,0 +1,24 @@
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#ifndef DTSMAYASCENEENUM_H_
#define DTSMAYASCENEENUM_H_
#include "appSceneEnum.h"
namespace DTS
{
class MayaSceneEnum : public AppSceneEnum
{
typedef AppSceneEnum Parent;
public:
void enumScene();
};
}; // namespace DTS
#endif // #define DTSMAYASCENEENUM_H_