Page 2 of 3

Re: Mirror's Edge Catalyst Beta

Posted: Sat Oct 01, 2016 9:41 pm
by RunaWhite
@OriginOfWaves thank you! I was really hoping to get the models from this game but I didn't know if it was already possible or not.

Re: Mirror's Edge Catalyst Beta

Posted: Fri Oct 21, 2016 7:36 am
by Irastris
Did anyone ever figure out how to get models with rigging from MEC? I'm really desperate for Faith but I have no idea how to go about rigging the OBJ that was previously posted.

Re: Mirror's Edge Catalyst Beta

Posted: Mon Oct 24, 2016 4:39 pm
by RunaWhite
The game uses the Frostbite engine like Dragon Age Inquisition... so technically it is possible since with the DAI Tools we can get rigged models. However, the programmer is already working hard on the new tools for that game, thus I doubt she will try to also implement a MEC support. Maybe someone else can figure out another way at some point, who knows.

Re: Mirror's Edge Catalyst Beta

Posted: Wed Nov 09, 2016 5:21 pm
by kkdf2
I'm working on a mesh converter: mesh→blenderPy script.

faith has 10 parts and we need to combine them into one body...

Re: Mirror's Edge Catalyst Beta

Posted: Fri Nov 11, 2016 3:15 pm
by kkdf2
I have a sample tool, in development status, in order to extract mesh data: writing down .py or .h2o formats. http://kkdf2.sakura.ne.jp/MEC/DecMECMesh-0.1.7z pass MEC

- Launch "Run-gui.bat"
- Require .NET Framework 4.0 or later

Use ILSpy to obtain source code. enjoy!

Re: Mirror's Edge Catalyst Beta

Posted: Tue Nov 15, 2016 12:42 pm
by kkdf2
MEC's skeleton data is partially decoded. Export will be available in near future...
e.g. bundles\ebx\characters\skeletons\skeleton_faith.ebx

The decoding code sample:

Code: Select all

        private void Skeleton(string fpebx) {
            MemoryStream siSkel = new MemoryStream(File.ReadAllBytes(fpebx));
            BinaryReader brSkel = new BinaryReader(siSkel);

            SkelFileHeader fileHeader = new SkelFileHeader {
                Data64 = brSkel.ReadBytes(64),
            };
            siSkel.Position = fileHeader.OffsetStrBlock1 + fileHeader.LengthStrBlock1;

            brSkel.ReadBytes(16 * fileHeader.EntryCount1);
            brSkel.ReadBytes(16 * fileHeader.EntryCount2);

            SkelHeader header = new SkelHeader {
                Data160 = brSkel.ReadBytes(160),
            };

            var strBlk2 = Encoding.ASCII.GetString(brSkel.ReadBytes(fileHeader.LengthStrBlock2));
            brSkel.ReadBytes(16); //GUID?
            brSkel.ReadBytes(0x30); //?

            List<Bone> bones = new List<Bone>();
            {
                int countBones = brSkel.ReadInt32();
                Debug.Assert(countBones == header.CountBones);
                for (int x = 0; x < countBones; x++) {
                    int relativeOffsetName = brSkel.ReadInt32();
                    bones.Add(new Bone {
                        index = x,
                        name = strBlk2.Substring(relativeOffsetName).Split('\0')[0],
                    });
                }
            }
            {
                int countBones = brSkel.ReadInt32();
                Debug.Assert(countBones == header.CountBones);
                for (int x = 0; x < countBones; x++) {
                    brSkel.ReadInt32();//?
                }
            }
            {
                int countBones = brSkel.ReadInt32();
                Debug.Assert(countBones == header.CountBones);
                for (int x = 0; x < countBones; x++) {
                    bones[x].parentIndex = brSkel.ReadInt32();
                }
            }
            {
                siSkel.Position += 12 - (int)(siSkel.Position & 15);
                int countBones = brSkel.ReadInt32();
                Debug.Assert(countBones == header.CountBones);
                for (int x = 0; x < countBones; x++) {
                    bones[x].matrix1 = new float[9];

                    bones[x].matrix1[0] = brSkel.ReadSingle();
                    bones[x].matrix1[1] = brSkel.ReadSingle();
                    bones[x].matrix1[2] = brSkel.ReadSingle();
                    brSkel.ReadSingle();

                    bones[x].matrix1[3] = brSkel.ReadSingle();
                    bones[x].matrix1[4] = brSkel.ReadSingle();
                    bones[x].matrix1[5] = brSkel.ReadSingle();
                    brSkel.ReadSingle();

                    bones[x].matrix1[6] = brSkel.ReadSingle();
                    bones[x].matrix1[7] = brSkel.ReadSingle();
                    bones[x].matrix1[8] = brSkel.ReadSingle();
                    brSkel.ReadSingle();

                    bones[x].vector1 = new float[3];
                    bones[x].vector1[0] = brSkel.ReadSingle();
                    bones[x].vector1[1] = brSkel.ReadSingle();
                    bones[x].vector1[2] = brSkel.ReadSingle();
                    brSkel.ReadSingle();
                }
            }
            {
                siSkel.Position += 12 - (int)(siSkel.Position & 15);
                int countBones = brSkel.ReadInt32();
                Debug.Assert(countBones == header.CountBones);
                for (int x = 0; x < countBones; x++) {
                    bones[x].matrix2 = new float[9];

                    bones[x].matrix2[0] = brSkel.ReadSingle();
                    bones[x].matrix2[1] = brSkel.ReadSingle();
                    bones[x].matrix2[2] = brSkel.ReadSingle();
                    brSkel.ReadSingle();

                    bones[x].matrix2[3] = brSkel.ReadSingle();
                    bones[x].matrix2[4] = brSkel.ReadSingle();
                    bones[x].matrix2[5] = brSkel.ReadSingle();
                    brSkel.ReadSingle();

                    bones[x].matrix2[6] = brSkel.ReadSingle();
                    bones[x].matrix2[7] = brSkel.ReadSingle();
                    bones[x].matrix2[8] = brSkel.ReadSingle();
                    brSkel.ReadSingle();

                    bones[x].vector2 = new float[3];
                    bones[x].vector2[0] = brSkel.ReadSingle();
                    bones[x].vector2[1] = brSkel.ReadSingle();
                    bones[x].vector2[2] = brSkel.ReadSingle();
                    brSkel.ReadSingle();
                }
            }

            siSkel.Position = fileHeader.OffsetStrBlock2;
            String fullName = Util.ReadStr(brSkel);

            String fpJson = Path.ChangeExtension(fpebx, ".json");
            using (StreamWriter writer = new StreamWriter(fpJson, false, Encoding.ASCII)) {
                JsonSerializer.CreateDefault(new JsonSerializerSettings { Formatting = Formatting.Indented }).Serialize(writer, new SkelJson {
                    fullName = fullName,
                    name = Path.GetFileNameWithoutExtension(fullName),
                    bones = bones.ToArray(),
                });
            }

            String fpTxt = Path.ChangeExtension(fpebx, ".skel.txt");
            using (StreamWriter writer = new StreamWriter(fpTxt, false, Encoding.ASCII)) {
                for (int y = 0; y < bones.Count; y++) {
                    writer.WriteLine("0x{0:X2},{0,4},{1,4}, {2}", y, bones[y].parentIndex, bones[y].name);
                }
            }
        }

    public class SkelFileHeader {
        public byte[] Data64;

        public int OffsetStrBlock2 { get { return BitConverter.ToInt32(Data64, 0x04); } }

        public int EntryCount2 { get { return BitConverter.ToUInt16(Data64, 0x16); } }

        public int EntryCount1 { get { return BitConverter.ToUInt16(Data64, 0x18); } }

        public int LengthStrBlock1 { get { return BitConverter.ToUInt16(Data64, 0x1A); } }

        public int LengthStrBlock2 { get { return BitConverter.ToInt32(Data64, 0x1C); } }

        public int OffsetStrBlock1 { get { return BitConverter.ToInt32(Data64, 0x24); } }
    }

    public class SkelHeader {
        public byte[] Data160;

        public int CountBones { get { return BitConverter.ToInt32(Data160, 0x20); } }
    }

Re: Mirror's Edge Catalyst Beta

Posted: Wed Nov 16, 2016 11:37 pm
by HeliosAI
This is amazing news :) Thanks for your hard work!

Re: Mirror's Edge Catalyst Beta

Posted: Thu Nov 17, 2016 5:29 am
by MisterPrawn
I would just like to say that the DecMECMesh tool seems really good! However, when I try to use it on a Plants vs Zombies Garden Warfare 2 .mesh file, it gives me this error:

Code: Select all

  Failure: System.IO.EndOfStreamException: Unable to read beyond the end of the stream.
   at System.IO.BinaryReader.FillBuffer(Int32 numBytes)
   at System.IO.BinaryReader.ReadInt32()
   at DecMECMesh.Program.Conv(String fpMesh, String dirConvTo, String dirChunks, Boolean ExportPy, Boolean ExportH2O, Boolean ExportOnlyFirstLOD)
   at DecMECMesh.ConvMeshForm.bwConv_DoWork(Object sender, DoWorkEventArgs e)
It'd be really nice if it could work with PvZGW2, just saying.

Re: Mirror's Edge Catalyst Beta

Posted: Fri Dec 02, 2016 4:19 pm
by daemon1
kkdf2 wrote:MEC's skeleton data is partially decoded. Export will be available in near future...
So how is it going. In my experience, binding model to skeleton may be the hardest part because of so many ways devs are doing this. Bone remaps, submeshes, groups, all of that stuff.

Re: Mirror's Edge Catalyst Beta

Posted: Sat Dec 03, 2016 2:59 pm
by kkdf2
It'd be really nice if it could work with PvZGW2, just saying.
sorry, currently I don't have much time to work on other game...
daemon1 wrote:
kkdf2 wrote:MEC's skeleton data is partially decoded. Export will be available in near future...
So how is it going. In my experience, binding model to skeleton may be the hardest part because of so many ways devs are doing this. Bone remaps, submeshes, groups, all of that stuff.
Skeleton exporter is ready on 0.2, pass MEC:
http://kkdf2.sakura.ne.jp/MEC/DecMECMesh-0.2.7z

But it is not fully automated yet. It needs some procedures even if we convert faith's mesh and bones:

- Convert dds textures to png

- Turn on [Export .json].

- Convert all .mesh files in MEC\bundles\res\characters\faith. Drag faith's folder and drop it into [Drop file(s) or folder(s) ...] button.

- Convert MEC\bundles\ebx\characters\skeletons\skeleton_faith.ebx
You will get required file skeleton_faith.json

- Edit attached Faith.py
Modify the path:

Code: Select all

bundlesDirectory = r"H:\MEC\bundles";
- Tweak importTables in Faith.py
Each jsonMeshFile is valid, but diffuseMap may be incorrect for most sub meshes. Please trial and error for better result!

Code: Select all

importTables = [
    {
        "jsonMeshFile": r"res\characters\faith\armgear\magrope\magrope_skin_mesh\magrope_skin-lod1.json",
        "diffuseMap":   r"res\characters\faith\armgear\magrope\t_magrope_d ec6cb90b09fef721 0b000000010000000000000000000000.PNG"
    },
    {
        "jsonMeshFile": r"res\characters\faith\arms\faith_arms_mesh\faith_arms-lod1.json"
    },
    {
        "jsonMeshFile": r"res\characters\faith\gridlink\faith_gridlink_mesh\faith_gridlink-lod1.json"
    },
    {
        "jsonMeshFile": r"res\characters\faith\hair\faith_hair_3pcloth_ingame_mesh ba25d653909762f1 3005000070a404006800000090003001-lod1.json",
        "diffuseMap":   r"res\characters\faith\hair\t_alphahair_a 98be69afce0ddd0b 0b000000010000000000000000000000.PNG"
    },
    {
        "jsonMeshFile": r"res\characters\faith\head\faith_head_mesh 9bd03e0f689c56d9 002c190020050800f800000090003001-lod1.json",
        "diffuseMap":   r"res\characters\faith\head\t_faithhead_dao b99b387e03207ab7 0b000000010000000000000000000000.PNG"
    },
    {
        "jsonMeshFile": r"res\characters\faith\headparts\faith_headparts_mesh\faith_headparts-lod1.json"
    },
    {
        "jsonMeshFile": r"res\characters\faith\lowerbody\faith_lowerbody_mesh\faith_lowerbody-lod1.json",
        "diffuseMap":   r"res\characters\faith\lowerbody\t_lowerbody_dao fc8450880b45f12b 0b000000010000000000000000000000.PNG"
    },
    {
        "jsonMeshFile": r"res\characters\faith\toolbag\faith_toolbag_mesh\faith_toolbag-lod1.json",
        "diffuseMap":   r"res\characters\faith\toolbag\faith_pickupbag_dao 6206caa6286b3edb 0b000000010000000000000000000000.PNG"
    },
    {
        "jsonMeshFile": r"res\characters\faith\upperbody\faith_upperbody_mesh\faith_upperbody-lod1.json",
        "diffuseMap":   r"res\characters\faith\upperbody\t_arms_dao a97c9a442565aba7 0b000000010000000000000000000000.PNG"
    }
]
- Launch Faith.py like other exported py scripts.

Code: Select all

#!BPY
# Runs great on Blender 2.77a
# How to:
# - Launch Blender 2.77a
# - Press Shift+[F11] to open Text Editor
# - Press Alt+O to open this script
# - Press Alt+P to run this script
# - Press Shift+[F5] to get back initial perspective view

Re: Mirror's Edge Catalyst Beta

Posted: Sat Jan 07, 2017 7:10 pm
by desperado
Hello, great job. Is anyone know where is texts of the game and how can i replace them?

Re: Mirror's Edge Catalyst Beta

Posted: Sat Jan 14, 2017 11:44 pm
by slayer983
only lark. why are these doing if not to be used in game? where repack it, replace it, import it. Files open and extract but there is no rest.

It will be more useful a thousand times than these if made a translation tool. these are only make an appearance.

Everyone can not do what you do, it also takes skill, I respect them. but it not works for me. it not works for who ones will make a difference.

Re: Mirror's Edge Catalyst Beta

Posted: Wed Jan 18, 2017 11:36 am
by keku645
Do you guys find out a way to extract the animations?

If someone asks who i am, I'm a Mirror's Edge modder (1st game) that we are still waiting to someone manages a way to mod MEC, until that at least me, i'm still in the first game, and i tried to export stuff from MEC into the original game, but ninja ripper worked really bad, didnt even extracted UV channels well so i gave up until i noticed this topic. Thank you so much for the tool.

At the moment my project was to "recreate" MEC into the first game, at least the city.

Re: Mirror's Edge Catalyst Beta

Posted: Mon Apr 17, 2017 10:32 pm
by keku645
Is this topic still up?

I can't figure out a way to get models, i dont care about bones but i'd like to get the rest, i already have everything except models.

Re: Mirror's Edge Catalyst Beta

Posted: Sat Sep 01, 2018 8:16 pm
by ximik163
little question. all textures have a diffuse (_d) channel and normal map (_n). but what is _rsm?