internal void ExportMeshFromFrame(ImportedFrame rootFrame, ImportedFrame meshFrame, List <ImportedMesh> meshList, List <ImportedMaterial> materialList, List <ImportedTexture> textureList, bool exportSkins) { var meshNode = _frameToNode[meshFrame]; var mesh = ImportedHelpers.FindMesh(meshFrame.Path, meshList); ExportMesh(rootFrame, materialList, textureList, meshNode, mesh, exportSkins); }
internal void ExportFrame(List <ImportedMesh> meshList, List <ImportedFrame> meshFrames, ImportedFrame rootFrame) { var rootNode = AsFbxGetSceneRootNode(_pContext); Debug.Assert(rootNode != IntPtr.Zero); var nodeStack = new Stack <IntPtr>(); var frameStack = new Stack <ImportedFrame>(); nodeStack.Push(rootNode); frameStack.Push(rootFrame); while (nodeStack.Count > 0) { var parentNode = nodeStack.Pop(); var frame = frameStack.Pop(); var childNode = AsFbxExportSingleFrame(_pContext, parentNode, frame.Path, frame.Name, frame.LocalPosition, frame.LocalRotation, frame.LocalScale); if (meshList != null && ImportedHelpers.FindMesh(frame.Path, meshList) != null) { meshFrames.Add(frame); } _frameToNode.Add(frame, childNode); for (var i = frame.Count - 1; i >= 0; i -= 1) { nodeStack.Push(childNode); frameStack.Push(frame[i]); } } }
private static void SearchHierarchy(ImportedFrame rootFrame, List <ImportedMesh> meshList, HashSet <string> exportFrames) { var frameStack = new Stack <ImportedFrame>(); frameStack.Push(rootFrame); while (frameStack.Count > 0) { var frame = frameStack.Pop(); var meshListSome = ImportedHelpers.FindMesh(frame.Path, meshList); if (meshListSome != null) { var parent = frame; while (parent != null) { exportFrames.Add(parent.Path); parent = parent.Parent; } var boneList = meshListSome.BoneList; if (boneList != null) { foreach (var bone in boneList) { if (!exportFrames.Contains(bone.Path)) { var boneParent = rootFrame.FindFrameByPath(bone.Path); while (boneParent != null) { exportFrames.Add(boneParent.Path); boneParent = boneParent.Parent; } } } } } for (var i = frame.Count - 1; i >= 0; i -= 1) { frameStack.Push(frame[i]); } } }
private void ConvertTexture2D(Texture2D tex2D, string name) { ImportedTexture iTex = ImportedHelpers.FindTexture(name, TextureList); if (iTex != null) { return; } using (MemoryStream memStream = new MemoryStream()) { tex2D.Export(memStream); memStream.Position = 0; iTex = new ImportedTexture(memStream, name); } TextureList.Add(iTex); }
public static void ReplaceAnimation(WorkspaceAnimation wsAnimation, List <ImportedFrame> wsSkeleton, reaParser parser, int resampleCount, bool linear, ReplaceAnimationMethod replaceMethod, int insertPos, bool negateQuaternionFlips) { Report.ReportLog("Replacing animation ..."); List <KeyValuePair <string, ImportedAnimationSampledTrack> > newTrackList = FbxUtility.CopySampledAnimation(wsAnimation, resampleCount, linear); reaANICsection animationNodeList = parser.ANIC; ImportedSampledAnimation iAnim = new ImportedSampledAnimation(); iAnim.TrackList = new List <ImportedAnimationSampledTrack>(animationNodeList.Count); Dictionary <string, ImportedAnimationSampledTrack> animationNodeDic = null; if (replaceMethod != ReplaceAnimationMethod.Replace) { animationNodeDic = new Dictionary <string, ImportedAnimationSampledTrack>(); foreach (reaAnimationTrack animationNode in animationNodeList) { ImportedFrame boneFrame = ImportedHelpers.FindFrame(animationNode.boneFrame, wsSkeleton[0]); bool isTopFrame = boneFrame != null && boneFrame.Parent == wsSkeleton[0]; ImportedAnimationSampledTrack iTrack = Plugins.REMConverter.ConvertTrack(animationNode, isTopFrame); iTrack.Name = animationNode.boneFrame; animationNodeDic.Add(animationNode.boneFrame, iTrack); iAnim.TrackList.Add(iTrack); } } FbxUtility.ReplaceAnimation(replaceMethod, insertPos, newTrackList, iAnim, animationNodeDic, negateQuaternionFlips); animationNodeList.ChildList.Clear(); foreach (var newTrack in iAnim.TrackList) { ImportedFrame boneFrame = ImportedHelpers.FindFrame(newTrack.Name, wsSkeleton[0]); bool isTopFrame = boneFrame != null && boneFrame.Parent == wsSkeleton[0]; reaAnimationTrack animationNode = Plugins.REMConverter.ConvertTrack(newTrack, isTopFrame); animationNodeList.AddChild(animationNode); } }
public static void ReplaceMesh(remBone frame, remParser parser, WorkspaceMesh mesh, List <ImportedMaterial> materials, List <ImportedTexture> textures, bool merge, CopyMeshMethod normalsMethod, CopyMeshMethod bonesMethod, bool meshFrameCorrection) { remMesh frameREMMesh = rem.FindMesh(frame, parser.MESC); int startPos = 0; if (meshFrameCorrection) { // frame.matrix = Matrix.Scaling(-1f, 1f, 1f) * Matrix.RotationYawPitchRoll(0f, (float)(Math.PI / 2), (float)Math.PI); frame.matrix = Matrix.Identity; frame.matrix.M22 = frame.matrix.M33 = 0f; frame.matrix.M23 = frame.matrix.M32 = 1f; startPos = mesh.Name.IndexOf("(Scale"); if (startPos > 0) { int endPos = mesh.Name.IndexOf(')'); float scale; if (Single.TryParse(mesh.Name.Substring(startPos + 7, endPos - startPos - 7), out scale)) { frame.matrix *= Matrix.Scaling(new Vector3(scale)); } remId newFrameName = new remId(mesh.Name.Substring(0, startPos)); if (newFrameName != frame.name) { if (rem.FindFrame(newFrameName, parser.BONC.rootFrame) == null) { frame.name = newFrameName; } else { Report.ReportLog("Warning! Cant rename frame (and mesh) " + mesh.Name + " automatically to " + newFrameName + "."); } } } } Matrix transform = Matrix.Scaling(-1f, 1f, 1f); remBone transformFrame = frame; while (transformFrame != parser.BONC.rootFrame) { transform *= transformFrame.matrix; transformFrame = transformFrame.Parent as remBone; } transform.Invert(); string[] materialNames; int[] indices; bool[] worldCoords; bool[] replaceSubmeshesOption; remMesh newREMMesh = CreateMesh(mesh, out materialNames, out indices, out worldCoords, out replaceSubmeshesOption); if (startPos > 0) { newREMMesh.name = frame.name; } Mesh newMesh = new Mesh(newREMMesh, CreateBoneList(mesh, transform)); remSkin frameMeshSkin = null; Mesh frameMesh = null; if (frameREMMesh != null) { newMesh.name = frameREMMesh.name; frameMeshSkin = rem.FindSkin(frameREMMesh.name, parser.SKIC); frameMesh = new Mesh(frameREMMesh, frameMeshSkin); } Submesh[] replaceSubmeshes = frameMesh != null ? new Submesh[frameMesh.Count] : null; List <Submesh> addSubmeshes = new List <Submesh>(newMesh.Count); for (int i = 0; i < newMesh.Count; i++) { remMaterial mat = rem.FindMaterial(new remId(materialNames[i]), parser.MATC); if (materials != null) { if (mat == null) { mat = CreateMaterial(ImportedHelpers.FindMaterial(materialNames[i], materials)); parser.MATC.AddChild(mat); } /* if (textures != null) * { * string texName = materials[i].Textures[0]; * remMaterial texMat = rem.FindMaterial(parser.MATC, new remId(texName)); * if (texMat == null) * { * for (int k = 0; k < textures.Count; k++) * { * if (textures[k].Name == texName) * { * // texMat = CreateTexture(textures[k], Path.GetDirectoryName(parser.ODFPath)); * break; * } * } * } * }*/ } Submesh newSubmesh = newMesh[i]; if (mat != null) { newSubmesh.MaterialName = mat.name; } if (worldCoords[i]) { List <remVertex> newVertexList = newSubmesh.VertexList; for (int j = 0; j < newVertexList.Count; j++) { newVertexList[j].Position = Vector3.TransformCoordinate(newVertexList[j].Position, transform); } } Submesh baseSubmesh = null; List <remBoneWeights> newBones = null; int idx = indices[i]; if ((frameMesh != null) && (idx >= 0) && (idx < frameMesh.Count)) { baseSubmesh = frameMesh[idx]; if ((bonesMethod == CopyMeshMethod.CopyOrder) || (bonesMethod == CopyMeshMethod.CopyNear)) { List <remBoneWeights> baseBones = baseSubmesh.BoneList; if (baseBones != null) { newBones = new List <remBoneWeights>(baseBones.Count); foreach (remBoneWeights boneWeights in baseBones) { remBoneWeights copy = boneWeights.Clone(); newBones.Add(copy); } newSubmesh.BoneList = newBones; } } else if (bonesMethod == CopyMeshMethod.Replace) { newBones = newSubmesh.BoneList; } } else { newBones = newSubmesh.BoneList; } if (baseSubmesh != null) { if (normalsMethod == CopyMeshMethod.CopyOrder) { rem.CopyNormalsOrder(baseSubmesh.VertexList, newSubmesh.VertexList); } else if (normalsMethod == CopyMeshMethod.CopyNear) { rem.CopyNormalsNear(baseSubmesh.VertexList, newSubmesh.VertexList); } if (bonesMethod == CopyMeshMethod.CopyOrder) { rem.CopyBonesOrder(baseSubmesh.VertexList, newSubmesh.VertexList, newBones); } else if (bonesMethod == CopyMeshMethod.CopyNear) { rem.CopyBonesNear(baseSubmesh.VertexList, newSubmesh.VertexList, newBones); } } if ((baseSubmesh != null) && merge && replaceSubmeshesOption[i]) { replaceSubmeshes[idx] = newSubmesh; } else { addSubmeshes.Add(newSubmesh); } } if ((frameMesh != null) && merge) { newMesh.ChildList.Clear(); newMesh.ChildList.Capacity = replaceSubmeshes.Length + addSubmeshes.Count; for (int i = 0, submeshesRemoved = 0; i < replaceSubmeshes.Length; i++) { if (replaceSubmeshes[i] == null) { Submesh newSubmesh = frameMesh[i - submeshesRemoved++]; newMesh.AddChild(newSubmesh); } else { newMesh.AddChild(replaceSubmeshes[i]); } } newMesh.ChildList.AddRange(addSubmeshes); } remSkin skin; newREMMesh = newMesh.CreateMesh(out skin); newREMMesh.frame = frame.name; if (frameREMMesh != null) { CopyUnknowns(frameREMMesh, newREMMesh); parser.MESC.InsertChild(parser.MESC.IndexOf(frameREMMesh), newREMMesh); RemoveMesh(parser, frameREMMesh); } else { CreateUnknowns(newREMMesh); parser.MESC.AddChild(newREMMesh); } if (skin.Count > 0) { parser.SKIC.AddChild(skin); } }
private void ExportMesh(ImportedFrame rootFrame, List <ImportedMaterial> materialList, List <ImportedTexture> textureList, IntPtr frameNode, ImportedMesh importedMesh, bool exportSkins) { var boneList = importedMesh.BoneList; var totalBoneCount = 0; var hasBones = false; if (exportSkins && boneList?.Count > 0) { totalBoneCount = boneList.Count; hasBones = true; } var pClusterArray = IntPtr.Zero; try { if (hasBones) { pClusterArray = AsFbxMeshCreateClusterArray(totalBoneCount); foreach (var bone in boneList) { if (bone.Path != null) { var frame = rootFrame.FindFrameByPath(bone.Path); var boneNode = _frameToNode[frame]; var cluster = AsFbxMeshCreateCluster(_pContext, boneNode); AsFbxMeshAddCluster(pClusterArray, cluster); } else { AsFbxMeshAddCluster(pClusterArray, IntPtr.Zero); } } } var mesh = AsFbxMeshCreateMesh(_pContext, frameNode); var totalVertexCount = 0; foreach (var m in importedMesh.SubmeshList) { totalVertexCount += m.VertexList.Count; } AsFbxMeshInitControlPoints(mesh, totalVertexCount); if (importedMesh.hasNormal) { AsFbxMeshCreateElementNormal(mesh); } if (importedMesh.hasUV[0]) { AsFbxMeshCreateDiffuseUV(mesh, 0); } if (importedMesh.hasUV[1]) { AsFbxMeshCreateNormalMapUV(mesh, 1); } if (importedMesh.hasTangent) { AsFbxMeshCreateElementTangent(mesh); } if (importedMesh.hasColor) { AsFbxMeshCreateElementVertexColor(mesh); } AsFbxMeshCreateElementMaterial(mesh); var firstVertex = 0; foreach (var meshObj in importedMesh.SubmeshList) { var materialIndex = 0; var mat = ImportedHelpers.FindMaterial(meshObj.Material, materialList); if (mat != null) { var foundMat = _createdMaterials.FindIndex(kv => kv.Key == mat.Name); IntPtr pMat; if (foundMat >= 0) { pMat = _createdMaterials[foundMat].Value; } else { var diffuse = mat.Diffuse; var ambient = mat.Ambient; var emissive = mat.Emissive; var specular = mat.Specular; var reflection = mat.Reflection; pMat = AsFbxCreateMaterial(_pContext, mat.Name, in diffuse, in ambient, in emissive, in specular, in reflection, mat.Shininess, mat.Transparency); _createdMaterials.Add(new KeyValuePair <string, IntPtr>(mat.Name, pMat)); } materialIndex = AsFbxAddMaterialToFrame(frameNode, pMat); var hasTexture = false; foreach (var texture in mat.Textures) { var tex = ImportedHelpers.FindTexture(texture.Name, textureList); var pTexture = ExportTexture(tex); if (pTexture != IntPtr.Zero) { switch (texture.Dest) { case 0: case 1: case 2: case 3: { AsFbxLinkTexture(texture.Dest, pTexture, pMat, texture.Offset.X, texture.Offset.Y, texture.Scale.X, texture.Scale.Y); hasTexture = true; break; } default: break; } } } if (hasTexture) { AsFbxSetFrameShadingModeToTextureShading(frameNode); } } var vertexList = meshObj.VertexList; var vertexCount = vertexList.Count; for (var j = 0; j < vertexCount; j += 1) { var importedVertex = vertexList[j]; var vertex = importedVertex.Vertex; AsFbxMeshSetControlPoint(mesh, j + firstVertex, vertex.X, vertex.Y, vertex.Z); if (importedMesh.hasNormal) { var normal = importedVertex.Normal; AsFbxMeshElementNormalAdd(mesh, 0, normal.X, normal.Y, normal.Z); } for (var uvIndex = 0; uvIndex < 2; uvIndex += 1) { if (importedMesh.hasUV[uvIndex]) { var uv = importedVertex.UV[uvIndex]; AsFbxMeshElementUVAdd(mesh, uvIndex, uv[0], uv[1]); } } if (importedMesh.hasTangent) { var tangent = importedVertex.Tangent; AsFbxMeshElementTangentAdd(mesh, 0, tangent.X, tangent.Y, tangent.Z, tangent.W); } if (importedMesh.hasColor) { var color = importedVertex.Color; AsFbxMeshElementVertexColorAdd(mesh, 0, color.R, color.G, color.B, color.A); } if (hasBones && importedVertex.BoneIndices != null) { var boneIndices = importedVertex.BoneIndices; var boneWeights = importedVertex.Weights; for (var k = 0; k < 4; k += 1) { if (boneIndices[k] < totalBoneCount && boneWeights[k] > 0) { AsFbxMeshSetBoneWeight(pClusterArray, boneIndices[k], j + firstVertex, boneWeights[k]); } } } } foreach (var face in meshObj.FaceList) { var index0 = face.VertexIndices[0] + firstVertex; var index1 = face.VertexIndices[1] + firstVertex; var index2 = face.VertexIndices[2] + firstVertex; AsFbxMeshAddPolygon(mesh, materialIndex, index0, index1, index2); } firstVertex += vertexCount; } if (hasBones) { IntPtr pSkinContext = IntPtr.Zero; try { pSkinContext = AsFbxMeshCreateSkinContext(_pContext, frameNode); unsafe { var boneMatrix = stackalloc float[16]; for (var j = 0; j < totalBoneCount; j += 1) { if (!FbxClusterArray_HasItemAt(pClusterArray, j)) { continue; } var m = boneList[j].Matrix; CopyMatrix4x4(in m, boneMatrix); AsFbxMeshSkinAddCluster(pSkinContext, pClusterArray, j, boneMatrix); } } AsFbxMeshAddDeformer(pSkinContext, mesh); } finally { AsFbxMeshDisposeSkinContext(ref pSkinContext); } } } finally { AsFbxMeshDisposeClusterArray(ref pClusterArray); } }
public static void ReplaceMesh(odfFrame frame, odfParser parser, WorkspaceMesh mesh, List <ImportedMaterial> materials, List <ImportedTexture> textures, bool merge, CopyMeshMethod normalsMethod, CopyMeshMethod bonesMethod) { Matrix transform = Matrix.Identity; odfFrame transformFrame = frame; while (transformFrame != null) { transform *= transformFrame.Matrix; transformFrame = transformFrame.Parent as odfFrame; } transform.Invert(); string[] materialNames; int[] indices; bool[] worldCoords; bool[] replaceSubmeshesOption; odfMesh newMesh = CreateMesh(mesh, parser.MeshSection._FormatType, out materialNames, out indices, out worldCoords, out replaceSubmeshesOption); odfMesh frameMesh = odf.FindMeshListSome(frame.MeshId, parser.MeshSection); if (frameMesh != null) { if (parser.UsedIDs == null) // prevent misleading error message { parser.CollectObjectIDs(); } newMesh.Id = frameMesh.Id; newMesh.Name = frameMesh.Name; parser.MeshSection.InsertChild(parser.MeshSection.IndexOf(frameMesh), newMesh); } else { newMesh.Id = parser.GetNewID(typeof(odfMesh)); frame.MeshId = newMesh.Id; parser.MeshSection.AddChild(newMesh); } Dictionary <ObjectID, ObjectID> submeshIDtranslation = new Dictionary <ObjectID, ObjectID>(newMesh.Count); odfSubmesh[] replaceSubmeshes = frameMesh != null ? new odfSubmesh[frameMesh.Count] : null; List <odfSubmesh> addSubmeshes = new List <odfSubmesh>(newMesh.Count); for (int i = 0; i < newMesh.Count; i++) { ObjectID[] texIDs = new ObjectID[4] { ObjectID.INVALID, ObjectID.INVALID, ObjectID.INVALID, ObjectID.INVALID }; odfMaterial mat = odf.FindMaterialInfo(materialNames[i], parser.MaterialSection); if (materials != null && mat == null) { ImportedMaterial impMat = ImportedHelpers.FindMaterial(materialNames[i], materials); if (impMat != null) { mat = CreateMaterial(impMat, parser.GetNewID(typeof(odfMaterial))); parser.MaterialSection.AddChild(mat); for (int j = 0; j < impMat.Textures.Length; j++) { string texName = impMat.Textures[j]; odfTexture tex = odf.FindTextureInfo(texName, parser.TextureSection); if (tex == null) { ImportedTexture impTex = ImportedHelpers.FindTexture(texName, textures); if (impTex != null) { tex = CreateTexture(impTex, parser.GetNewID(typeof(odfTexture)), parser.TextureSection._FormatType, Path.GetDirectoryName(parser.ODFPath)); parser.TextureSection.AddChild(tex); texIDs[j] = tex.Id; } } else { texIDs[j] = tex.Id; } } } } odfSubmesh newSubmesh = newMesh[i]; newSubmesh.Id = parser.GetNewID(typeof(odfSubmesh)); newSubmesh.MaterialId = mat != null ? mat.Id : ObjectID.INVALID; newSubmesh.TextureIds = texIDs; List <odfVertex> newVertexList = newSubmesh.VertexList; if (worldCoords[i]) { for (int j = 0; j < newVertexList.Count; j++) { newVertexList[j].Position = Vector3.TransformCoordinate(newVertexList[j].Position, transform); } } odfSubmesh baseSubmesh = null; odfBoneList newBones = null; int newBonesIdx = -1; int idx = indices[i]; if ((frameMesh != null) && (idx >= 0) && (idx < frameMesh.Count)) { baseSubmesh = frameMesh[idx]; submeshIDtranslation.Add(newSubmesh.Id, baseSubmesh.Id); for (int j = 0; j < baseSubmesh.TextureIds.Length; j++) { ObjectID texID = baseSubmesh.TextureIds[j]; newSubmesh.TextureIds[j] = texID; } newSubmesh.Name = new ObjectName(baseSubmesh.Name.Name, baseSubmesh.Name.Info); CopyUnknowns(baseSubmesh, newSubmesh, parser.MeshSection._FormatType); if ((bonesMethod == CopyMeshMethod.CopyOrder) || (bonesMethod == CopyMeshMethod.CopyNear)) { odfBoneList baseBones = odf.FindBoneList(baseSubmesh.Id, parser.EnvelopeSection); if (baseBones != null) { newBones = baseBones.Clone(); newBones.Id = ObjectID.INVALID; // parser.GetNewID(typeof(odfBoneList)); newBones.SubmeshId = newSubmesh.Id; newBonesIdx = parser.EnvelopeSection.IndexOf(baseBones); } } else if (bonesMethod == CopyMeshMethod.Replace) { newBones = CreateBoneList(ObjectID.INVALID /*parser.GetNewID(typeof(odfBoneList))*/, frame.Id, newSubmesh, mesh.BoneList, transform, parser.FrameSection.RootFrame); newBonesIdx = parser.EnvelopeSection.Count; } } else { CreateUnknowns(newSubmesh, parser.MeshSection._FormatType); newBones = CreateBoneList(ObjectID.INVALID /*parser.GetNewID(typeof(odfBoneList))*/, frame.Id, newSubmesh, mesh.BoneList, transform, parser.FrameSection.RootFrame); newBonesIdx = parser.EnvelopeSection.Count; } if (newBones != null) { parser.EnvelopeSection.InsertChild(newBonesIdx, newBones); } if (baseSubmesh != null) { if (normalsMethod == CopyMeshMethod.CopyOrder) { odf.CopyNormalsOrder(baseSubmesh.VertexList, newSubmesh.VertexList); } else if (normalsMethod == CopyMeshMethod.CopyNear) { odf.CopyNormalsNear(baseSubmesh.VertexList, newSubmesh.VertexList); } if (bonesMethod == CopyMeshMethod.CopyOrder) { odf.CopyBonesOrder(baseSubmesh.VertexList, newSubmesh.VertexList, newBones); } else if (bonesMethod == CopyMeshMethod.CopyNear) { odf.CopyBonesNear(baseSubmesh.VertexList, newSubmesh.VertexList, newBones); } } if ((baseSubmesh != null) && merge && replaceSubmeshesOption[i]) { replaceSubmeshes[idx] = newSubmesh; } else { addSubmeshes.Add(newSubmesh); } } if ((frameMesh != null) && merge) { newMesh.Clear(); newMesh.Capacity = replaceSubmeshes.Length + addSubmeshes.Count; for (int i = 0, submeshesRemoved = 0; i < replaceSubmeshes.Length; i++) { if (replaceSubmeshes[i] == null) { odfSubmesh newSubmesh = frameMesh[i - submeshesRemoved++]; frameMesh.RemoveChild(newSubmesh); // save the bone list from being deleted in RemoveMesh newMesh.AddChild(newSubmesh); } else { newMesh.AddChild(replaceSubmeshes[i]); } } newMesh.AddRange(addSubmeshes); } if (frameMesh != null) { RemoveMesh(parser, frameMesh, frame, false); parser.UsedIDs.Add((int)newMesh.Id, typeof(odfMesh)); frame.MeshId = newMesh.Id; List <ObjectID> removeKeyList = new List <ObjectID>(); foreach (odfSubmesh submesh in newMesh) { ObjectID newSubmeshID = submesh.Id; ObjectID baseSubmeshID; if (submeshIDtranslation.TryGetValue(newSubmeshID, out baseSubmeshID)) { if (odf.FindBoneList(baseSubmeshID, parser.EnvelopeSection) == null) { odfBoneList boneList = odf.FindBoneList(newSubmeshID, parser.EnvelopeSection); if (boneList != null) { boneList.SubmeshId = baseSubmeshID; } submesh.Id = baseSubmeshID; parser.UsedIDs.Remove((int)newSubmeshID); } foreach (KeyValuePair <ObjectID, ObjectID> pair in submeshIDtranslation) { if (pair.Value == baseSubmeshID) { removeKeyList.Add(pair.Key); } } foreach (ObjectID removeId in removeKeyList) { submeshIDtranslation.Remove(removeId); } removeKeyList.Clear(); } } } }
private void ConvertMaterial(Material mat) { ImportedMaterial iMat = ImportedHelpers.FindMaterial(mat.m_Name, MaterialList); if (iMat != null) { return; } iMat = new ImportedMaterial(); iMat.Name = mat.m_Name; foreach (var col in mat.m_SavedProperties.m_Colors) { switch (col.Key.name) { case "_Color": iMat.Diffuse = col.Value; break; case "_SColor": iMat.Ambient = col.Value; break; case "_ReflectColor": iMat.Emissive = col.Value; break; case "_SpecColor": iMat.Specular = col.Value; break; case "_RimColor": case "_OutlineColor": case "_ShadowColor": break; } } foreach (var flt in mat.m_SavedProperties.m_Floats) { switch (flt.Key.name) { case "_Shininess": iMat.Power = flt.Value; break; case "_RimPower": case "_Outline": break; } } iMat.Textures = new string[4]; int numTex = mat.m_SavedProperties.m_TexEnvs.Count > 4 ? 4 : mat.m_SavedProperties.m_TexEnvs.Count; for (int i = 0; i < numTex; i++) { var tex = mat.m_SavedProperties.m_TexEnvs[i]; Texture2D tex2D = tex.Value.m_Texture.instance; if (tex2D != null) { iMat.Textures[i] = tex2D.m_Name + "-" + tex.Key.name + "-" + "offset(X" + tex.Value.m_Offset.X.ToFloatString() + "Y" + tex.Value.m_Offset.Y.ToFloatString() + ")-scale(X" + tex.Value.m_Scale.X.ToFloatString() + "Y" + tex.Value.m_Scale.Y.ToFloatString() + ")" + (tex2D.m_TextureFormat == TextureFormat.DXT1 || tex2D.m_TextureFormat == TextureFormat.DXT5 ? ".dds" : ".tga"); ConvertTexture2D(tex2D, iMat.Textures[i]); } } MaterialList.Add(iMat); }
private void ConvertMeshes(List <remMesh> meshes, remParser parser) { MeshList = new List <ImportedMesh>(meshes.Count); MaterialList = new List <ImportedMaterial>(meshes.Count); TextureList = new List <ImportedTexture>(parser.MATC.Count); foreach (remMesh mesh in meshes) { ImportedMesh iMesh = new ImportedMesh(); MeshList.Add(iMesh); iMesh.BoneList = new List <ImportedBone>(); Dictionary <remId, byte> boneDic = new Dictionary <remId, byte>(); remSkin skin = rem.FindSkin(mesh.name, parser.SKIC); rem.Mesh convertedMesh = new rem.Mesh(mesh, skin); iMesh.SubmeshList = new List <ImportedSubmesh>(convertedMesh.Count); remBone meshFrame = rem.FindFrame(mesh.frame, parser.BONC.rootFrame); ImportedFrame iFrame = ImportedHelpers.FindFrame(mesh.frame, FrameList[0]); float s = (float)Math.Round(Math.Abs(meshFrame.matrix.M11), 5); iFrame.Name = iMesh.Name = mesh.name + (s != 1f ? "(Scale=" + s.ToString() + ")" : String.Empty); foreach (rem.Submesh submesh in convertedMesh) { ImportedSubmesh iSubmesh = new ImportedSubmesh(); iMesh.SubmeshList.Add(iSubmesh); remMaterial mat = rem.FindMaterial(submesh.MaterialName, parser.MATC); if (mat != null) { iSubmesh.Material = mat.name; ImportedMaterial iMat = ImportedHelpers.FindMaterial(iSubmesh.Material, MaterialList); if (iMat == null) { iMat = new ImportedMaterial(); MaterialList.Add(iMat); iMat.Name = iSubmesh.Material; iMat.Diffuse = new Color4(mat.diffuse); iMat.Ambient = new Color4(mat.ambient); iMat.Specular = new Color4(mat.specular); iMat.Emissive = new Color4(mat.emissive); iMat.Power = mat.specularPower; iMat.Textures = new string[4] { String.Empty, String.Empty, String.Empty, String.Empty }; if (mat.texture != null) { iMat.Textures[0] = mat.texture; if (ImportedHelpers.FindTexture(iMat.Textures[0], TextureList) == null) { try { ImportedTexture iTex = rem.ImportedTexture(mat.texture, parser.RemPath, true); TextureList.Add(iTex); } catch { Report.ReportLog("cant read texture " + iMat.Textures[0]); } } } } } List <Tuple <byte, float> >[] iSkin = new List <Tuple <byte, float> > [submesh.numVertices]; for (int i = 0; i < submesh.numVertices; i++) { iSkin[i] = new List <Tuple <byte, float> >(4); } List <remBoneWeights> boneList = submesh.BoneList; if (boneList != null) { if (iMesh.BoneList.Capacity < boneList.Count) { iMesh.BoneList.Capacity += boneList.Count; } foreach (remBoneWeights boneWeights in boneList) { byte idx; if (!boneDic.TryGetValue(boneWeights.bone, out idx)) { ImportedBone iBone = new ImportedBone(); iMesh.BoneList.Add(iBone); iBone.Name = boneWeights.bone; Vector3 scale, translate; Quaternion rotate; meshFrame.matrix.Decompose(out scale, out rotate, out translate); scale.X = Math.Abs(scale.X); scale.Y = Math.Abs(scale.Y); scale.Z = Math.Abs(scale.Z); iBone.Matrix = Matrix.Scaling(1f, 1f, -1f) * Matrix.Invert(meshFrame.matrix) * Matrix.Scaling(scale) * boneWeights.matrix; boneDic.Add(boneWeights.bone, idx = (byte)boneDic.Count); } for (int i = 0; i < boneWeights.numVertIdxWts; i++) { iSkin[boneWeights.vertexIndices[i]].Add(new Tuple <byte, float>(idx, boneWeights.vertexWeights[i])); } } } iSubmesh.VertexList = new List <ImportedVertex>(submesh.numVertices); for (int i = 0; i < submesh.numVertices; i++) { remVertex vert = submesh.VertexList[i]; ImportedVertex iVert = new ImportedVertex(); iSubmesh.VertexList.Add(iVert); iVert.Position = new Vector3(vert.Position.X, vert.Position.Z, -vert.Position.Y); iVert.Normal = new Vector3(vert.Normal.X, vert.Normal.Z, -vert.Normal.Y); iVert.UV = new float[] { vert.UV[0], vert.UV[1] }; iVert.BoneIndices = new byte[4]; iVert.Weights = new float[4]; for (int j = 0; j < 4; j++) { if (j < iSkin[i].Count) { Tuple <byte, float> vertIdxWeight = iSkin[i][j]; iVert.BoneIndices[j] = vertIdxWeight.Item1; iVert.Weights[j] = vertIdxWeight.Item2; } else { iVert.BoneIndices[j] = 0xFF; } } } iSubmesh.FaceList = rem.ImportedFaceList(submesh.FaceList); } } }
private void ConvertMeshes(List <odfMesh> meshes, odfParser parser) { MeshList = new List <ImportedMesh>(meshes.Count); MaterialList = new List <ImportedMaterial>(meshes.Count); TextureList = new List <ImportedTexture>(parser.TextureSection != null ? parser.TextureSection.Count : 0); foreach (odfMesh mesh in meshes) { ImportedMesh iMesh = new ImportedMesh(); MeshList.Add(iMesh); iMesh.Name = odf.FindMeshFrame(mesh.Id, parser.FrameSection.RootFrame).Name; iMesh.BoneList = new List <ImportedBone>(); Dictionary <ObjectID, byte> boneDic = new Dictionary <ObjectID, byte>(); iMesh.SubmeshList = new List <ImportedSubmesh>(mesh.Count); foreach (odfSubmesh submesh in mesh) { ImportedSubmesh iSubmesh = new ImportedSubmesh(); iMesh.SubmeshList.Add(iSubmesh); odfMaterial mat = odf.FindMaterialInfo(submesh.MaterialId, parser.MaterialSection); if (mat != null) { iSubmesh.Material = mat.Name; ImportedMaterial iMat = ImportedHelpers.FindMaterial(iSubmesh.Material, MaterialList); if (iMat == null) { iMat = new ImportedMaterial(); MaterialList.Add(iMat); iMat.Name = iSubmesh.Material; iMat.Diffuse = mat.Diffuse; iMat.Ambient = mat.Ambient; iMat.Specular = mat.Specular; iMat.Emissive = mat.Emissive; iMat.Power = mat.SpecularPower; iMat.Textures = new string[4]; for (int i = 0; i < 4; i++) { if (submesh.TextureIds[i] != ObjectID.INVALID) { odfTexture tex = odf.FindTextureInfo(submesh.TextureIds[i], parser.TextureSection); iMat.Textures[i] = tex.Name; if (ImportedHelpers.FindTexture(iMat.Textures[i], TextureList) == null) { try { odfTextureFile texFile = new odfTextureFile(iMat.Textures[i], Path.GetDirectoryName(parser.ODFPath) + @"\" + iMat.Textures[i]); MemoryStream memStream; int filesize = 0; using (BinaryReader reader = texFile.DecryptFile(ref filesize)) { memStream = new MemoryStream(reader.ReadBytes(filesize)); } ImportedTexture iTex = new ImportedTexture(memStream, iMat.Textures[i]); TextureList.Add(iTex); } catch { Report.ReportLog("cant read texture " + iMat.Textures[i]); } } } else { iMat.Textures[i] = String.Empty; } } } } List <Tuple <byte, float> >[] skin = new List <Tuple <byte, float> > [submesh.NumVertices]; for (int i = 0; i < submesh.NumVertices; i++) { skin[i] = new List <Tuple <byte, float> >(4); } odfBoneList boneList = odf.FindBoneList(submesh.Id, parser.EnvelopeSection); if (boneList != null) { if (iMesh.BoneList.Capacity < boneList.Count) { iMesh.BoneList.Capacity += boneList.Count; } foreach (odfBone bone in boneList) { byte idx; if (!boneDic.TryGetValue(bone.FrameId, out idx)) { ImportedBone iBone = new ImportedBone(); iMesh.BoneList.Add(iBone); iBone.Name = odf.FindFrame(bone.FrameId, parser.FrameSection.RootFrame).Name; iBone.Matrix = bone.Matrix; boneDic.Add(bone.FrameId, idx = (byte)boneDic.Count); } for (int i = 0; i < bone.NumberIndices; i++) { skin[bone.VertexIndexArray[i]].Add(new Tuple <byte, float>(idx, bone.WeightArray[i])); } } } iSubmesh.VertexList = new List <ImportedVertex>(submesh.NumVertices); for (int i = 0; i < submesh.NumVertices; i++) { odfVertex vert = submesh.VertexList[i]; ImportedVertex iVert = new ImportedVertex(); iSubmesh.VertexList.Add(iVert); iVert.Position = vert.Position; iVert.Normal = vert.Normal; iVert.UV = new float[] { vert.UV[0], vert.UV[1] }; iVert.BoneIndices = new byte[4]; iVert.Weights = new float[4]; for (int j = 0; j < 4; j++) { if (j < skin[i].Count) { Tuple <byte, float> vertIdxWeight = skin[i][j]; iVert.BoneIndices[j] = vertIdxWeight.Item1; iVert.Weights[j] = vertIdxWeight.Item2; } else { iVert.BoneIndices[j] = 0xFF; } } } iSubmesh.FaceList = new List <ImportedFace>(submesh.NumVertexIndices / 3); foreach (odfFace face in submesh.FaceList) { ImportedFace iFace = new ImportedFace(); iSubmesh.FaceList.Add(iFace); iFace.VertexIndices = new int[3]; for (int i = 0; i < 3; i++) { iFace.VertexIndices[i] = face.VertexIndices[i]; } } } } }