Jump to content

Recommended Posts

Posted

Helldivers 1 (much like the second game) is on the Bitsquid/Stingray engine, and (I believe) uses similar formats, however, another game, Vermintide 2, uses an older, and more similar version of the engine compared to the first Helldivers. The model format has a Blender plug-in made for it, but the Helldivers model format is too old, and is not supported by the tool. If it would be possible for anyone to edit the plug-in (https://gitlab.com/qasikfwn/bitsquid-blender-tools), or just make a new one based off the code, I would be very grateful. I have attached a few sample models, I am unsure what materials and textures go with them, as all files are hashes. I do not care to modify the models/reimport them, I just wish to be able to have them without using Ninja Ripper or some other method. Skeletons would be nice, and I have included a file that seems to semi-correspond to it, but I will not complain if only meshes are supported. The files attached are extracted from the game's archives, I have not provided said archives as they are too big, but if someone thinks it'd be more useful to have them, I can send them.

HD1MeshSample.rar

Posted

Here's some more, I included some that didn't have bone files as well, figured they might be static meshes or something, but I can find even more if needed, it's just with the naming structure it's a bit of a pain. Some of them did have matching material names, I don't know if that's much help. Thank you so much either way.

MoreSamples.rar

  • Engineers
Posted (edited)

Hope you are familiar with 010 Hex Editor. Unfortunately I can't get it work in Noesis. I have problem with Indices.

//------------------------------------------------
//--- 010 Editor v14.0 Binary Template
//
//      File: 
//   Authors: 
//   Version: 
//   Purpose: 
//  Category: 
// File Type: *.unit
//  ID Bytes: 
//   History: 
//------------------------------------------------
LittleEndian();OutputPaneClear();
local string FileName=GetFileName(),FilePath=FileNameGetPath(FileName,true),BaseName=FileNameGetBase(FileName,false),MeshNum;
local uint32 i,j,k,l;

uint32 Sign;
uint32 MeshCount;

for (i=0; i < MeshCount; i++)
{
    struct
    {
        uint32 ElementBufferSize;
        byte ElementBuffer[ElementBufferSize];
        uint32 Null[2];
        uint32 VertexCount;
        uint32 Stride;
        uint32 ElementCount;
        struct
        {
            uint32 ElementId;
            uint32 ElementSize;
            uint32 Unknown_0;
            uint32 Unknown_1;
            byte EndMarker;
        }ElementInfo[ElementCount]<optimize=false>;
        
        byte Dummy[12];
        uint32 TotalIndexCount;
        uint32 IndexBufferSize;
        local uint32 TotalIndexBufferOffset=FTell();
        FSkip(IndexBufferSize);
        //uint16 IndexBuffer[TotalIndexCount];
        uint32 ShapeCount;
        struct
        {
            uint32 MaterialIndex;
            uint32 IndexOffset;
            uint32 IndexCount;
            uint32 ShapeIndex;
        }ShapeInfo[ShapeCount]<optimize=false>;
        
        float Unknown_4[7];
        uint32 MaterialCount;
        struct
        {
            uint32 StrLen;
            char MaterialName[StrLen];
        }MaterialInfo[MaterialCount]<optimize=false>;
    }MeshInfo;
}

for (i=0; i < MeshCount; i++)
{
    FSeek(startof(MeshInfo[i].ElementBuffer));
    SPrintf(MeshNum,"_mesh_%u",i);
    struct
    {
        struct
        {
            for (j=0; j < MeshInfo[i].ElementCount; j++)
            {
                if (MeshInfo[i].ElementInfo[j].ElementId == 0)
                {
                    struct
                    {
                        float VPosX,VPosY,VPosZ;
                    }Vertices;
                }
                else if (MeshInfo[i].ElementInfo[j].ElementId == 1)
                {
                    struct
                    {
                        float VNPosX,VNPosY,VNPosZ;
                    }Normals;
                }
                else if (MeshInfo[i].ElementInfo[j].ElementId == 2)
                {
                    struct
                    {
                        float PosX,PosY,PosZ;
                    }Unknown_2;
                }
                else if (MeshInfo[i].ElementInfo[j].ElementId == 3)
                {
                    struct
                    {
                        float PosX,PosY,PosZ;
                    }Unknown_3;
                }
                else if (MeshInfo[i].ElementInfo[j].ElementId == 4)
                {
                    struct
                    {
                        float UVPosX,UVPosY;
                    }UnitVector;
                }
                else if (MeshInfo[i].ElementInfo[j].ElementId == 5)
                {
                    struct
                    {
                        float PosX,PosY,PosZ,PosW;
                    }Unknown_5;
                }
                else if (MeshInfo[i].ElementInfo[j].ElementId == 6)
                {
                    struct
                    {
                        if (MeshInfo[i].ElementInfo[j].ElementSize == 0)
                            float PosX;
                        else if (MeshInfo[i].ElementInfo[j].ElementSize == 1)
                            float PosX,PosY;
                        else if (MeshInfo[i].ElementInfo[j].ElementSize == 2)
                            float PosX,PosY,PosZ;
                        else if (MeshInfo[i].ElementInfo[j].ElementSize == 3)
                            float PosX,PosY,PosZ,PosW;
                    }Unknown_6;
                }
                else if (MeshInfo[i].ElementInfo[j].ElementId == 7)
                {
                    struct
                    {
                        if (MeshInfo[i].ElementInfo[j].ElementSize == 0)
                            float PosX;
                        else if (MeshInfo[i].ElementInfo[j].ElementSize == 1)
                            float PosX,PosY;
                        else if (MeshInfo[i].ElementInfo[j].ElementSize == 2)
                            float PosX,PosY,PosZ;
                        else if (MeshInfo[i].ElementInfo[j].ElementSize == 3)
                            float PosX,PosY,PosZ,PosW;
                    }Unknown_7;
                }
            }
            Printf("v %f %f %f\n",Vertices[0].VPosX,Vertices[0].VPosY,Vertices[0].VPosZ);
            Printf("vt %f %f\n",UnitVector[0].UVPosX,UnitVector[0].UVPosY);
            Printf("vn %f %f %f\n",Normals[0].VNPosX,Normals[0].VNPosY,Normals[0].VNPosZ);
        }ElementBuffer[MeshInfo[i].VertexCount]<optimize=false>;
        Printf("\n");
        
        for (k=0; k < MeshInfo[i].ShapeCount; k++)
        {
            Printf("g mesh_%04u_shape_%04u_%s\n",i,k,MeshInfo[i].MaterialInfo[MeshInfo[i].ShapeInfo[k].MaterialIndex].MaterialName);
            FSeek(MeshInfo[i].TotalIndexBufferOffset + MeshInfo[i].ShapeInfo[k].IndexOffset * 6);
            struct
            {
                uint16 F1,F2,F3;
                Printf("f %u/%u/%u %u/%u/%u %u/%u/%u\n",F1+1,F1+1,F1+1,F2+1,F2+1,F2+1,F3+1,F3+1,F3+1);
            }ShapeIndex0[MeshInfo[i].ShapeInfo[k].IndexCount]<optimize=false>;
            Printf("\n");
        }
    }MeshObject;
    OutputPaneSave(FilePath + BaseName + MeshNum + ".obj");
    OutputPaneClear();
}

 

Edited by h3x3r
Posted (edited)

So trying the 010 editor script, and I might be doing something wrong, as it has been a very long time since I've used it, but it keeps telling me "ERROR line 151: Variable 'Mesh' is undefined." As for hex2obj stuff, I've tried it before, I made a bit of progress on some models for another game, but I haven't had much luck with these ones, I've had a very hard time trying to learn it, my brain can't seem to rack around it, and I feel stupid for not being able to understand it. 

EDIT: I just had to change one of the lines slightly, and it started working, I can use the 010 script.

Edited by DreamingOxxy
  • Engineers
Posted

Yeah sorry. It was on line 151.

Printf("g mesh_%04u_%s\n",i,Mesh[i].ShapeNameInfo[k].ShapeName);

I forgot to change it form Mesh. > MeshInfo.

Posted

Oh, one thing I saw, there's a few (and I mean very few, there's only 2 I've found so far) .unit files that are way bigger than the rest, I didn't notice them until now, and they spew errors about being so large, no idea what's in them to make them so massive compared to the rest, here's one if you wanna look at it.

4E5BDACF55825507.rar

Posted

Well, I managed to find the archive that contained all the armors, and one for all the bugs, still trying to find the Illuminate and Cyborgs. Since there's still some things that could use addressed (possible vertex groups/skeletons, and some of the bigger files not being extract-able via script yet, also the materials are being applied to the vertex groups while using the current script) I'll leave the topic unsolved, but it is working! Thank you both for your help so far, and for anything else that may be done, it means a lot to me. I'm really surprised they actually had material names at all though, that doesn't exist at all in HD2. If no one wants to figure out anything more though I'll probably mark the script as the solution. I'll also definitely be taking notes about hex2obj, I've been trying to learn how to do this kind of thing for a while but this format confused me, recently I did figure out some of the Star Wars Bounty Hunter PC models though, so that's something.image.thumb.png.b159faf1f7fd84fbcb8d971ef75ecf04.png

  • Engineers
Posted (edited)

Updated template. There was a problem with names. Now it should work.

EDiT: Updated one more time. I found out that MeshIndex was actually MaterialIndex.

Edited by h3x3r
Posted
16 minutes ago, DreamingOxxy said:

With the newer version, the bigger model now works, awesome, but the Materials are still being saved to the Vertex groups, though I could've messed up in updating it? I'm not sure.image.png.f51df3e32efd96ed0f5ab6ae8f303417.png

The mesh format isn't too bad.  It might be handy to have a few samples of the material textures for a mesh to test them out.

 

Posted (edited)
3 minutes ago, DreamingOxxy said:

I couldn't add any extra text for some reason, but this is the player armor archive, it has all the materials and textures (.texture files are just renamed DDS files)
I extracted the archive with a tool made for the game (and other games on the engine) years ago, but if it's anything like HD2, there might be shared files between all the archives, the tool for HD2 opens all at once to scroll through the files within rather than extracting.

Edited by DreamingOxxy
Posted

Yeah, the files are probably split up over many different archives.  I can see in that archive that there aren't any .unit files for some .texture files, or no .texture files for some .unit files.  It seems like there's only 1 texture file per mesh file as well, or there's a lot in other archives.

 

Posted (edited)

If it's helpful, I can just send one of the archives untouched, or multiple. Most of the textures if not all are definitely in the archive though, I was going though texturing the models to find out, and so far haven't found any missing ones. There was a tool made for the VT2 archives that does work with HD1, but I wasn't sure if it was perfect since it's for a newer game, so I didn't use the files from it.

There's stuff like emissive masks, normal maps, base colors, and specular tints/masks, here's an example of one shaded.image.thumb.png.ce7bc25c63a2d7833e16be3f010207bc.png

Edited by DreamingOxxy
Posted

Alright, last comment I'll make in a row since I don't wanna clog up stuff with my rambling, this is NOT REQUIRED at all, I am okay with finding the materials and textures that go with a model myself, and using this extractor for the archives is doable, but incase someone is interested enough to make an archive explorer to open multiple at once blah blah, here's a good few to look around at, I don't want to upload the entire game's archives (at least not right now, it would take too long and I'm not sure I'm even allowed to do that), but this is some random ones that seemed like a good sample without eating a ton of storage. https://drive.google.com/file/d/1ezq3mP480Pby13GwcSA9eyp1yjXkWG1J/view?usp=sharing

Posted

Ooooohhh nice! One thing I did notice with the script is the UVs were upside down, that might cause some issues in figuring out if the right texture is applied if you're using that guy's code as a reference. This is so cool though, I never expected the materials to be figured out at all with how random the files seem to be.

Posted
2 minutes ago, DreamingOxxy said:

Ooooohhh nice! One thing I did notice with the script is the UVs were upside down, that might cause some issues in figuring out if the right texture is applied if you're using that guy's code as a reference. This is so cool though, I never expected the materials to be figured out at all with how random the files seem to be.

 

I didn't look at that other code, so I'm just starting from a blank slate almost.

All of the textures used for a particular model have their hash ID values in the .material file, and the structure of that is fairly simple to read, although there's still stuff in there that's unknown - probably lighting values, etc..  It's also tricky trying to match the correct texture types - diffuse, normal, others - to the right texture files, and then working out how the materials are assigned to each submesh of the model.

I notice that some models are made up of multiple parts and even multiple files, and some have different versions of the model in the same file, such as "damaged" models, etc.

 

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...