2 registered members (Quad, aliswee),
835
guests, and 5
spiders. |
Key:
Admin,
Global Mod,
Mod
|
|
|
Open/Extract Model and Textures from WMB
#482129
12/29/20 20:16
12/29/20 20:16
|
Joined: Dec 2020
Posts: 3
MooseMannequin
OP
Guest
|
OP
Guest
Joined: Dec 2020
Posts: 3
|
Hello everyone, sorry if this is not the right thread, but I didn't found the right one, so I'm not familiar with 3GS at all, and need your help. I have the WMB files from the game and I figured out, it carry model and texture files inside. I need to extract them somehow to edit in the zbrush/maya then, but I don't know how. I installed Gamestudio A8, but it can't open these files in any of editors. And I found out, one guy did it with Unity and some script, but it's just another one universe for me as well. I can send you the link, if you interested. I am doing it just for fun and out of curiosity, and need your help so much, thank you gamers. p.s. Sry if there is mistakes, am not english at all.
|
|
|
Re: Open/Extract Model and Textures from WMB
[Re: MooseMannequin]
#482131
12/30/20 09:23
12/30/20 09:23
|
Joined: May 2009
Posts: 5,370 Caucasus
3run
Senior Expert
|
Senior Expert
Joined: May 2009
Posts: 5,370
Caucasus
|
@Dooley as far as I remember, all game studio editors are working in free version (WED, MED, SED, but not sure about the GED). I remember there was a Lite-C version back in A7 times and it didn't have WED support, but it's not available anymore. Aside from that version differences are more about scene management, shader support, etc. Also it seems that the thread creator doesn't want to extract WAD files, but want to somehow extract textures/models from already compiled .WMB file. Sadly, I don't know how to do that.
|
|
|
Re: Open/Extract Model and Textures from WMB
[Re: MooseMannequin]
#482132
12/30/20 13:07
12/30/20 13:07
|
Joined: Jun 2007
Posts: 1,337 Hiporope and its pain
txesmi
Serious User
|
Serious User
Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
|
There is some information into http://www.conitec.net/beta/prog_mdlhmp.htmI did some tests some time ago. It is not really hard.
#include <acknex.h>
#define PRAGMA_PATH "models"
// ------------------------------------------------------------
STRING *strT = "";
TEXT *txtGlobal = {
pos_x = 10;
pos_y = 10;
string = ("GLOBAL", "--------------------");
flags = SHOW;
}
TEXT *txtObjects = {
pos_x = 200;
pos_y = 10;
string = ("OBJECTS", "--------------------");
flags = SHOW;
}
TEXT *txtMaterials = {
pos_x = 400;
pos_y = 10;
string = ("MATERIALS", "--------------------");
flags = SHOW;
}
TEXT *txtTextures = {
pos_x = 600;
pos_y = 10;
string = ("TEXTURES", "--------------------");
flags = SHOW;
}
TEXT *txtLightmaps = {
pos_x = 800;
pos_y = 10;
string = ("LIGHTMAPS", "--------------------");
flags = SHOW;
}
TEXT *txtBlocks = {
pos_x = 1000;
pos_y = 10;
string = ("BLOCKS", "--------------------");
flags = SHOW;
}
TEXT *txtPaths = {
pos_x = 1200;
pos_y = 10;
string = ("PATHS", "--------------------");
// flags = SHOW;
}
// ------------------------------------------------------------
typedef struct LIST {
long offset; // offset of the list from the start of the WMB file, in bytes
long length; // length of the list, in bytes
} LIST;
typedef struct WMB_HEADER {
char version[4]; // "WMB7"
LIST palettes; // WMB1..6 only
LIST legacy1; // WMB1..6 only
LIST textures; // textures list
LIST legacy2; // WMB1..6 only
LIST pvs; // BSP only
LIST bsp_nodes; // BSP only
LIST materials; // material names
LIST legacy3; // WMB1..6 only
LIST legacy4; // WMB1..6 only
LIST aabb_hulls; // WMB1..6 only
LIST bsp_leafs; // BSP only
LIST bsp_blocks; // BSP only
LIST legacy5; // WMB1..6 only
LIST legacy6; // WMB1..6 only
LIST legacy7; // WMB1..6 only
LIST objects; // entities, paths, sounds, etc.
LIST lightmaps; // lightmaps for blocks
LIST blocks; // block meshes
LIST legacy8; // WMB1..6 only
LIST lightmaps_terrain; // lightmaps for terrains
} WMB_HEADER;
typedef struct TEXTURE {
char name[16]; // texture name, max. 16 characters
long width,height; // texture size
long type; // texture type: 5 = 8888 RGBA; 4 = 888 RGB; 2 = 565 RGB; 6 = DDS; +8 = mipmaps
long legacy[3]; // always 0
} TEXTURE;
typedef struct MATERIAL_INFO {
char legacy[44]; // always 0
char material[20]; // material name from the script, max. 20 characters
} MATERIAL_INFO;
typedef struct LIGHTMAP_TERRAIN {
long object; // terrain entity index into the objects list
long width,height; // lightmap size
} LIGHTMAP_TERRAIN;
typedef struct BLOCK {
float fMins[3]; // bounding box
float fMaxs[3]; // bounding box
long lContent; // always 0
long lNumVerts; // number of VERTEX structs that follow
long lNumTris; // number of TRIANGLE structs that follow
long lNumSkins; // number of SKIN structs that follow
} BLOCK;
typedef struct VERTEX {
float x,y,z; // position
float tu,tv; // texture coordinates
float su,sv; // lightmap coordinates
} VERTEX;
typedef struct TRIANGLE {
short v1,v2,v3; // indices into the VERTEX array
short skin; // index into the SKIN array
long unused; // always 0
} TRIANGLE;
typedef struct SKIN {
short texture; // index into the textures list
short lightmap; // index into the lightmaps list
long material; // index into the MATERIAL_INFO array
float ambient,albedo;
long flags; // bit 1 = flat (no lightmap), bit 2 = sky, bit 14 = smooth
} SKIN;
typedef struct WMB_INFO {
long type; // 5 = INFO
float origin[3]; // not used
float azimuth; // sun azimuth
float elevation; // sun elevation
long flags; // always 127 (0x7F)
float version; // compiler version
byte gamma; // light level at black
byte LMapSize; // 0,1,2 for lightmap sizes 256x256, 512x512, or 1024x1024
byte unused[2];
DWORD dwSunColor,dwAmbientColor; // color double word, ARGB
DWORD dwFogColor[4];
} WMB_INFO;
typedef struct WMB_POSITION {
long type; // 1 = POSITION
float origin[3];
float angle[3];
long unused[2];
char name[20];
} WMB_POSITION;
typedef struct WMB_LIGHT {
long type; // 2 = LIGHT
float origin[3];
float red,green,blue; // color in percent, 0..100
float range;
long flags; // 0 = static, 2 = dynamic
} WMB_LIGHT;
typedef struct WMB_SOUND {
long type; // 4 = Sound
float origin[3];
float volume;
float unused[2];
long range;
long flags; // always 0
char filename[33];
} WMB_SOUND;
typedef struct WMB_PATH {
long type; // 6 = PATH
char name[20]; // Path name
float fNumPoints; // number of nodes
long unused[3]; // always 0
long num_edges;
} WMB_PATH;
typedef struct WMB_ENTITY {
long type; // 7 = ENTITY
float origin[3];
float angle[3];
float scale[3];
char name[33];
char filename[33];
char behavior[33];
float skill[20];
long flags;
float ambient;
float albedo;
long path; // attached path index, starting with 1, or 0 for no path
long entity2; // attached entity index, starting with 1, or 0 for no attached entity
char material[33];
char string1[33];
char string2[33];
char unused[33];
} WMB_ENTITY;
typedef struct WMB_OLD_ENTITY {
long type; // 3 = OLD ENTITY
float origin[3];
float angle[3];
float scale[3];
char name[20];
char filename[13];
char behavior[20];
float skill[8];
long flags;
float ambient;
} WMB_OLD_ENTITY;
typedef struct PATH_EDGE {
float fNode1,fNode2; // node numbers of the edge, starting with 1
float fLength;
float fBezier;
float fWeight;
float fSkill;
} PATH_EDGE;
typedef struct BSP_NODE {
long legacy1[2]; // WMB1..6 only
short mins[3]; // bounding box, packed shorts
short maxs[3];
long legacy2; // WMB1..6 only
long children[2]; // node index when >= 0, -(leaf index + 1) when < 0
long legacy3[2]; // WMB1..6 only
} BSP_NODE;
typedef struct BSP_LEAF {
long flags; // content flags
long pvs; // PVS offset or -1
short mins[3]; // bounding box, packed shorts
short maxs[3];
long legacy1[2]; // WMB1..6 only
long nbspblock; // offset into the bsp_blocks list
long numblocks; // number of bsp_blocks for this leaf
} BSP_LEAF;
typedef struct BSP_BLOCK {
long nblock; // index of block in the blocks list
} BSP_BLOCK;
// ------------------------------------------------------------
var texFormats[8] = {0, 0, 565, 0, 888, 8888, 0, 0};
typedef struct TX_TEXTURE {
TEXTURE *texture;
char name[16];
BYTE *buffer;
long bufSize;
BMAP *bmap;
long format;
long mipmaps;
long width;
long height;
PANEL *panel;
} TX_TEXTURE;
typedef struct TX_LIGHTMAP {
BYTE *buffer;
BMAP *bmap;
PANEL *panel;
} TX_LIGHTMAP;
typedef struct TX_TERRAIN_LIGHTMAP {
LIGHTMAP_TERRAIN *lightmap_terrain;
BYTE *buffer;
BMAP *bmap;
PANEL *panel;
} TX_TERRAIN_LIGHTMAP;
typedef struct TX_OBJECT {
BYTE *buffer;
long type;
} TX_OBJECT;
typedef struct TX_BLOCK {
BLOCK *block;
VERTEX *vertex;
TRIANGLE *tris;
SKIN *skins;
} TX_BLOCK;
typedef struct TX_FILE {
BYTE *buffer;
long bufSize;
char version[5];
//objects
long objCount;
TX_OBJECT *objects;
TX_OBJECT *info;
//blocks
long blkCount;
TX_BLOCK *blocks;
//materials
long mtlCount;
MATERIAL_INFO *materials;
//textures
long texCount;
TX_TEXTURE *textures;
//lightmaps
long lmCount;
TX_LIGHTMAP *lightmaps;
//terrain lightmaps
long tlmCount;
TX_LIGHTMAP *terrain_lightmaps;
} TX_FILE;
// ------------------------------------------------------------
void load_textures (TX_FILE *_txFile) {
WMB_HEADER *_header = _txFile->buffer;
long *_texOffArray = (long*)(_txFile->buffer + _header->textures.offset);
_txFile->texCount = *_texOffArray;
str_printf(strT, "Texture count: %d", _txFile->texCount);
txt_addstring(txtGlobal, strT);
txt_addstring(txtGlobal, " ");
_txFile->textures = sys_malloc(sizeof(TX_TEXTURE) * _txFile->texCount);
TX_TEXTURE *_txTex = _txFile->textures;
long *_texOff = _texOffArray + 1;
long _index = 0;
for(; _index < _txFile->texCount; _index += 1, _texOff += 1, _txTex += 1) {
_txTex->texture = (TEXTURE*)(((BYTE*)_texOffArray) + *_texOff);
memcpy(_txTex->name, _txTex->texture->name, 16);
_txTex->width = _txTex->texture->width;
_txTex->height = _txTex->texture->height;
_txTex->mipmaps = 0;
if(_txTex->texture->type - 8 > 0)
_txTex->mipmaps = 8;
_txTex->format = _txTex->texture->type - _txTex->mipmaps;
if(_txTex->format == 6) {
str_cpy(strT, _txTex->texture->name);
str_cat(strT, ".dds");
_txTex->buffer = _txTex->texture + 1;
_txTex->bufSize = _txTex->width;
add_buffer(strT->chars, _txTex->buffer, _txTex->bufSize);
_txTex->bmap = bmap_create(strT->chars);
_txTex->width = bmap_width(_txTex->bmap);
_txTex->height = bmap_height(_txTex->bmap);
add_buffer(strT->chars, NULL, _txTex->bufSize);
} else {
_txTex->bmap = bmap_createblack(_txTex->width, _txTex->height, texFormats[_txTex->format]);
bmap_lock(_txTex->bmap, 0);
_txTex->buffer = _txTex->texture + 1;
_txTex->bufSize = _txTex->width * _txTex->height * _txTex->bmap->finalbytespp;
memcpy(_txTex->bmap->finalbits, _txTex->buffer, _txTex->bufSize);
bmap_unlock(_txTex->bmap);
}
_txTex->panel = pan_create("flags=SHOW", 1);
_txTex->panel->pos_x = txtTextures->pos_x;
_txTex->panel->pos_y = 28 + _index * 45;
_txTex->panel->bmap = _txTex->bmap;
_txTex->panel->scale_x = 32.0 / (var)_txTex->width;
_txTex->panel->scale_y = 32.0 / (var)_txTex->height;
str_printf(strT, " Name: %s\n Width: %d\n Height: %d\n Type: %d + %d", _txTex->name, _txTex->width, _txTex->height, _txTex->format, _txTex->mipmaps);
txt_addstring(txtTextures, strT);
txt_addstring(txtTextures, " ");
}
}
void load_materials (TX_FILE *_txFile) {
WMB_HEADER *_header = _txFile->buffer;
_txFile->materials = _txFile->buffer + _header->materials.offset;
_txFile->mtlCount = _header->materials.length / sizeof(MATERIAL_INFO);
str_printf(strT, "Material count: %d", _txFile->mtlCount);
txt_addstring(txtGlobal, strT);
txt_addstring(txtGlobal, " ");
MATERIAL_INFO *_mtl = _txFile->materials;
long _index = 0;
for(; _index < _txFile->mtlCount; _index += 1, _mtl += 1) {
str_printf(strT, "Name: %s", _mtl->material);
txt_addstring(txtMaterials, strT);
txt_addstring(txtMaterials, " ");
}
}
void load_info (TX_OBJECT *_txObject, WMB_INFO *_info) {
_txObject->buffer = _info;
_txObject->type = _info->type;
txt_addstring(txtObjects, "WMB_INFO");
str_printf(strT, "Sun azimuth: %.3f", (double)_info->azimuth);
txt_addstring(txtObjects, strT);
str_printf(strT, "Sun elevation: %.3f", (double)_info->elevation);
txt_addstring(txtObjects, strT);
str_printf(strT, "Gamma: %d", _info->gamma);
txt_addstring(txtObjects, strT);
char *_chrCol = &_info->dwSunColor;
str_printf(strT, "Sun color: %d, %d, %d, %d", *(_chrCol++), *(_chrCol++), *(_chrCol++), *(_chrCol++));
txt_addstring(txtObjects, strT);
str_printf(strT, "Ambient color: %d, %d, %d, %d", *(_chrCol++), *(_chrCol++), *(_chrCol++), *(_chrCol++));
txt_addstring(txtObjects, strT);
str_printf(strT, "Fog 1 color: %d, %d, %d, %d", *(_chrCol++), *(_chrCol++), *(_chrCol++), *(_chrCol++));
txt_addstring(txtObjects, strT);
str_printf(strT, "Fog 2 color: %d, %d, %d, %d", *(_chrCol++), *(_chrCol++), *(_chrCol++), *(_chrCol++));
txt_addstring(txtObjects, strT);
str_printf(strT, "Fog 3 color: %d, %d, %d, %d", *(_chrCol++), *(_chrCol++), *(_chrCol++), *(_chrCol++));
txt_addstring(txtObjects, strT);
str_printf(strT, "Fog 4 color: %d, %d, %d, %d", *(_chrCol++), *(_chrCol++), *(_chrCol++), *(_chrCol++));
txt_addstring(txtObjects, strT);
txt_addstring(txtObjects, " ");
}
void load_position (TX_OBJECT *_txObject, WMB_POSITION *_pos) {
_txObject->buffer = _pos;
_txObject->type = _pos->type;
txt_addstring(txtObjects, "WMB_POSITION");
str_printf(strT, "Origin: %.3f,%.3f,%.3f", (double)_pos->origin[0], (double)_pos->origin[1], (double)_pos->origin[2]);
txt_addstring(txtObjects, strT);
txt_addstring(txtObjects, " ");
}
void load_light (TX_OBJECT *_txObject, WMB_LIGHT *_light) {
_txObject->buffer = _light;
_txObject->type = _light->type;
txt_addstring(txtObjects, "WMB_LIGHT");
str_printf(strT, "Origin: %.3f,%.3f,%.3f", (double)_light->origin[0], (double)_light->origin[1], (double)_light->origin[2]);
txt_addstring(txtObjects, strT);
txt_addstring(txtObjects, " ");
}
void load_sound (TX_OBJECT *_txObject, WMB_SOUND *_sound) {
_txObject->buffer = _sound;
_txObject->type = _sound->type;
txt_addstring(txtObjects, "WMB_SOUND");
str_printf(strT, "File: %s", _sound->filename);
txt_addstring(txtObjects, strT);
txt_addstring(txtObjects, " ");
}
void load_path (TX_OBJECT *_txObject, WMB_PATH *_path) {
_txObject->buffer = _path;
_txObject->type = _path->type;
txt_addstring(txtObjects, "WMB_PATH");
str_printf(strT, "Name: %s", _path->name);
txt_addstring(txtObjects, strT);
txt_addstring(txtObjects, " ");
}
void load_entity (TX_OBJECT *_txObject, WMB_ENTITY *_ent) {
_txObject->buffer = _ent;
_txObject->type = _ent->type;
txt_addstring(txtObjects, "WMB_ENTITY");
str_printf(strT, "File: %s", _ent->filename);
txt_addstring(txtObjects, strT);
txt_addstring(txtObjects, " ");
}
void load_old_entity (TX_OBJECT *_txObject, WMB_OLD_ENTITY *_ent) {
_txObject->buffer = _ent;
_txObject->type = _ent->type;
txt_addstring(txtObjects, "WMB_OLD_ENTITY");
str_printf(strT, "File: %s", _ent->filename);
txt_addstring(txtObjects, strT);
txt_addstring(txtObjects, " ");
}
void load_objects (TX_FILE *_txFile) {
WMB_HEADER *_header = _txFile->buffer;
long *_objOffArray = (long*)(_txFile->buffer + _header->objects.offset);
_txFile->objCount = *_objOffArray;
str_printf(strT, "Object count: %d", _txFile->objCount);
txt_addstring(txtGlobal, strT);
txt_addstring(txtGlobal, " ");
_txFile->objects = sys_malloc(sizeof(TX_OBJECT) * _txFile->objCount);
TX_OBJECT *_txObject = _txFile->objects;
long *_objOff = _objOffArray + 1;
long _index = 0;
for(; _index < _txFile->objCount; _index += 1, _objOff += 1, _txObject += 1) {
str_printf(strT, "ID: %d", _index);
txt_addstring(txtObjects, strT);
long *_objType = (long*)(((BYTE*)_objOffArray) + *_objOff);
switch(*_objType) {
case 1: //WMB_POSITION
load_position(_txObject, _objType);
break;
case 2: //WMB_LIGHT
load_light(_txObject, _objType);
break;
case 3: //WMB_OLD_ENTITY
load_old_entity(_txObject, _objType);
break;
case 4: //WMB_SOUND
load_sound(_txObject, _objType);
break;
case 5: //WMB_INFO
_txFile->info = _txObject;
load_info(_txObject, _objType);
break;
case 6: //WMB_PATH
load_path(_txObject, _objType);
break;
case 7: //WMB_ENTITY
load_entity(_txObject, _objType);
break;
default:
str_printf(strT, "type: %d", *_objType);
txt_addstring(txtObjects, strT);
txt_addstring(txtObjects, " ");
}
}
}
void load_lightmaps (TX_FILE *_txFile) {
WMB_HEADER *_header = _txFile->buffer;
long _width = 0;
WMB_INFO *_info = _txFile->info->buffer;
switch(_info->LMapSize) {
case 0: _width = 256; break; // 196608
case 1: _width = 512; break; // 786432
case 2: _width = 1024; break; // 3145728
}
long _size = _width * _width * 3;
_txFile->lmCount = _header->lightmaps.length / _size;
str_printf(strT, "Lightmmap count: %d", _txFile->lmCount);
txt_addstring(txtGlobal, strT);
txt_addstring(txtGlobal, " ");
_txFile->lightmaps = sys_malloc(sizeof(TX_LIGHTMAP) * _txFile->lmCount);
TX_LIGHTMAP *_txLm = _txFile->lightmaps;
BYTE *_buffer = _txFile->buffer + _header->lightmaps.offset;
long _index = 0;
for(; _index < _txFile->lmCount; _index += 1, _txLm += 1, _buffer += _size) {
_txLm->buffer = _buffer;
_txLm->bmap = bmap_createblack(_width, _width, 24);
bmap_lock(_txLm->bmap, 0);
BYTE *_bits = _txLm->bmap->finalbits;
BYTE *_pBuf = _txLm->buffer;
long _y = 0;
for(; _y < _width; _y += 1) {
long _x = 0;
for(; _x < _width; _x += 1, _pBuf += 3, _bits += 4) {
memcpy(_bits, _pBuf, 3);
*(_bits + 3) = 255;
}
}
bmap_unlock(_txLm->bmap);
_txLm->panel = pan_create("flags=SHOW", 1);
_txLm->panel->pos_x = txtLightmaps->pos_x;
_txLm->panel->pos_y = txtLightmaps->pos_y + txtLightmaps->strings * 9 /*+ _index * 45*/;
_txLm->panel->bmap = _txLm->bmap;
_txLm->panel->scale_x = 32.0 / (var)_width;
_txLm->panel->scale_y = 32.0 / (var)_width;
str_printf(strT, " ID: %d", _index);
txt_addstring(txtLightmaps, strT);
str_printf(strT, " Width: %d", _width);
txt_addstring(txtLightmaps, strT);
str_printf(strT, " Height: %d", _width);
txt_addstring(txtLightmaps, strT);
// txt_addstring(txtLightmaps, " ");
// txt_addstring(txtLightmaps, " ");
// txt_addstring(txtLightmaps, " ");
txt_addstring(txtLightmaps, " ");
// while(!key_space) {
// DEBUG_BMAP(_txLm->bmap, txtLightmaps->pos_x + 160, 1);
// wait(1);
// }
// key_pressed(-1);
// wait(1);
}
// str_printf(strT, "%d\n%d", _header->lightmaps.offset, _header->lightmaps.length);
// txt_addstring(txtLightmaps, strT);
// txt_addstring(txtLightmaps, " ");
//
// str_printf(strT, "%d", _size);
// txt_addstring(txtLightmaps, strT);
// txt_addstring(txtLightmaps, " ");
//
// str_printf(strT, "LMapSize: %d", _info->LMapSize);
// txt_addstring(txtLightmaps, strT);
// txt_addstring(txtLightmaps, " ");
// BMAP *_bmp = bmap_createblack(256, 256, 24);
// var _frm = bmap_lock(_bmp, 0);
// memcpy(_bmp->finalbits, _lmOffArray, 256*256*3);
// bmap_unlock(_bmp);
//
// while(!key_space) {
// DEBUG_BMAP(_bmp, 1, 1);
// wait(1);
// }
}
void load_lightmaps_terrain (TX_FILE *_txFile) {
WMB_HEADER *_header = _txFile->buffer;
long *_tlmOffArray = (long*)(_txFile->buffer + _header->lightmaps_terrain.offset);
_txFile->tlmCount = *_tlmOffArray;
str_printf(strT, "Lightmmap terrain count: %d", _txFile->tlmCount);
txt_addstring(txtGlobal, strT);
txt_addstring(txtGlobal, " ");
txt_addstring(txtLightmaps, " ");
txt_addstring(txtLightmaps, "TERRAIN LIGHTMAPS");
txt_addstring(txtLightmaps, "--------------------");
txt_addstring(txtLightmaps, " ");
_txFile->terrain_lightmaps = sys_malloc(sizeof(TX_TERRAIN_LIGHTMAP) * _txFile->tlmCount);
TX_TERRAIN_LIGHTMAP *_txLm = _txFile->terrain_lightmaps;
BYTE *_buffer = _tlmOffArray + 1;
long _index = 0;
for(; _index < _txFile->tlmCount; _index += 1, _txLm += 1) {
_txLm->lightmap_terrain = _buffer;
_txLm->buffer = _txLm->lightmap_terrain + 1; //_buffer + sizeof(LIGHTMAP_TERRAIN); //
long _size = _txLm->lightmap_terrain->width * _txLm->lightmap_terrain->height * 3;
// if(_index == 1) {
// _txLm->lightmap_terrain->object = 9;
// }
_txLm->bmap = bmap_createblack(_txLm->lightmap_terrain->width, _txLm->lightmap_terrain->height, 24);
bmap_lock(_txLm->bmap, 0);
BYTE *_bits = _txLm->bmap->finalbits;
BYTE *_pBuf = _txLm->buffer;
long _y = 0;
for(; _y < _txLm->lightmap_terrain->height; _y += 1) {
long _x = 0;
for(; _x < _txLm->lightmap_terrain->width; _x += 1, _pBuf += 3, _bits += 4) {
memcpy(_bits, _pBuf, 3);
*(_bits + 3) = 255;
}
}
bmap_unlock(_txLm->bmap);
_txLm->panel = pan_create("flags=SHOW", 1);
_txLm->panel->pos_x = txtLightmaps->pos_x;
_txLm->panel->pos_y = txtLightmaps->pos_y + txtLightmaps->strings * 9 /*+ _index * 45*/;
_txLm->panel->bmap = _txLm->bmap;
_txLm->panel->scale_x = 32.0 / (var)_txLm->lightmap_terrain->width;
_txLm->panel->scale_y = 32.0 / (var)_txLm->lightmap_terrain->height;
str_printf(strT, " Object ID: %d", _txLm->lightmap_terrain->object);
txt_addstring(txtLightmaps, strT);
str_printf(strT, " Width: %d", _txLm->lightmap_terrain->width);
txt_addstring(txtLightmaps, strT);
str_printf(strT, " Height: %d", _txLm->lightmap_terrain->height);
txt_addstring(txtLightmaps, strT);
txt_addstring(txtLightmaps, " ");
_buffer = _txLm->buffer + _size;
// while(!key_space) {
// DEBUG_BMAP(_txLm->bmap, 1, 1);
// wait(1);
// }
// key_pressed(-1);
// wait(1);
}
}
void load_blocks (TX_FILE *_txFile) {
WMB_HEADER *_header = _txFile->buffer;
long *_blkOffArray = (long*)(_txFile->buffer + _header->blocks.offset);
_txFile->blkCount = *_blkOffArray;
str_printf(strT, "Block count: %d", _txFile->blkCount);
txt_addstring(txtGlobal, strT);
txt_addstring(txtGlobal, " ");
_txFile->blocks = sys_malloc(sizeof(TX_BLOCK) * _txFile->blkCount);
TX_BLOCK *_txBlock = _txFile->blocks;
BYTE *_buffer = _blkOffArray + 1;
long _index = 0;
for(; _index < _txFile->blkCount; _index += 1, _txBlock += 1) {
_txBlock->block = _buffer;
_buffer += sizeof(BLOCK);
_txBlock->vertex = _buffer;
_buffer += sizeof(VERTEX) * _txBlock->block->lNumVerts;
_txBlock->tris = _buffer;
_buffer += sizeof(TRIANGLE) * _txBlock->block->lNumTris;
_txBlock->skins = _buffer;
_buffer += sizeof(SKIN) * _txBlock->block->lNumSkins;
str_printf(strT, "ID: %d", _index);
txt_addstring(txtBlocks, strT);
str_printf(strT, "Vertex: %d", _txBlock->block->lNumVerts);
txt_addstring(txtBlocks, strT);
str_printf(strT, "Triangles: %d", _txBlock->block->lNumTris);
txt_addstring(txtBlocks, strT);
str_printf(strT, "Skins: %d", _txBlock->block->lNumSkins);
txt_addstring(txtBlocks, strT);
txt_addstring(txtBlocks, " ");
}
}
TX_FILE *load_level_file (char *_levelName) {
if(!file_exists(_levelName)) {
printf("file not found\n%s", _levelName);
return NULL;
}
// main data struct
TX_FILE *_txFile = sys_malloc(sizeof(TX_FILE));
memset(_txFile, 0, sizeof(TX_FILE));
// open file
_txFile->buffer = file_load(_levelName, NULL, &_txFile->bufSize);
// header
WMB_HEADER *_header = _txFile->buffer;
// version
memcpy(_txFile->version, _header->version, 4);
_txFile->version[4] = NULL;
str_printf(strT, "Format version: %s", _txFile->version);
txt_addstring(txtGlobal, strT);
txt_addstring(txtGlobal, " ");
if(_txFile->version[3] != 55) {
txt_addstring(txtGlobal, "wrong wmb version");
return _txFile;
}
// objects
load_objects(_txFile);
// blocks
load_blocks(_txFile);
// materials
load_materials(_txFile);
// textures
load_textures(_txFile);
// lightmaps
load_lightmaps(_txFile);
wait_for(load_lightmaps);
// lightmaps terrain
load_lightmaps_terrain(_txFile);
txt_addstring(txtGlobal, "--------------------");
txt_addstring(txtGlobal, " ");
str_printf(strT, "objects: %d - %d", _header->objects.offset, _header->objects.length);
txt_addstring(txtGlobal, strT);
str_printf(strT, "legacy7: %d - %d", _header->legacy7.offset, _header->legacy7.length);
txt_addstring(txtGlobal, strT);
str_printf(strT, "legacy1: %d - %d", _header->legacy1.offset, _header->legacy1.length);
txt_addstring(txtGlobal, strT);
str_printf(strT, "blocks: %d - %d", _header->blocks.offset, _header->blocks.length);
txt_addstring(txtGlobal, strT);
str_printf(strT, "materials: %d - %d", _header->materials.offset, _header->materials.length);
txt_addstring(txtGlobal, strT);
str_printf(strT, "textures: %d - %d", _header->textures.offset, _header->textures.length);
txt_addstring(txtGlobal, strT);
str_printf(strT, "palettes: %d - %d", _header->palettes.offset, _header->palettes.length);
txt_addstring(txtGlobal, strT);
str_printf(strT, "lightmaps: %d - %d", _header->lightmaps.offset, _header->lightmaps.length);
txt_addstring(txtGlobal, strT);
str_printf(strT, "terrain lm: %d - %d", _header->lightmaps_terrain.offset, _header->lightmaps_terrain.length);
txt_addstring(txtGlobal, strT);
str_printf(strT, "bsp_leafs: %d - %d", _header->bsp_leafs.offset, _header->bsp_leafs.length);
txt_addstring(txtGlobal, strT);
str_printf(strT, "bsp_nodes: %d - %d", _header->bsp_nodes.offset, _header->bsp_nodes.length);
txt_addstring(txtGlobal, strT);
str_printf(strT, "aabb_hulls: %d - %d", _header->aabb_hulls.offset, _header->aabb_hulls.length);
txt_addstring(txtGlobal, strT);
str_printf(strT, "bsp_blocks: %d - %d", _header->bsp_blocks.offset, _header->bsp_blocks.length);
txt_addstring(txtGlobal, strT);
str_printf(strT, "pvs: %d - %d", _header->pvs.offset, _header->pvs.length);
txt_addstring(txtGlobal, strT);
str_printf(strT, " %d", _header->pvs.offset + _header->pvs.length);
txt_addstring(txtGlobal, strT);
str_printf(strT, "legacy2: %d - %d", _header->legacy2.offset, _header->legacy2.length);
txt_addstring(txtGlobal, strT);
str_printf(strT, "legacy3: %d - %d", _header->legacy3.offset, _header->legacy3.length);
txt_addstring(txtGlobal, strT);
str_printf(strT, "legacy4: %d - %d", _header->legacy4.offset, _header->legacy4.length);
txt_addstring(txtGlobal, strT);
str_printf(strT, "legacy5: %d - %d", _header->legacy5.offset, _header->legacy5.length);
txt_addstring(txtGlobal, strT);
str_printf(strT, "legacy6: %d - %d", _header->legacy6.offset, _header->legacy6.length);
txt_addstring(txtGlobal, strT);
str_printf(strT, "legacy8: %d - %d", _header->legacy8.offset, _header->legacy8.length);
txt_addstring(txtGlobal, strT);
txt_addstring(txtGlobal, " ");
return _txFile;
}
void txFile_remove (TX_FILE *_txFile) {
// TX_TEXTURE *_txTex = _txFile->textures;
// long _index = 0;
// for(; _index<_txFile->texCount; _index+=1, _txTex+=1) {
// pan_remove(_txTex->panel);
// bmap_remove(_txTex->bmap);
// }
// sys_free(_txFile->textures);
file_load(NULL, _txFile->buffer, &_txFile->bufSize);
}
void main () {
video_mode = 10;
wait(3);
on_esc = NULL;
level_load("");
camera->bg = pixel_for_vec(vector(0,0,0), 100, 888);
TX_FILE *_txFile = load_level_file("scene.wmb");
while(!key_esc) {
wait(1);
}
file_save("scene_mod.wmb", _txFile->buffer, _txFile->bufSize);
txFile_remove(_txFile);
sys_exit(NULL);
}
Have fun!
Last edited by txesmi; 12/31/20 07:54.
|
|
|
Re: Open/Extract Model and Textures from WMB
[Re: txesmi]
#482133
12/30/20 16:20
12/30/20 16:20
|
Joined: Dec 2020
Posts: 3
MooseMannequin
OP
Guest
|
OP
Guest
Joined: Dec 2020
Posts: 3
|
Uuuuuh, what exactly should I do with this terrifying tree? I read info in the link, at least now I know that, .WMB created in WED. I already tried import my .WMB there, it just says: "invalid file name" and that's it. But even if it'll open, I still don't get how to extract the model from .WMB. I thought, it's gonna be something like .OBJ or other 3D type file haha. If it's gonna be the code, I have no use of it then. I need visual model.
And I made mistake, I said, that .WMB has model and textures. .WMB has the model only, the textures in .WTB files. Thanks
|
|
|
Re: Open/Extract Model and Textures from WMB
[Re: MooseMannequin]
#482134
12/30/20 16:36
12/30/20 16:36
|
Joined: May 2005
Posts: 868 Chicago, IL
Dooley
User
|
User
Joined: May 2005
Posts: 868
Chicago, IL
|
A WMB file is a game level, so it will contain 3D models as well as textures. However, WMB is the compiled level, not the editable level you would work on designing. I misread this part, and assumed you meant WMP, which is the editable level.
As WMB, it would be much more difficult to extract models and textures from it. txesmi's script, if I understand it correctly, would allow you to open a WMB and extract models/textures as you need, but if you are not familiar with how the engine works, and how to run scripts, then that might look intimidating.
|
|
|
Re: Open/Extract Model and Textures from WMB
[Re: MooseMannequin]
#482135
12/30/20 18:31
12/30/20 18:31
|
Joined: Oct 2007
Posts: 5,210 İstanbul, Turkey
Quad
Senior Expert
|
Senior Expert
Joined: Oct 2007
Posts: 5,210
İstanbul, Turkey
|
Only level blocks are actually in the wmb file. Models/textures are separate files with the extension .mdl. Models may be compressed in wrs though.
3333333333
|
|
|
Re: Open/Extract Model and Textures from WMB
[Re: Dooley]
#482136
12/30/20 20:23
12/30/20 20:23
|
Joined: Dec 2020
Posts: 3
MooseMannequin
OP
Guest
|
OP
Guest
Joined: Dec 2020
Posts: 3
|
I understand, well, I can run scripts on "copy/paste, press Run" level haha, but I definitely not familiar with engines, So, I think, I will try do this through Unity, but again I need to figure out how to use Python there, instead of C#, because the script WMB2OBJ that I found, written on Python language.
|
|
|
|