Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

[Pomoc] Rohan Online - Modele 3D


Rekomendowane odpowiedzi

Opublikowano

Witam Wszystkich.

 

Nie wiem czy dobry dział, ale nigdzie nie znalazłem podobnego więc piszę tutaj. Do rzeczy:

Grałem już w niejedną grę online, najbardziej przypadły mi do gustu 3 z nich: Rohan Online - za piękną grafikę i "coś jeszcze", Atlantica - za pomysłowość i Metin2 - za dynamikę. Pomyślałem, że fajnie by było zebrać najlepsze rzeczy z tych gier w jedną. Dzięki temu forum udało mi się "rozebrać" metina, dzięki nauce 3ds max wyciąłem "co nieco" z gry Atlantica Online jednak najważniejsza z tych gier - Rohan okazał się największym wyzwaniem. Dzięki kodowi znalezionemu na innym forum udało mi się wypakować pliki .gem i .gel w których to zapakowane są pliki Rohana.

Tutaj macie ten kod:

 

#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;

}

 

 

Niestety po ich wypakowaniu okazało się, że plików nadal nie da się użyć (wszystkich oprócz tekstur, program wypakowuje pliki z rozszerzeniem .tga ale w rzeczywistości powinno być .dds, wystarczy zmienić rozszerzenie). Animacje zapisane są jako .GAF, szkielet jako .gsf, material (???) jako .grf i w końcu najważniejsze - mesh jako .gmf. Przeszukałem chyba całe google w poszukiwaniu programu, który mógłby otworzyć i przekonwertować pliki .gmf na inny format, znalazłem tylko Ultimate Unwrap 3D, do którego linki na oficjalnej stronie nie działają a nigdzie poza tą stroną nie można go znaleźć. Na forum, na którym znalazłem kod do rozpakowywania .gem i .gel istniał projekt, który miał na celu przetworzenie plików .gmf na .obj, niestety wygląda na to, że został dawno już porzucony, nikt nie odpowiada już w tamtym temacie a autorzy pozostawili po sobie tylko kody, które nie mam pojęcia jak użyć:

Animacje

char[4] header //CAF

dword ver //Version

float fTime //Length of this animation in second

dword ?? //always 1, No. of amnimation ??

dword nBones //No. of bones

struct Animation {

dword nBLen //length of Bone name

char[nBLen] sBone //Bone name

dword nKeys //no. of key frames

struct KeyData {

float fKTime //key time

float X 3 posXYZ //position XYZ

float X 4 rotXYZW //rotation quat XYZW

} KeyData[nKeys]

} Animation[nBones]

 

Szkielet

char[4] header //CSF

dword ver //Version

dword nBones //Bones count

struct Bone {

dword nBLen //length of Bone name

char[nBLen] sBone //Bone name

float X 3 pos1 //Position XYZ

float X 4 rot1 //Rotation Quat XYZW

float X 3 pos2 //another set of Position XYZ ??

float X 4 rot2 //another set of Rotation Quat XYZW ??

dword nPLen //length of Parent name

char[nBLen] sPBone //Parent name

dword nChild //Children count

struct ChildBone {

dword nCLen //length of Child name

char[nBLen] sCBone //Child name

} ChildBone[nChild]

} Bone[nBones]

 

 

i dwa najważniejsze Mesh

1)

 

==============

Header Section

==============

char[4] header //CMF

dword ver //Version

dword ??

dword nMLen //length of material name

char[nMLen] sMtl //material name(internal)??

 

==============

Mesh 1 Section

==============

dword nVerts //Verts count

dword nFaces //Faces count

dword ??

dword nLayer //No. of UV layers

*dword ?? //appears in version 1200 only

struct VertPool {

float X 3 posXYZ //Position XYZ

float X 3 norXYZ //Normal XYZ

byte X 7 ?? //always FF

dword ?? //always 0

struct TexCoord {

float X 2 uv

} TexCoord[nLayer]

dword nABone //No. of Bones for this vert

struct BoneSkin { //appears when bFlag == 1

dword nBLen //length of Bone name

char[nBLen] sBone //Bone name

float wgt //Bone weight

float X 3 //another set of position ??

float X 3 //another set of normal ??

} BoneSkin[nABone]

} VertPool[nVerts]

struct Face {

dword nIdx1 //Face index 1

dword nIdx2 //Face index 2

dword nIdx3 //Face index 3

} Face[nFace]

 

==============

Mesh 2 Section

==============

dword nLOD //always 20

dword nPart //No. parts of this mesh

struct MeshPart {

dword nBone //No. bones for this part

struct BonesData {

dword nLen //length of bone name

char[nLen] sBName //Bone name

} BonesData[nBone]

dword nFidx //face index count

struct face {

word f1 //face index 1

word f2 //face index 2

word f3 //face index 3

} face[nFidx/3]

dword nVert //vert count

struct vertPool {

float X 3 vt //Position xyz

byte X 4 ?? //Vert color??

float X 3 norl //Normal

float X 3 ??

*dword ?? //appears in version 1200 only

float X 2 uv //Texture coordinate

*float X ?? //7 bytes for ver 1200, 5 for the others

} vertPool[nVert]

} MeshPart[nPart]

==============

Mesh 3 Section

==============

Same as Mesh 2 Section

 

2)

 

/* 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

}

}

}

}

}

 

 

Jest jeszcze material ale wydaje mi się nieważny. Są to kody w języku C++, jakkolwiek mam jakieś pojęcie o programowaniu tak te kody są dla mnie zbyt skomplikowane, próba ich kompilacji kończy się niepowodzeniem. Może coś źle robię, może powinienem coś dopisać lub wkleić je do kodu, który został przeze mnie podany w pierwszym spojlerze. Nie jeden raz to forum przyszło mi już z pomocą, dlatego postanowiłem napisać tutaj, może znajdzie się na tym forum programista, który z pomocą powyższych kodów znajdzie sposób, by zamienić pliki .gmf na jakiekolwiek inne, takie które można by otworzyć w 3DS max?

 

Tutaj macie link do oryginalnego tematu:

To jest ukryta treść, proszę

 

Za każdą pomoc oczywiście polecą + lub -, co tam wolicie i 5 w profilu. Z góry dziękuję każdemu kto chociaż spróbuje.

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Zaloguj się poniżej.

Zaloguj się
×
×
  • Dodaj nową pozycję...