Important information: this site is currently scheduled to go offline indefinitely by end of the year.
Rohan Online: GMF Models
-
- ultra-veteran
- Posts: 586
- Joined: Sun Jun 05, 2005 12:00 pm
- Location: Ontario, Canada
- Has thanked: 36 times
- Been thanked: 243 times
Re: Rohan Online: GMF Models
These file formats are no longer accurate. I've got meshes parsed out, and have even pared the material files with them, to get models converted into a custom 3D format I use for my 3D engine. To start with, Here's the source code for a program that will extract files from the gel/gem archives :
Check the comments by the srcGel, srcGem and destPath std::string's. They are pretty self-explanatory, but I added the comments just in case. Soon, I'll post the updated .GMF and .GRF format and source code for converting the .GMF files into .OBJ meshes.
Some teasers tho -
Code: Select all
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tchar.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
struct GELHeader
{
int i1;
int i2;
int numberOfElements;
int i4;
int i5;
int i6;
void print()
{
//printf( "i1 = %d\n", i1 );
//printf( "i2 = %d\n", i2 );
printf( "numberOfElements = %d\n", numberOfElements );
//printf( "i4 = %d\n", i4 );
//printf( "i5 = %d\n", i5 );
//printf( "i6 = %d\n", i6 );
printf( "\n" );
}
};
struct GELEntry
{
int i1;
int i2;
char filename[128];
int i3;
int startOffset;
int dataSize;
int i6;
void print()
{
//printf( "i1 = %d\n", i1 );
//printf( "i2 = %d\n", i2 );
printf( "filename = %s\n", filename );
//printf( "i3 = %d\n", i3 );
printf( "startOffset = %d\n", startOffset );
printf( "dataSize = %d\n", dataSize );
//printf( "i6 = %d\n", i6 );
printf( "\n" );
}
};
// Set this to the .GEL file that you want to extract
std::string srcGel = "C:\\Rohan\\res\\model\\Building\\skeleton.gel";
// Set this to the .GEM file that matches the .GEL file you want to extract
std::string srcGem = "C:\\Rohan\\res\\model\\Building\\skeleton.gem";
// This is the path where all the files will be extracted to
std::string destPath = "C:\\RohanData\\model\\Building";
int main()
{
FILE* gelFP = 0;
fopen_s( &gelFP, srcGel.c_str(), "rb" );
if( gelFP )
{
FILE* gemFP = 0;
fopen_s( &gemFP, srcGem.c_str(), "rb" );
if( gemFP )
{
GELHeader gelHeader;
fread( &gelHeader, sizeof( GELHeader ), 1, gelFP );
//gelHeader.print();
for( int i=0; i<gelHeader.numberOfElements; i++ )
{
GELEntry gelEntry;
fread( &gelEntry, sizeof( GELEntry ), 1, gelFP );
//gelEntry.print();
printf( "\b\b\b\b\b\b\b%d", i + 1 );
if( gelEntry.dataSize > 0 )
{
// Create the file
std::string sFilename = gelEntry.filename;
size_t pos = sFilename.find_last_of( "\\" );
std::string path = sFilename.substr( 0, pos + 1 );
std::string filename = sFilename.substr( pos + 1, sFilename.length() - pos );
//printf( "Path = %s\nFile = %s\n", path.c_str(), filename.c_str() );
std::string newPath = destPath;
newPath.append( path );
CreateDirectory( newPath.c_str(), NULL );
// Detect GTX files (DDS files with the header changed and the extension changed
pos = filename.find_last_of( "." );
//printf( "pos = %d\n", pos );
std::string ext = filename.substr( pos + 1, filename.length() - pos - 1 );
//printf( "ext = %s\n", ext.c_str() );
if( ext.find( "gtx" ) != std::string::npos )
{
//printf( "Found GTX file!\n" );
char* data = (char*)malloc( gelEntry.dataSize );
fseek( gemFP, gelEntry.startOffset, 0 );
fread( data, gelEntry.dataSize, 1, gemFP );
if( data[0] == 'G' && data[1] == 'E' && data[2] == 'O' )
{
// Most gtx files are DDS files with the "Magic Word" changed to GEO. We change that here, before
// writing the file
filename.replace( pos + 1, 3, "dds" );
std::string fullPath = newPath;
fullPath.append( "\\" );
fullPath.append( filename );
data[0] = 'D';
data[1] = 'D';
data[2] = 'S';
FILE* outFP = 0;
fopen_s( &outFP, fullPath.c_str(), "wb" );
if( outFP )
{
fwrite( data, gelEntry.dataSize, 1, outFP );
fclose( outFP );
}
}
else if( data[0] == 'D' && data[1] == 'D' && data[2] == 'S' )
{
// Sometimes, DDS files have the proper header in them
filename.replace( pos + 1, 3, "dds" );
std::string fullPath = newPath;
fullPath.append( "\\" );
fullPath.append( filename );
FILE* outFP = 0;
fopen_s( &outFP, fullPath.c_str(), "wb" );
if( outFP )
{
fwrite( data, gelEntry.dataSize, 1, outFP );
fclose( outFP );
}
}
else
{
// Haven't come across this yet, but just in case, we'll know.
printf( "\n" );
printf( "Encountered UNKNOWN GTX file!\n" );
printf( "%c %c %c\n", data[0], data[1], data[2] );
printf( "\n" );
}
free( data );
}
else
{
std::string fullPath = newPath;
fullPath.append( "\\" );
fullPath.append( filename );
FILE* outFP = 0;
fopen_s( &outFP, fullPath.c_str(), "wb" );
if( outFP )
{
void* data = malloc( gelEntry.dataSize );
fseek( gemFP, gelEntry.startOffset, 0 );
fread( data, gelEntry.dataSize, 1, gemFP );
fwrite( data, gelEntry.dataSize, 1, outFP );
free( data );
fclose( outFP );
}
}
}
}
printf( "\n\n" );
fclose( gemFP );
}
fclose( gelFP );
}
return 0;
}
Some teasers tho -
Re: Rohan Online: GMF Models
I've been looking into the non DDS gtx files. They seem to be Truevision TGA files (uncompressed in ARGB format) but with a slightly different header.
I think I've exported it properly, but if you zoom in, the edges don't seem to align correctly. I've attached my exported file, but if anyone has any ideas on these type of images, please let me know.
I think I've exported it properly, but if you zoom in, the edges don't seem to align correctly. I've attached my exported file, but if anyone has any ideas on these type of images, please let me know.
You do not have the required permissions to view the files attached to this post.
Re: Rohan Online: GMF Models
Thank you to fatduck for figuring out and releasing numerous file formats for rohan. Thanks also to Spintz for the extraction code. One problem when extracting all the meshes and textures is that it hard to tell what pieces go together. IEF files contain this information, so I would like to share its format with you:
Just as an example, using .ief files, I was able to do this:
(This tool will also extract and convert full sets from .gmf to .x. I plan on releasing it once it is 100% perfect).
Code: Select all
/* ROHAN ONLINE .IEF FORMAT
* BY PRINCEWADII
* 01/27/08 4:50 AM
* Description: .ief files group all meshes that
* belong together and store their .gmf file names
* and material names.
*/
//=============
// HEADER
//=============
dword header //always 0x00 00 00 00
dword typeCount
//============
// DATA
//============
struct Type[typeCount] //normal armor, event armor, head deco, etc..
{
dword typeID
dword setCount
struct Set[setCount] //combination of parts that form a full armor for example
{
dword setID
struct Part[4]
/*Parts always come in sets of 4 (ex: upper body,
lower body, glove, boot)*/
{
dword partLen
char[partLen] bodyPart //Example: Upper Body
dword meshCount //Number of meshes per part
struct Mesh [meshCount]
{
dword meshLen
char[meshLen] meshName //example: c_am_body01.gmf
dword matCount //Number of materials per mesh
struct Materials [matCount]
{
dword matLen
char[matLen] material //Example: Material #01001
}
}
}
}
}
(This tool will also extract and convert full sets from .gmf to .x. I plan on releasing it once it is 100% perfect).
-
- ultra-veteran
- Posts: 423
- Joined: Mon Aug 11, 2008 11:30 pm
- Has thanked: 27 times
- Been thanked: 15 times
Re: Rohan Online: GMF Models
That's a crazy cool tool! I will eagerly wait for a tool. I love the rohan models
-
- VVIP member
- Posts: 688
- Joined: Fri Jul 04, 2003 6:11 pm
- Has thanked: 33 times
- Been thanked: 16 times
Re: Rohan Online: GMF Models
Pretty cool, though the *.x mesh format has little documentation or at least a low support rating for modeling programs. Though ironically, free modeling programs like Blender do.
Still, I love to see converting and viewing of 3D models, and 3D in general, can't wait to see the results. It's good that a converter is being made, and from what I've seen, it was worth the wait. Not exactly familiar with Rohan, but the models look interesting.
Oh yeah, does the converter put out the animations intact as well?
Still, I love to see converting and viewing of 3D models, and 3D in general, can't wait to see the results. It's good that a converter is being made, and from what I've seen, it was worth the wait. Not exactly familiar with Rohan, but the models look interesting.
Oh yeah, does the converter put out the animations intact as well?
-
- ultra-veteran
- Posts: 423
- Joined: Mon Aug 11, 2008 11:30 pm
- Has thanked: 27 times
- Been thanked: 15 times
-
- VVIP member
- Posts: 688
- Joined: Fri Jul 04, 2003 6:11 pm
- Has thanked: 33 times
- Been thanked: 16 times
Re: Rohan Online: GMF Models
Hm... fbx IS a good format and seems widely supported. Though isn't it difficult to make a converter for? Not sure, but I do like the format for those perks, and even Milkshape seems to support it WITH animations (most imports in MS3D come WITHOUT animations).
-
- ultra-veteran
- Posts: 423
- Joined: Mon Aug 11, 2008 11:30 pm
- Has thanked: 27 times
- Been thanked: 15 times
Re: Rohan Online: GMF Models
.ms3d is also quite a good format. i think looking at blender scripts can give alot of hints...but dont ask me cause i dont know anything about those things
-
- ultra-veteran
- Posts: 423
- Joined: Mon Aug 11, 2008 11:30 pm
- Has thanked: 27 times
- Been thanked: 15 times
-
- ultra-n00b
- Posts: 6
- Joined: Thu May 21, 2009 7:51 pm
Re: Rohan Online: GMF Models
EDITED: How did you delete the first 3 hexes in the file?
This is what I did,
file.gtx -> containing geo header -> replace with dds characters.
in hex editor, there contain readable character which is TRUEVISION-XFile which is a tga file located at the bottom.
These are the first 16
44 44 53 00 00 02 00 00 00 00 00 00 00 00 00 20
Target
00 00 02 00 00 00 00 00 00 00 00 00 20
I need to delete index 0 1 2 in the c++ code, how to do this?
I'm thinking if I rewrite the output to skip data[2] and start with data[3] onwards
EDITED: Used another programming language for solution
This is what I did,
file.gtx -> containing geo header -> replace with dds characters.
in hex editor, there contain readable character which is TRUEVISION-XFile which is a tga file located at the bottom.
These are the first 16
44 44 53 00 00 02 00 00 00 00 00 00 00 00 00 20
Target
00 00 02 00 00 00 00 00 00 00 00 00 20
I need to delete index 0 1 2 in the c++ code, how to do this?
I'm thinking if I rewrite the output to skip data[2] and start with data[3] onwards
EDITED: Used another programming language for solution
-
- ultra-veteran
- Posts: 423
- Joined: Mon Aug 11, 2008 11:30 pm
- Has thanked: 27 times
- Been thanked: 15 times
Re: Rohan Online: GMF Models
bumping this beauty again. just saw a character creatin vid on youtube and remember this still has some cool models. Any viewer/converter out there longing for my harddrive?
- Rimbros
- ultra-veteran
- Posts: 495
- Joined: Fri Jul 09, 2010 12:23 am
- Has thanked: 41 times
- Been thanked: 16 times
Re: Rohan Online: GMF Models
Nothing News abouth the program to convert?
Renders Art by Rimbros
http://s303.photobucket.com/albums/nn12 ... E/Renders/
Personal Game repository samples, send PM
http://s303.photobucket.com/albums/nn12 ... E/Renders/
Personal Game repository samples, send PM