private void ExportMesh(int meshIndex)
{
GrnMesh mesh = this.File.Meshes[meshIndex];
string mainObject = "mainObject";
Maxscript.Command("{0} = grnMeshes[{1}]", mainObject, meshIndex + 1);
string mainMesh = Maxscript.SnapshotAsMesh("mainMesh", mainObject);
mesh.DataExtensionIndex = this.File.AddDataExtension(Maxscript.QueryString("{0}.name", mainObject));
Dictionary<int, int> matIdMapping = this.ExportMeshMaterial(mainObject);
// Setup Normals
Maxscript.Command("max modify mode");
string tempObject = "tempObject";
Maxscript.Command("{0} = Editable_Mesh()", tempObject);
Maxscript.Command("{0}.mesh = {1}", tempObject, mainMesh);
Maxscript.Command("addModifier {0} (Edit_Normals()) ui:off", tempObject);
Maxscript.Command("modPanel.setCurrentObject {0}.modifiers[#edit_normals] ui:true", tempObject);
int numVertices = Maxscript.QueryInteger("meshop.getnumverts {0}", mainMesh);
int numFaces = Maxscript.QueryInteger("meshop.getnumfaces {0}", mainMesh);
for (int i = 0; i < numVertices; i++)
{
try
{
Maxscript.Command("vertex = meshGetVertFunc {0} {1}", mainMesh, i + 1);
mesh.Vertices.Add(new Vector3D(
Maxscript.QueryFloat("vertex.x"),
Maxscript.QueryFloat("vertex.y"),
Maxscript.QueryFloat("vertex.z")));
}
catch (Exception ex)
{
throw new Exception("Error importing vertex at index " + (i + 1) + ".", ex);
}
}
int numNorms = Maxscript.QueryInteger("{0}.modifiers[#edit_normals].GetNumNormals()", tempObject);
Maxscript.Command("getVertNormalFunc = {0}.modifiers[#edit_normals].GetNormal", tempObject);
for (int i = 0; i < numNorms; ++i)
{
try
{
Maxscript.Command("currentNormal = getVertNormalFunc {0}", i + 1);
mesh.Normals.Add(new Vector3D(
Maxscript.QueryFloat("currentNormal.x"),
Maxscript.QueryFloat("currentNormal.y"),
Maxscript.QueryFloat("currentNormal.z")));
}
catch (Exception ex)
{
throw new Exception("Error importing normal at index " + (i + 1) + ".", ex);
}
}
int numTexVertices = Maxscript.QueryInteger("meshop.getnumtverts {0}", mainMesh);
for (int i = 0; i < numTexVertices; i++)
{
try
{
Maxscript.Command("tVert = meshGetMapVertFunc {0} 1 {1}", mainMesh, i + 1);
mesh.TextureCoordinates.Add(new Vector3D(
Maxscript.QueryFloat("tVert.x"),
1f-Maxscript.QueryFloat("tVert.y"),
Maxscript.QueryFloat("tVert.z")));
}
catch (Exception ex)
{
throw new Exception("Error importing texture vertex at index " + (i + 1) + ".", ex);
}
}
Maxscript.Command("meshGetNormalIdFunc = {0}.modifiers[#edit_normals].GetNormalID", tempObject);
for (int i = 0; i < numFaces; ++i)
{
Face f = new Face();
Int32 matIndex = Maxscript.QueryInteger("getFaceMatID {0} {1}", mainMesh, i + 1);
if (matIdMapping.ContainsKey(matIndex))
{
f.MaterialIndex = (Int16)(matIdMapping[matIndex]);
}
else
{
throw new Exception("In mesh " + mesh.Name + " face index " + (i + 1) + " has an invalid material id " + matIndex + ".");
}
Maxscript.Command("face = getFace {0} {1}", mainMesh, i + 1);
f.Indices.Add((Int16)(Maxscript.QueryInteger("face.x") - 1));
f.Indices.Add((Int16)(Maxscript.QueryInteger("face.y") - 1));
f.Indices.Add((Int16)(Maxscript.QueryInteger("face.z") - 1));
f.NormalIndices.Add(Maxscript.QueryInteger("meshGetNormalIdFunc {0} {1}", i + 1, 1) - 1);
f.NormalIndices.Add(Maxscript.QueryInteger("meshGetNormalIdFunc {0} {1}", i + 1, 2) - 1);
f.NormalIndices.Add(Maxscript.QueryInteger("meshGetNormalIdFunc {0} {1}", i + 1, 3) - 1);
Maxscript.Command("tFace = getTVFace {0} {1}", mainMesh, i + 1);
f.TextureIndices.Add(Maxscript.QueryInteger("tFace.x") - 1);
f.TextureIndices.Add(Maxscript.QueryInteger("tFace.y") - 1);
f.TextureIndices.Add(Maxscript.QueryInteger("tFace.z") - 1);
mesh.Faces.Add(f);
}
// Delete temporary object
Maxscript.Command("delete {0}", tempObject);
if (Maxscript.QueryBoolean("{0}.modifiers[#skin] != undefined", mainObject))
{
Maxscript.Command("skinMod = {0}.modifiers[#skin]", mainObject);
Maxscript.Command("modPanel.setCurrentObject skinMod ui:true");
Maxscript.Command("ExportSkinData()");
int numBVerts = Maxscript.QueryInteger("grnSkinWeights.count");
for (int i = 0; i < numBVerts; ++i)
{
mesh.VertexWeights.Add(new VertexWeight());
Maxscript.Command("skinWeightArray = grnSkinWeights[{0}]", i + 1);
int numVWs = Maxscript.QueryInteger("skinWeightArray.count");
for (int j = 0; j < numVWs; ++j)
{
mesh.VertexWeights[i].BoneIndices.Add(Maxscript.QueryInteger("skinWeightArray[{0}][1]", j + 1));
mesh.VertexWeights[i].Weights.Add(Maxscript.QueryFloat("skinWeightArray[{0}][2]", j + 1));
}
}
int numSkinBBs = Maxscript.QueryInteger("grnSkinBBMaxs.count");
for (int i = 0; i < numSkinBBs; ++i)
{
Maxscript.Command("bbMax = grnSkinBBMaxs[{0}]", i + 1);
Maxscript.Command("bbMin = grnSkinBBMins[{0}]", i + 1);
mesh.BoneBindings.Add(new GrnBoneBinding());
mesh.BoneBindings[i].BoneIndex = Maxscript.QueryInteger("grnSkinBBIndices[{0}]", i + 1);
mesh.BoneBindings[i].OBBMax = new Vector3D(
Maxscript.QueryFloat("bbMax.x"),
Maxscript.QueryFloat("bbMax.y"),
Maxscript.QueryFloat("bbMax.z"));
mesh.BoneBindings[i].OBBMin = new Vector3D(
Maxscript.QueryFloat("bbMin.x"),
Maxscript.QueryFloat("bbMin.y"),
Maxscript.QueryFloat("bbMin.z"));
}
if (numBVerts == 0 || numSkinBBs == 0)
{
throw new Exception("Failed to export skin vertices in mesh " + mesh.Name + ".");
}
}
else
{
throw new Exception("Mesh " + mesh.Name + " has no skin.");
}
}