I. Model Extraction
Previews
First and foremost, knowledge of using Hex2Obj is required.
I'll take "DVD_SuitUpIronManMark6.pkg" from PS3 as an example, XBox360 version should be similar.
After unpacking the archive with "IronMan2_Unpacker_SF.bms" there should be five folders named from "0" to "4".
In the folder "0" there are files suffixing with "_ib_gpudata", for face indices; and "_vb_gpudata", for vertices/UV data or both.
Folder "4" contains index files for all other files outside this folder. Here files suffixing with "_vb_gpumaindata" are the actual vertices file and in this case,
"_vb_gpudata" suffixed files in folder "0" are just UV files. You can take a look at them to obtain a basic understanding of UV data. It shouldn't be too hard to calculate FI & vertices counts, and you don't even need to find their start address because they both are 0x0. Just copy everything into one file(face indices, vertices, UVs if it's separated) and record the needed offsets and counts.
But of course these info can be found in the header files in the index folder, here the "4" folder.
For PS3 version:
Code: Select all
Files suffixing with Explanation
_vb_gpumaindata Vertex coordinate data, no UVs, UVs are in separate file with same basename but suffixs with _vb_gpudata
_ib Face indices data header
_vb Vertex data header
---------------------------------------------------------------------------------------------------------------------------------------
_ib_gpudata Face indices data
_vb_gpudata Vertex data, could contain UVs(depends upon whether _vb_gpumaindata exist or not)
Header file structures
_ib Structure
Code: Select all
0x1C LONG Faces count
0x20 LONG Face indices count
0x24 LONG Vertex count
_vb Structure
Code: Select all
0x18 LONG Vertex count
0x40 LONG Vertex stride size
0x44 LONG Vertex coordinate data size
0x60 LONG UVB size
0x64 LONG UV data size
0x68 LONG UV data start offset
For XBox 360 version:
Code: Select all
Files suffixing with Explanation
_ib Face indices data header
_vb Vertex data header
---------------------------------------------------------------------------------------------------------------------------------------
_ib_gpudata Face indices data
_vb_gpudata Vertex data, contains UVs
Header file structures
_ib Structure
Code: Select all
0x20 LONG Face indices count
0x24 LONG Vertex count
_vb Structure
Code: Select all
0x0C LONG Vertex count
0x1C LONG Vertex stride size
0x2C LONG UVB size
0x30 LONG UV data start offset
To obtain UVs, just load your mesh with "HF_UV" type selected.
Extra information for Hex2Obj:
BigEndian; VB mode; Vertex data type set to Float(or HF_UV); FVFsize 12, 16, 28; UVB size 4, 12.
II. Textures Extraction
Full size image previews

In this case, textures are stored in folder "1" and "2" with different resolution. Chances are that the one with smaller size could sometimes contain bigger-res textures. Each file inside is a small textures pack containing at least 1 map, usually 2. Texture info stores in suffixal files with _Diffuse/_AmbientOcclusion/_Normal/_LightEmission in folder "4". Their structure is showed bellow:
Code: Select all
Offset Type
0x00 LONG Unknown, always be 0.
0x04 LONG Entry size, 0x1C per entry.
0x08 LONG Size of the entire entry, barring 0xC bytes header.
0x0C LONG DDS formats, 0x0 for dxt1, 0x3 for dxt5, 0x4 for dxt1 packed ATI1/BC4, 0x6 for DXT5 packed normal map(X360), or dxt5 NormalMap(PS3),
0x8 for ?
0x10 LONG Image width
0x14 LONG Image height
0x18 LONG MIP maps number
0x1C LONG Texture data start offset in each texture pack, first entry for SurfaceResident, second for SurfaceStreamed when have two entries.
0x20 LONGLONG 0xFF FF FF FF FF FF FF FF, ending string of this directory.
Pattern repeats if entry number is larger than 1. The last four bytes represent the group amount containing the same map in different resolusion.
I don't know how to handle MIP maps for XBox360 version in Noesis, but this Noesis script should do the trick:
Code: Select all
from inc_noesis import *
def registerNoesisTypes():
handle = noesis.register("Iron Man II XBox360 Textures", ".i2t")
noesis.setHandlerTypeCheck(handle, noepyCheckType)
noesis.setHandlerLoadRGBA(handle, noepyLoadRGBA)
return 1
def noepyCheckType(data):
if len(data) < 8:
return 0
return 1
def noepyLoadRGBA(data, texList):
datasize = len(data)
bs = NoeBitStream(data, NOE_BIGENDIAN)
imgWidth = #Set your image width here
imgHeight = #Set your image height here
data = bs.readBytes(datasize)
#data = rapi.imageUntile360DXT(rapi.swapEndianArray(data, 2), imgWidth, imgHeight, 16) # XBox360 version needed, change 16 to 8 if format is dxt1
texFmt = noesis.NOESISTEX_DXT5 # change 5 to 1 if format is dxt1
texList.append(NoeTexture(rapi.getInputName(), imgWidth, imgHeight, data, texFmt))
return 1
Before you use it remember split the texture group to individual file and rename them to .i2t format. Select "Reload Plugins" under "Tools" every time you modify the script.
Some textures cannot be handled correctly. I guess it might be using a different order of RGB coz Alpha looks OK in Photoshop, or it's in different formats.