mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
cppkore uses string/wstring as StringBase while we use std::string/std::wstring as string/wstring. Changed all types in cppkore to String/WString instead.
518 lines
20 KiB
C++
518 lines
20 KiB
C++
#include "stdafx.h"
|
|
#include "AutodeskMaya.h"
|
|
|
|
#include "File.h"
|
|
#include "Path.h"
|
|
#include "CRC32.h"
|
|
#include "StreamWriter.h"
|
|
#include "DictionaryBase.h"
|
|
|
|
namespace Assets::Exporters
|
|
{
|
|
bool AutodeskMaya::ExportAnimation(const Animation& Animation, const String& Path)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
bool AutodeskMaya::ExportModel(const Model& Model, const String& Path)
|
|
{
|
|
auto Writer = IO::StreamWriter(IO::File::Create(Path));
|
|
auto FileName = IO::Path::GetFileNameWithoutExtension(Path);
|
|
auto Hash = Hashing::CRC32::HashString(FileName);
|
|
|
|
Writer.WriteLine(
|
|
"//Maya ASCII 8.5 scene\n\n"
|
|
"requires maya \"8.5\";\ncurrentUnit -l centimeter -a degree -t film;\nfileInfo \"application\" \"maya\";\nfileInfo \"product\" \"Maya Unlimited 8.5\";\nfileInfo \"version\" \"8.5\";\nfileInfo \"cutIdentifier\" \"200612162224-692032\";"
|
|
"createNode transform -s -n \"persp\";\n\tsetAttr \".v\" no;\n\tsetAttr \".t\" -type \"double3\" 48.186233840145825 37.816674066853686 41.0540421364379 ;\n\tsetAttr \".r\" -type \"double3\" -29.738352729603015 49.400000000000432 0 ;\ncreateNode camera -s -n \"perspShape\" -p \"persp\";\n\tsetAttr -k off \".v\" no;\n\tsetAttr \".fl\" 34.999999999999993;\n\tsetAttr \".fcp\" 10000;\n\tsetAttr \".coi\" 73.724849603665149;\n\tsetAttr \".imn\" -type \"string\" \"persp\";\n\tsetAttr \".den\" -type \"string\" \"persp_depth\";\n\tsetAttr \".man\" -type \"string\" \"persp_mask\";\n\tsetAttr \".hc\" -type \"string\" \"viewSet -p %camera\";\ncreateNode transform -s -n \"top\";\n\tsetAttr \".v\" no;\n\tsetAttr \".t\" -type \"double3\" 0 100.1 0 ;\n\tsetAttr \".r\" -type \"double3\" -89.999999999999986 0 0 ;\ncreateNode camera -s -n \"topShape\" -p \"top\";\n\tsetAttr -k off \".v\" no;\n\tsetAttr \".rnd\" no;\n\tsetAttr \".coi\" 100.1;\n\tsetAttr \".ow\" 30;\n\tsetAttr \".imn\" -type \"string\" \"top\";\n\tsetAttr \".den\" -type \"string\" \"top_depth\";\n\tsetAttr \".man\" -type \"string\" \"top_mask\";\n\tsetAttr \".hc\" -type \"string\" \"viewSet -t %camera\";\n\tsetAttr \".o\" yes;\ncreateNode transform -s -n \"front\";\n\tsetAttr \".v\" no;\n\tsetAttr \".t\" -type \"double3\" 0 0 100.1 ;\ncreateNode camera -s -n \"frontShape\" -p \"front\";\n\tsetAttr -k off \".v\" no;\n\tsetAttr \".rnd\" no;\n\tsetAttr \".coi\" 100.1;\n\tsetAttr \".ow\" 30;\n\tsetAttr \".imn\" -type \"string\" \"front\";\n\tsetAttr \".den\" -type \"string\" \"front_depth\";\n\tsetAttr \".man\" -type \"string\" \"front_mask\";\n\tsetAttr \".hc\" -type \"string\" \"viewSet -f %camera\";\n\tsetAttr \".o\" yes;\ncreateNode transform -s -n \"side\";\n\tsetAttr \".v\" no;\n\tsetAttr \".t\" -type \"double3\" 100.1 0 0 ;\n\tsetAttr \".r\" -type \"double3\" 0 89.999999999999986 0 ;\ncreateNode camera -s -n \"sideShape\" -p \"side\";\n\tsetAttr -k off \".v\" no;\n\tsetAttr \".rnd\" no;\n\tsetAttr \".coi\" 100.1;\n\tsetAttr \".ow\" 30;\n\tsetAttr \".imn\" -type \"string\" \"side\";\n\tsetAttr \".den\" -type \"string\" \"side_depth\";\n\tsetAttr \".man\" -type \"string\" \"side_mask\";\n\tsetAttr \".hc\" -type \"string\" \"viewSet -s %camera\";\n\tsetAttr \".o\" yes;\ncreateNode lightLinker -n \"lightLinker1\";\n\tsetAttr -s 9 \".lnk\";\n\tsetAttr -s 9 \".slnk\";\ncreateNode displayLayerManager -n \"layerManager\";\ncreateNode displayLayer -n \"defaultLayer\";\ncreateNode renderLayerManager -n \"renderLayerManager\";\ncreateNode renderLayer -n \"defaultRenderLayer\";\n\tsetAttr \".g\" yes;\ncreateNode script -n \"sceneConfigurationScriptNode\";\n\tsetAttr \".b\" -type \"string\" \"playbackOptions -min 1 -max 24 -ast 1 -aet 48 \";\n\tsetAttr \".st\" 6;\nselect -ne :time1;\n\tsetAttr \".o\" 1;\nselect -ne :renderPartition;\n\tsetAttr -s 2 \".st\";\nselect -ne :renderGlobalsList1;\nselect -ne :defaultShaderList1;\n\tsetAttr -s 2 \".s\";\nselect -ne :postProcessList1;\n\tsetAttr -s 2 \".p\";\nselect -ne :lightList1;\nselect -ne :initialShadingGroup;\n\tsetAttr \".ro\" yes;\nselect -ne :initialParticleSE;\n\tsetAttr \".ro\" yes;\nselect -ne :hardwareRenderGlobals;\n\tsetAttr \".ctrs\" 256;\n\tsetAttr \".btrs\" 512;\nselect -ne :defaultHardwareRenderGlobals;\n\tsetAttr \".fn\" -type \"string\" \"im\";\n\tsetAttr \".res\" -type \"string\" \"ntsc_4d 646 485 1.333\";\nselect -ne :ikSystem;\n\tsetAttr -s 4 \".sol\";\nconnectAttr \":defaultLightSet.msg\" \"lightLinker1.lnk[0].llnk\";\nconnectAttr \":initialShadingGroup.msg\" \"lightLinker1.lnk[0].olnk\";\nconnectAttr \":defaultLightSet.msg\" \"lightLinker1.lnk[1].llnk\";\nconnectAttr \":initialParticleSE.msg\" \"lightLinker1.lnk[1].olnk\";\nconnectAttr \":defaultLightSet.msg\" \"lightLinker1.slnk[0].sllk\";\nconnectAttr \":initialShadingGroup.msg\" \"lightLinker1.slnk[0].solk\";\nconnectAttr \":defaultLightSet.msg\" \"lightLinker1.slnk[1].sllk\";\nconnectAttr \":initialParticleSE.msg\" \"lightLinker1.slnk[1].solk\";\nconnectAttr \"layerManager.dli[0]\" \"defaultLayer.id\";\nconnectAttr \"renderLayerManager.rlmi[0]\" \"defaultRenderLayer.rlid\";\nconnectAttr \"lightLinker1.msg\" \":lightList1.ln\" -na;"
|
|
);
|
|
|
|
Writer.WriteLineFmt(
|
|
"createNode transform -n \"%s\";\n"
|
|
"setAttr \".ove\" yes;",
|
|
(char*)FileName
|
|
);
|
|
|
|
uint32_t SubmeshIndex = 0;
|
|
|
|
for (auto& Submesh : Model.Meshes)
|
|
{
|
|
Writer.WriteLineFmt(
|
|
"createNode transform -n \"KoreMesh_%08x_%02d\" -p \"%s\";\n"
|
|
"setAttr \".rp\" -type \"double3\" 0.000000 0.000000 0.000000 ;\nsetAttr \".sp\" -type \"double3\" 0.000000 0.000000 0.000000 ;\n"
|
|
"createNode mesh -n \"MeshShape_%d\" -p \"KoreMesh_%08x_%02d\";\n"
|
|
"setAttr -k off \".v\";\nsetAttr \".vir\" yes;\nsetAttr \".vif\" yes;\n"
|
|
"setAttr -s %d \".uvst\";",
|
|
Hash, SubmeshIndex, (char*)FileName,
|
|
SubmeshIndex, Hash, SubmeshIndex,
|
|
Submesh.Vertices.UVLayerCount()
|
|
);
|
|
|
|
for (uint8_t i = 1; i < Submesh.Vertices.UVLayerCount() + 1; i++)
|
|
{
|
|
if (Submesh.Vertices.Count() == 1)
|
|
{
|
|
Writer.WriteFmt(
|
|
"setAttr \".uvst[%d].uvsn\" -type \"string\" \"map%d\";\n"
|
|
"setAttr -s 1 \".uvst[0].uvsp[0]\" -type \"float2\"",
|
|
(i - 1), i
|
|
);
|
|
}
|
|
else
|
|
{
|
|
Writer.WriteFmt(
|
|
"setAttr \".uvst[%d].uvsn\" -type \"string\" \"map%d\";\n"
|
|
"setAttr -s %d \".uvst[0].uvsp[0:%d]\" -type \"float2\"",
|
|
(i - 1), i,
|
|
Submesh.Vertices.Count(), (Submesh.Vertices.Count() - 1)
|
|
);
|
|
}
|
|
|
|
for (auto& Vertex : Submesh.Vertices)
|
|
{
|
|
auto& Layer = Vertex.UVLayers(i - 1);
|
|
Writer.WriteFmt(" %f %f", Layer.U, (1 - Layer.V));
|
|
}
|
|
|
|
Writer.Write(";\n");
|
|
}
|
|
|
|
Writer.WriteFmt(
|
|
"setAttr \".cuvs\" -type \"string\" \"map1\";\nsetAttr \".dcol\" yes;\nsetAttr \".dcc\" -type \"string\" \"Ambient+Diffuse\";\nsetAttr \".ccls\" -type \"string\" \"colorSet1\";\nsetAttr \".clst[0].clsn\" -type \"string\" \"colorSet1\";\n"
|
|
"setAttr -s %d \".clst[0].clsp\";\n"
|
|
"setAttr \".clst[0].clsp[0:%d]\"",
|
|
(Submesh.Faces.Count() * 3),
|
|
(Submesh.Faces.Count() * 3) - 1
|
|
);
|
|
|
|
for (auto& Face : Submesh.Faces)
|
|
{
|
|
auto& Vertex1 = Submesh.Vertices[Face[2]].Color();
|
|
auto& Vertex2 = Submesh.Vertices[Face[1]].Color();
|
|
auto& Vertex3 = Submesh.Vertices[Face[0]].Color();
|
|
|
|
Writer.WriteFmt(
|
|
" %f %f %f %f"
|
|
" %f %f %f %f"
|
|
" %f %f %f %f",
|
|
Vertex1[0] / 255.f, Vertex1[1] / 255.f, Vertex1[2] / 255.f, Vertex1[3] / 255.f,
|
|
Vertex2[0] / 255.f, Vertex2[1] / 255.f, Vertex2[2] / 255.f, Vertex2[3] / 255.f,
|
|
Vertex3[0] / 255.f, Vertex3[1] / 255.f, Vertex3[2] / 255.f, Vertex3[3] / 255.f
|
|
);
|
|
}
|
|
|
|
Writer.WriteLineFmt(
|
|
";\n"
|
|
"setAttr \".covm[0]\" 0 1 1;\nsetAttr \".cdvm[0]\" 0 1 1;\nsetAttr -s %d \".vt\";",
|
|
Submesh.Vertices.Count()
|
|
);
|
|
|
|
if (Submesh.Vertices.Count() == 1)
|
|
Writer.Write("setAttr \".vt[0]\"");
|
|
else
|
|
Writer.WriteFmt("setAttr \".vt[0:%d]\"", Submesh.Vertices.Count() - 1);
|
|
|
|
for (auto& Vertex : Submesh.Vertices)
|
|
{
|
|
auto& Position = Vertex.Position();
|
|
Writer.WriteFmt(" %f %f %f", Position.X, Position.Y, Position.Z);
|
|
}
|
|
|
|
Writer.WriteFmt(
|
|
";\n"
|
|
"setAttr -s %d \".ed\";\n"
|
|
"setAttr \".ed[0:%d]\"",
|
|
(Submesh.Faces.Count() * 3),
|
|
(Submesh.Faces.Count() * 3) - 1
|
|
);
|
|
|
|
for (auto& Face : Submesh.Faces)
|
|
Writer.WriteFmt(" %d %d 0 %d %d 0 %d %d 0", Face[2], Face[1], Face[1], Face[0], Face[0], Face[2]);
|
|
|
|
Writer.WriteFmt(
|
|
";\n"
|
|
"setAttr -s %d \".n\";\n"
|
|
"setAttr \".n[0:%d]\" -type \"float3\"",
|
|
(Submesh.Faces.Count() * 3),
|
|
(Submesh.Faces.Count() * 3) - 1
|
|
);
|
|
|
|
for (auto& Face : Submesh.Faces)
|
|
{
|
|
auto& Vertex1 = Submesh.Vertices[Face[2]].Normal();
|
|
auto& Vertex2 = Submesh.Vertices[Face[1]].Normal();
|
|
auto& Vertex3 = Submesh.Vertices[Face[0]].Normal();
|
|
|
|
Writer.WriteFmt(
|
|
" %f %f %f"
|
|
" %f %f %f"
|
|
" %f %f %f",
|
|
Vertex1.X, Vertex1.Y, Vertex1.Z,
|
|
Vertex2.X, Vertex2.Y, Vertex2.Z,
|
|
Vertex3.X, Vertex3.Y, Vertex3.Z
|
|
);
|
|
}
|
|
|
|
Writer.WriteLine(";");
|
|
|
|
if (Submesh.Faces.Count() == 1)
|
|
Writer.WriteFmt("setAttr -s %d \".fc[0]\" -type \"polyFaces\"", Submesh.Faces.Count());
|
|
else
|
|
Writer.WriteFmt("setAttr -s %d \".fc[0:%d]\" -type \"polyFaces\"", Submesh.Faces.Count(), Submesh.Faces.Count() - 1);
|
|
|
|
uint32_t FaceIndex = 0;
|
|
|
|
for (auto& Face : Submesh.Faces)
|
|
{
|
|
Writer.WriteFmt(" f 3 %d %d %d", FaceIndex, (FaceIndex + 1), (FaceIndex + 2));
|
|
|
|
for (uint8_t i = 0; i < Submesh.Vertices.UVLayerCount(); i++)
|
|
Writer.WriteFmt(" mu %d 3 %d %d %d", i, Face[2], Face[1], Face[0]);
|
|
|
|
Writer.WriteFmt(" mc 0 3 %d %d %d", FaceIndex, (FaceIndex + 1), (FaceIndex + 2));
|
|
|
|
FaceIndex += 3;
|
|
}
|
|
|
|
Writer.WriteLine(
|
|
";\n"
|
|
"setAttr \".cd\" -type \"dataPolyComponent\" Index_Data Edge 0 ;\nsetAttr \".cvd\" -type \"dataPolyComponent\" Index_Data Vertex 0 ;\nsetAttr \".hfd\" -type \"dataPolyComponent\" Index_Data Face 0 ;"
|
|
);
|
|
|
|
SubmeshIndex++;
|
|
}
|
|
|
|
Writer.Write("\n");
|
|
|
|
for (auto& Material : Model.Materials)
|
|
{
|
|
auto MaterialName = (char*)Material.Name;
|
|
|
|
Writer.WriteLineFmt(
|
|
"createNode shadingEngine -n \"%sSG\";\n"
|
|
"setAttr \".ihi\" 0;\n"
|
|
"setAttr \".ro\" yes;\n"
|
|
"createNode materialInfo -n \"%sMI\";\r\ncreateNode lambert -n \"%s\";\n"
|
|
"createNode place2dTexture -n \"%sP2DT\";",
|
|
MaterialName,
|
|
MaterialName, MaterialName,
|
|
MaterialName
|
|
);
|
|
|
|
auto DiffuseTexture = (Material.Slots.ContainsKey(MaterialSlotType::Albedo))
|
|
? MaterialSlotType::Albedo : (Material.Slots.ContainsKey(MaterialSlotType::Diffuse) ? MaterialSlotType::Diffuse : MaterialSlotType::Invalid);
|
|
|
|
if (DiffuseTexture != MaterialSlotType::Invalid)
|
|
{
|
|
Writer.WriteLineFmt(
|
|
"createNode file -n \"%sFILE\";\n"
|
|
"setAttr \".ftn\" -type \"string\" \"%s\";",
|
|
MaterialName,
|
|
(char*)String(Material.Slots[DiffuseTexture].first).Replace("\\", "\\\\")
|
|
);
|
|
}
|
|
}
|
|
|
|
uint32_t LightConnectionIndex = 2;
|
|
|
|
for (auto& Material : Model.Materials)
|
|
{
|
|
auto MaterialName = (char*)Material.Name;
|
|
|
|
Writer.WriteLineFmt(
|
|
"connectAttr \":defaultLightSet.msg\" \"lightLinker1.lnk[%d].llnk\";\n"
|
|
"connectAttr \"%sSG.msg\" \"lightLinker1.lnk[%d].olnk\";\n"
|
|
"connectAttr \":defaultLightSet.msg\" \"lightLinker1.slnk[%d].sllk\";\n"
|
|
"connectAttr \"%sSG.msg\" \"lightLinker1.slnk[%d].solk\";\n"
|
|
"connectAttr \"%s.oc\" \"%sSG.ss\";\n"
|
|
"connectAttr \"%sSG.msg\" \"%sMI.sg\";\n"
|
|
"connectAttr \"%s.msg\" \"%sMI.m\";",
|
|
LightConnectionIndex,
|
|
MaterialName, LightConnectionIndex,
|
|
LightConnectionIndex,
|
|
MaterialName, LightConnectionIndex,
|
|
MaterialName, MaterialName,
|
|
MaterialName, MaterialName,
|
|
MaterialName, MaterialName
|
|
);
|
|
|
|
auto DiffuseTexture = (Material.Slots.ContainsKey(MaterialSlotType::Albedo))
|
|
? MaterialSlotType::Albedo : (Material.Slots.ContainsKey(MaterialSlotType::Diffuse) ? MaterialSlotType::Diffuse : MaterialSlotType::Invalid);
|
|
|
|
if (DiffuseTexture != MaterialSlotType::Invalid)
|
|
{
|
|
Writer.WriteLineFmt(
|
|
"connectAttr \"%sFILE.msg\" \"%sMI.t\" -na;\n"
|
|
"connectAttr \"%sFILE.oc\" \"%s.c\";\n"
|
|
"connectAttr \"%sP2DT.c\" \"%sFILE.c\";\n"
|
|
"connectAttr \"%sP2DT.tf\" \"%sFILE.tf\";\n"
|
|
"connectAttr \"%sP2DT.rf\" \"%sFILE.rf\";\n"
|
|
"connectAttr \"%sP2DT.mu\" \"%sFILE.mu\";\n"
|
|
"connectAttr \"%sP2DT.mv\" \"%sFILE.mv\";\n"
|
|
"connectAttr \"%sP2DT.s\" \"%sFILE.s\";\n"
|
|
"connectAttr \"%sP2DT.wu\" \"%sFILE.wu\";\n"
|
|
"connectAttr \"%sP2DT.wv\" \"%sFILE.wv\";\n"
|
|
"connectAttr \"%sP2DT.re\" \"%sFILE.re\";\n"
|
|
"connectAttr \"%sP2DT.of\" \"%sFILE.of\";\n"
|
|
"connectAttr \"%sP2DT.r\" \"%sFILE.ro\";\n"
|
|
"connectAttr \"%sP2DT.n\" \"%sFILE.n\";\n"
|
|
"connectAttr \"%sP2DT.vt1\" \"%sFILE.vt1\";\n"
|
|
"connectAttr \"%sP2DT.vt2\" \"%sFILE.vt2\";\n"
|
|
"connectAttr \"%sP2DT.vt3\" \"%sFILE.vt3\";\n"
|
|
"connectAttr \"%sP2DT.vc1\" \"%sFILE.vc1\";\n"
|
|
"connectAttr \"%sP2DT.o\" \"%sFILE.uv\";\n"
|
|
"connectAttr \"%sP2DT.ofs\" \"%sFILE.fs\";\n",
|
|
MaterialName, MaterialName,
|
|
MaterialName, MaterialName,
|
|
MaterialName, MaterialName,
|
|
MaterialName, MaterialName,
|
|
MaterialName, MaterialName,
|
|
MaterialName, MaterialName,
|
|
MaterialName, MaterialName,
|
|
MaterialName, MaterialName,
|
|
MaterialName, MaterialName,
|
|
MaterialName, MaterialName,
|
|
MaterialName, MaterialName,
|
|
MaterialName, MaterialName,
|
|
MaterialName, MaterialName,
|
|
MaterialName, MaterialName,
|
|
MaterialName, MaterialName,
|
|
MaterialName, MaterialName,
|
|
MaterialName, MaterialName,
|
|
MaterialName, MaterialName,
|
|
MaterialName, MaterialName,
|
|
MaterialName, MaterialName
|
|
);
|
|
}
|
|
|
|
Writer.WriteLineFmt(
|
|
"connectAttr \"%sSG.pa\" \":renderPartition.st\" -na;\n"
|
|
"connectAttr \"%s.msg\" \":defaultShaderList1.s\" -na;\n"
|
|
"connectAttr \"%sP2DT.msg\" \":defaultRenderUtilityList1.u\" -na;\n"
|
|
"connectAttr \"%sFILE.msg\" \":defaultTextureList1.tx\" -na;\n",
|
|
MaterialName,
|
|
MaterialName,
|
|
MaterialName,
|
|
MaterialName
|
|
);
|
|
|
|
LightConnectionIndex++;
|
|
}
|
|
|
|
SubmeshIndex = 0;
|
|
|
|
for (auto& Submesh : Model.Meshes)
|
|
{
|
|
Writer.WriteLineFmt(
|
|
"setAttr -s %d \"MeshShape_%d.iog\";",
|
|
Submesh.Vertices.UVLayerCount(), SubmeshIndex
|
|
);
|
|
|
|
for (uint8_t i = 0; i < Submesh.Vertices.UVLayerCount(); i++)
|
|
{
|
|
if (Submesh.MaterialIndices[i] < 0)
|
|
continue;
|
|
|
|
Writer.WriteLineFmt(
|
|
"connectAttr \"MeshShape_%d.iog[%d]\" \"%sSG.dsm\" -na;",
|
|
SubmeshIndex, i, (char*)Model.Materials[Submesh.MaterialIndices[i]].Name
|
|
);
|
|
}
|
|
|
|
SubmeshIndex++;
|
|
}
|
|
|
|
Writer.WriteLine(
|
|
"createNode transform -n \"Joints\";\nsetAttr \".ove\" yes;\n"
|
|
);
|
|
|
|
for (auto& Bone : Model.Bones)
|
|
{
|
|
if (Bone.Parent() == -1)
|
|
Writer.WriteLineFmt("createNode joint -n \"%s\" -p \"Joints\";", (char*)Bone.Name());
|
|
else
|
|
Writer.WriteLineFmt("createNode joint -n \"%s\" -p \"%s\";", (char*)Bone.Name(), (char*)Model.Bones[Bone.Parent()].Name());
|
|
|
|
if (Bone.GetFlag(BoneFlags::HasLocalSpaceMatrices))
|
|
{
|
|
auto Rotation = Bone.LocalRotation().ToEulerAngles();
|
|
|
|
auto& Position = Bone.LocalPosition();
|
|
auto& Scale = Bone.Scale();
|
|
|
|
Writer.WriteLineFmt(
|
|
"addAttr -ci true -sn \"liw\" -ln \"lockInfluenceWeights\" -bt \"lock\" -min 0 -max 1 -at \"bool\";\n"
|
|
"setAttr \".uoc\" yes;\n"
|
|
"setAttr \".ove\" yes;\n"
|
|
"setAttr \".t\" -type \"double3\" %f %f %f ;\n"
|
|
"setAttr \".mnrl\" -type \"double3\" -360 -360 -360 ;\n"
|
|
"setAttr \".mxrl\" -type \"double3\" 360 360 360 ;\n"
|
|
"setAttr \".radi\" 0.50;\n"
|
|
"setAttr \".jo\" -type \"double3\" %f %f %f;\n"
|
|
"setAttr \".scale\" -type \"double3\" %f %f %f;\n",
|
|
Position.X, Position.Y, Position.Z,
|
|
Rotation.X, Rotation.Y, Rotation.Z,
|
|
Scale.X, Scale.Y, Scale.Z
|
|
);
|
|
}
|
|
else
|
|
{
|
|
auto Rotation = Bone.GlobalRotation().ToEulerAngles();
|
|
|
|
auto& Position = Bone.GlobalPosition();
|
|
auto& Scale = Bone.Scale();
|
|
|
|
Writer.WriteLineFmt(
|
|
"addAttr -ci true -sn \"liw\" -ln \"lockInfluenceWeights\" -bt \"lock\" -min 0 -max 1 -at \"bool\";\n"
|
|
"setAttr \".uoc\" yes;\n"
|
|
"setAttr \".ove\" yes;\n"
|
|
"setAttr \".it\" no;\n"
|
|
"setAttr \".t\" -type \"double3\" %f %f %f ;\n"
|
|
"setAttr \".mnrl\" -type \"double3\" -360 -360 -360 ;\n"
|
|
"setAttr \".mxrl\" -type \"double3\" 360 360 360 ;\n"
|
|
"setAttr \".radi\" 0.50;\n"
|
|
"setAttr \".jo\" -type \"double3\" %f %f %f;\n"
|
|
"setAttr \".scale\" -type \"double3\" %f %f %f;\n",
|
|
Position.X, Position.Y, Position.Z,
|
|
Rotation.X, Rotation.Y, Rotation.Z,
|
|
Scale.X, Scale.Y, Scale.Z
|
|
);
|
|
}
|
|
}
|
|
|
|
auto Binder = IO::StreamWriter(IO::File::Create(IO::Path::Combine(IO::Path::GetDirectoryName(Path), FileName + "_BIND.mel")));
|
|
|
|
Binder.WriteLine(
|
|
"/*\n* Autodesk Maya Bind Script\n*/\n"
|
|
);
|
|
|
|
SubmeshIndex = 0;
|
|
|
|
for (auto& Submesh : Model.Meshes)
|
|
{
|
|
Binder.WriteLineFmt(
|
|
"global proc KoreMesh_%08x_%02d_BindFunc()\n{\n"
|
|
" select -r KoreMesh_%08x_%02d;",
|
|
Hash, SubmeshIndex,
|
|
Hash, SubmeshIndex
|
|
);
|
|
|
|
auto MaximumInfluence = Submesh.Vertices.WeightCount();
|
|
|
|
uint32_t BoneMapIndex = 0;
|
|
Dictionary<uint32_t, uint8_t> BoneMap;
|
|
Dictionary<uint32_t, uint32_t> ReverseBoneMap;
|
|
List<String> BoneNames;
|
|
|
|
for (auto& Vertex : Submesh.Vertices)
|
|
{
|
|
for (uint8_t i = 0; i < Vertex.WeightCount(); i++)
|
|
{
|
|
auto& Weight = Vertex.Weights(i);
|
|
|
|
if (BoneMap.Add(Weight.Bone, 0))
|
|
{
|
|
BoneNames.Add(Model.Bones[Weight.Bone].Name());
|
|
ReverseBoneMap.Add(BoneMapIndex, Weight.Bone);
|
|
BoneMapIndex++;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (auto& BoneName : BoneNames)
|
|
Binder.WriteLineFmt(" select -add %s;", (char*)BoneName);
|
|
|
|
Binder.WriteLineFmt(
|
|
" newSkinCluster \"-toSelectedBones -mi %d -omi true -dr 5.0 -rui false\";\n"
|
|
" string $clu = findRelatedSkinCluster(\"KoreMesh_%08x_%02d\");",
|
|
MaximumInfluence,
|
|
Hash, SubmeshIndex
|
|
);
|
|
|
|
// If we are a complex skin, we need a weight matrix
|
|
if (BoneNames.Count() > 1)
|
|
{
|
|
Binder.WriteFmt(" int $NV = %d;\n matrix $WM[%d][%d] = <<", Submesh.Vertices.Count(), Submesh.Vertices.Count(), BoneNames.Count());
|
|
|
|
for (uint32_t i = 0; i < Submesh.Vertices.Count(); i++)
|
|
{
|
|
auto Vertex = Submesh.Vertices[i];
|
|
|
|
if (i != 0)
|
|
Binder.Write(";");
|
|
|
|
for (uint32_t b = 0; b < BoneNames.Count(); b++)
|
|
{
|
|
if (b != 0)
|
|
Binder.Write(",");
|
|
|
|
float WeightValue = 0.0f;
|
|
|
|
for (uint8_t w = 0; w < Vertex.WeightCount(); w++)
|
|
{
|
|
if (Vertex.Weights(w).Bone == ReverseBoneMap[b])
|
|
{
|
|
WeightValue = Vertex.Weights(w).Value;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (WeightValue == 0.0f || WeightValue == 1.0f)
|
|
Binder.WriteFmt("%d", (uint32_t)WeightValue);
|
|
else
|
|
Binder.WriteFmt("%f", WeightValue);
|
|
}
|
|
}
|
|
|
|
Binder.WriteLine(">>;");
|
|
Binder.Write(" for ($i = 0; $i < $NV; $i++) {");
|
|
|
|
Binder.WriteFmt(" setAttr($clu + \".weightList[\" + $i + \"].weights[0:%d]\")", BoneNames.Count() - 1);
|
|
|
|
for (uint32_t i = 0; i < BoneNames.Count(); i++)
|
|
Binder.WriteFmt(" $WM[$i][%d]", i);
|
|
|
|
Binder.WriteLine("; }");
|
|
}
|
|
|
|
Binder.WriteLine("}\n");
|
|
SubmeshIndex++;
|
|
}
|
|
|
|
Binder.WriteLine("global proc RunAdvancedScript()\n{");
|
|
|
|
SubmeshIndex = 0;
|
|
|
|
for (auto& Submesh : Model.Meshes)
|
|
Binder.WriteLineFmt(" catch(KoreMesh_%08x_%02d_BindFunc());", Hash, SubmeshIndex++);
|
|
|
|
Binder.WriteLine("}\n\nglobal proc NamespacePurge()\n{\n string $allNodes[] = `ls`;\n for($node in $allNodes) {\n string $buffer[];\n tokenize $node \":\" $buffer;\n string $newName = $buffer[size($buffer)-1];\n catchQuiet(`rename $node $newName`);\n }\n}\n\nprint(\"Currently binding the current model, please wait...\\n\");\nNamespacePurge();\nRunAdvancedScript();\nprint(\"The model has been binded.\\n\");\n");
|
|
|
|
return true;
|
|
}
|
|
|
|
imstring AutodeskMaya::ModelExtension()
|
|
{
|
|
return ".ma";
|
|
}
|
|
|
|
imstring AutodeskMaya::AnimationExtension()
|
|
{
|
|
return ".anim";
|
|
}
|
|
|
|
ExporterScale AutodeskMaya::ExportScale()
|
|
{
|
|
return ExporterScale::CM;
|
|
}
|
|
|
|
bool AutodeskMaya::SupportsAnimations()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
bool AutodeskMaya::SupportsModels()
|
|
{
|
|
return true;
|
|
}
|
|
}
|