Re: [Request] Kingdom Hearts Birth By Sleep models
Posted: Wed Aug 18, 2010 6:26 pm
Well I actually thought that, when its released in English, more people will be interested in it.
Hmmw well i opened the tm2 file in noesis and this was my before the exoprtZerox wrote:Make sure you export the tm2 files as .png or .tga by adding that to the end of the file name.
actually yeah im a newbie ^^" and well i know i extracted textures BUT then how can we extract models??Panzah wrote:Are you a newbie? That's exactly how textures look. There is nothing wrong with them. If you though that textures are models, then you are wrong.
Models are 3D meshes made out of polygons (triangles of different sizes and shapes placed in three dimensional space). Textures are what you could call a "skin" which is put on the model. I don't really know how to explain it to a person who doesn't seem to know what he's doing so well, I guess this will have to do.
Basicly, what you exported are textures and they are just fine, nothing wrong with them.
ahh thanks zeorx ^^ i already have a registered milkshop and well that aside can you tell me that how can i apply textures to these models?? ^^Zerox wrote:Yeah the .objs are the exported models. And I will admit I have no idea how to use Blender for anything other than importing and exporting. An easy alternative I can think of is Milkshape 3D, though it's not nearly as capable as Blender, it is more simplistic and user friendly. You can start it out with a 30 day free trial and then it's only $20 USD.
Well, I guess nobody is working on this anymore, and I too would like to have a good exporter that would support normals and hopefully bones along with all the weights aswell.Zerox wrote:Well in Milkshape you select the geoset group you want to give a texture and then in the materials tab select the material with your texture and double click it to assign it or just click the assign button.
All off-topic aside is anyone trying to make any progress on this?
Code: Select all
/*****************************************************************************
* pmo.bt - Structure definitions for Kingdom Hearts: Birth by Sleep - pmo file related entities.
*
*****************************************************************************
* Revision History:
* 2010/08/11 - revel8n - Original
*/
#include "common-types.bt"
SetReadOnly(true);
// #pragma displayname("pmo structures")
// #pragma fileextensions(".pmo")
// #pragma byteorder(little_endian)
LittleEndian();
// mark used bytes with a light green background
SetBackColor(cLtGreen);
BitfieldDisablePadding();
enum GsPSM //<uint32>
{
// Pixel Storage Format (0 = 32bit RGBA)
GS_PSMCT32 = 0,
GS_PSMCT24 = 1,
GS_PSMCT16 = 2,
GS_PSMCT16S = 10,
GS_PSMT8 = 19,
GS_PSMT4 = 20,
GS_PSMT8H = 27,
GS_PSMT4HL = 36,
GS_PSMT4HH = 44,
GS_PSMZ32 = 48,
GS_PSMZ24 = 49,
GS_PSMZ16 = 50,
GS_PSMZ16S = 58,
};
enum <uint8> IMG_TYPE
{
IT_RGBA = 3,
IT_CLUT4 = 4,
IT_CLUT8 = 5,
};
enum <uint8> CLT_TYPE
{
CT_A1BGR5 = 1,
CT_XBGR8 = 2,
CT_ABGR8 = 3,
};
typedef struct
{
uint64 TBP0 :14; // Texture Buffer Base Pointer (Address/256)
uint64 TBW : 6; // Texture Buffer Width (Texels/64)
GsPSM PSM : 6; // Pixel Storage Format (0 = 32bit RGBA)
uint64 TW : 4; // width = 2^TW
uint64 TH : 4; // height = 2^TH
uint64 TCC : 1; // 0 = RGB, 1 = RGBA
uint64 TFX : 2; // TFX - Texture Function (0=modulate, 1=decal, 2=hilight, 3=hilight2)
uint64 CBP :14; // CLUT Buffer Base Pointer (Address/256)
GsPSM CPSM : 4; // CLUT Storage Format
uint64 CSM : 1; // CLUT Storage Mode
uint64 CSA : 5; // CLUT Offset
uint64 CLD : 3; // CLUT Load Control
} GsTex0;
struct PMO_TEXTURE_HEADER
{
// 0x00
SetBackColor(cLtBlue);
uint32 dataOffset <format = hex>;
SetBackColor(cLtYellow);
char resourceName[0x0C];
// 0x10
SetBackColor(cLtGreen);
uint32 unknown0x10[4];
if (dataOffset < FileSize())
{
local int64 filePos = FTell();
FSeek(dataOffset);
// TM2 File Structure
struct TM2_FILE
{
SetBackColor(cLtBlue);
// tm2 File Header Structure - 0x10 (16) bytes
struct TM2_HEADER
{
char fileID[4]; // usually 'TIM2' or 'CLT2'
uint8 version; // format version
uint8 id; // format id
uint16 imageCount;
uint32 padding[2];
} fileHeader; // file header
struct
{
struct TM2_IMAGE_DATA
{
SetBackColor(cLtGreen);
struct TM2_PICTURE_HEADER
{
// 0x00
uint32 totalSize <format = hex>;
uint32 clutSize <format = hex>;
uint32 imageSize <format = hex>;
uint16 headerSize <format = hex>;
uint16 clutColors;
// 0x10
uint8 format;
uint8 mipMapCount;
CLT_TYPE clutType;
IMG_TYPE imageType;
uint16 width;
uint16 height;
GsTex0 GsTex0b; //[8];
// 0x20
GsTex0 GsTex1b; //[8];
uint32 GsRegs;
uint32 GsTexClut;
} pictureHeader;
SetBackColor(cLtRed);
struct
{
uint8 data[pictureHeader.imageSize];
} imagePixels;
SetBackColor(cLtYellow);
struct
{
uint8 data[pictureHeader.clutSize];
} imageCLUT;
} imageData[fileHeader.imageCount] <optimize = false>;
} imageData;
} textureData;
FSeek(filePos);
}
};
struct PMO_MESH_HEADER(uint32 skeletonOffset)
{
SetBackColor(cLtBlue);
// 0x00
uint16 vertexCount;
if (vertexCount == 0)
break;
uint8 textureID;
uint8 vertexSize;
SetBackColor(cLtBlue);
struct
{
uint32 texCoord : 2; // texture coordinate format: 0 - none, 1 - uint8, 2 - uint16, 3 - float
uint32 unknown9 : 2; //
uint32 unknown0 : 3; // unsure of bit size, but when this is not zero, diffuse color is present in vertex data
uint32 position : 2; // position format: 0 - none, 2 - int16, 3 - float
uint32 skinning : 1; // only seems to be set when there are joint weights present?
uint32 unknown1 : 4;
uint32 jointCnt : 4; // maximum joint index used? (index count = joint count + 1 - or just use (jointCnt + skinning)
uint32 unknown2 : 6;
uint32 diffuse : 1; // seems to only be set when a diffuse color is present in header
uint32 unknown3 : 3;
uint32 dataType : 4; // 0x30 - tri-list, 0x40 - tri-strip - ?
} dataFlags;
SetBackColor(cLtBlue);
uint8 unknown0x08;
uint8 triStripCount;
uint8 unknown0x0A[2];
if (skeletonOffset != 0)
{
uint8 jointIndices[8];
}
if (dataFlags.diffuse & 1)
{
uint32 diffuseColor <format = hex>;
}
//Printf("Format flags for vertex size (0x%02X) - 0x%08X\n", vertexSize, dataFlags.flagValue);
if (dataFlags.dataType == 3 && (vertexCount % 3) != 0)
Printf("Tri-list vertex count mis-match (0x%02X) - 0x%08X\n", vertexCount, FTell());
if (triStripCount > 0)
{
SetBackColor(cLtGreen);
uint16 triStripLengths[triStripCount];
}
SetBackColor(cLtRed);
struct
{
union
{
struct
{
local uint32 jointCount = dataFlags.skinning + dataFlags.jointCnt;
if (jointCount > 0)
{
uint8 jointWeights[jointCount];
}
if (dataFlags.texCoord > 0)
{
switch (dataFlags.texCoord)
{
case 1:
uint8 textureCoord[2];
break;
case 2:
FSkip((0x02 - ((FTell() - startof(this)) & 0x01)) & 0x01);
uint16 textureCoord[2];
break;
case 3:
if (vertexSize != 0x10 && vertexSize != 0x14 && vertexSize != 0x18)
Printf("Float texture coordinates at offset 0x%08X.\n", FTell());
FSkip((0x04 - ((FTell() - startof(this)) & 0x03)) & 0x03);
float2 textureCoord;
break;
default:
Printf("Unrecognized texture coordinate format! - 0x%08X\n", FTell());
break;
}
}
if (dataFlags.unknown0 != 0)
{
switch (dataFlags.unknown0)
{
case 1:
FSkip((0x04 - ((FTell() - startof(this)) & 0x03)) & 0x03);
uint32 diffuseColor <format = hex>;
break;
case 2:
uint8 diffuseColor[3] <format = hex>;
break;
default:
Printf("Unrecognized color format! - 0x%08X\n", FTell());
break;
}
if (vertexSize != 0x14 && vertexSize != 0x18 && vertexSize != 0x10)
{
Printf("Diffuse color present on unexpected vertex size (0x%02X) at 0x%08X\n", vertexSize, FTell());
}
}
if (dataFlags.position != 0)
{
switch (dataFlags.position)
{
case 2:
FSkip((0x02 - ((FTell() - startof(this)) & 0x01)) & 0x01);
int16 position[3];
break;
case 3:
FSkip((0x04 - ((FTell() - startof(this)) & 0x03)) & 0x03);
float3 position;
break;
default:
Printf("Unrecognized position format! - 0x%08X\n", FTell());
break;
}
}
local uint32 paddingSize = vertexSize - (FTell() - startof(this));
if (paddingSize > 0)
{
uint8 padding[paddingSize];
}
} vertex;
uint8 dataBytes[vertexSize];
} vertexData[vertexCount] <optimize = false>;
} vertexData;
FSkip((0x4 - (FTell() & 0x3)) & 0x3);
};
struct PMO_JOINT
{
SetBackColor(cLtBlue);
uint16 index;
uint16 padding0;
uint16 parent;
uint16 padding1;
uint16 unknown0x08; // skinning index?
uint16 padding2;
uint32 unknown0x0C;
// 0x10
SetBackColor(cLtYellow);
char name[0x10];
// 0x20
SetBackColor(cLtGreen);
float4x4 transform;
float4x4 transformInverse;
};
struct PMO_SKEL_HEADER
{
SetBackColor(cLtBlue);
char dataTag[4]; // 'BON'
uint32 unknown0x04;
uint32 jointCount;
uint16 unknown0x0C; // number of skinned joints?
uint16 unknown0x0E; // skinning start index
struct PMO_JOINT jointData[jointCount];
};
struct PMO_HEADER
{
SetBackColor(cLtBlue);
// 0x00
char fileTag[4]; // 'PMO'
uint8 unknown0x04[4];
uint16 textureCount; //
uint16 unknown0x0A;
uint32 skeletonOffset <format = hex>;
// 0x10
uint32 meshOffset0 <format = hex>;
uint16 triangleCount;
uint16 vertexCount;
float unknown0x18; // radius?
uint32 meshOffset1 <format = hex>;
// 0x20
SetBackColor(cLtGreen);
float4 boundingBox[8];
};
struct PMO_FILE
{
SetBackColor(cLtBlue);
struct PMO_HEADER header;
if (header.textureCount > 0)
{
struct
{
struct PMO_TEXTURE_HEADER textureInfo[header.textureCount] <optimize = false>;
} textureInfo;
}
if (header.meshOffset0 != 0)
{
FSeek(header.meshOffset0);
struct
{
while (!FEof())
{
struct PMO_MESH_HEADER meshInfo(header.skeletonOffset);
if (meshInfo.vertexCount == 0)
break;
}
} meshInfo0;
}
if (header.meshOffset1 != 0)
{
FSeek(header.meshOffset1);
struct
{
while (!FEof())
{
struct PMO_MESH_HEADER meshInfo(header.skeletonOffset);
if (meshInfo.vertexCount == 0)
break;
}
} meshInfo1;
}
if (header.skeletonOffset != 0)
{
FSeek(header.skeletonOffset);
struct PMO_SKEL_HEADER skeletonInfo;
}
};
struct PMO_FILE fileInfo;
Code: Select all
//LoL2Obj by renticletape
//Converts the LoL's .sco model format into the .obj model format
#include<iostream>
#include<fstream>
#include<vector>
#include<string>
#include<sstream>
using namespace std;
struct vector3 {
float x,y,z;
};
struct vector2 {
float x,y,z;
};
struct face {
vector<int> index;
};
int main(int argc, char* argv[]) {
ifstream fin; //file input stream
ofstream fout; //file output stream
int vertcount; //number of vertecies
int facecount; //number of faces
if (argc < 2) {
cout << "error: no input files\n";
exit(1);
}
fin.open(argv[1]); //open the first arguement from the command line
if (fin.fail()) {
cout << "error: failed to read: " << argv[1];
exit(1);
}
if (argc == 2) {
fout.open(string(string(argv[1]) + string(".obj")).c_str());
} else {
fout.open(argv[2]);
}
if (fout.fail()) {
cout << "Failed to open the output file\n";
exit(1);
}
while(!fin.eof()) {
string line;
stringstream ss;
string tmp;
getline(fin,line);
ss << line;
ss >> tmp;
if (tmp == "Verts=") {
//read in the vertecies
ss >> vertcount;
for (int i = 0; i < vertcount; i++) {
vector3 vtx;
fin >> vtx.x >> vtx.y >> vtx.z;
//output the verts in the obj format
fout << "v " << vtx.x << " " << vtx.y << " " << vtx.z << "\n";
}
cout << "read " << vertcount << " vertecies" << "\n";
}
if (tmp == "Faces=") {
int vtc = 1; //vertex counter, set initially to 1 because the obj format starts at 1 for indexing
ss >> facecount;
for (int i = 0; i < facecount; i++) {
face f;
int facesize; //number of verts per face
fin >> facesize;
for (int j = 0; j < facesize; j++) {
int v;
fin >> v;
f.index.push_back(v);
}
fin >> tmp;
for (int j = 0; j < facesize; j++) {
//read in the UV coordinates
vector2 vt;
fin >> vt.x >> vt.y;
fout << "vt " << vt.x << " " << 1.0 - vt.y << "\n";
}
fout << "f ";
for (int j = 0; j < (int)f.index.size(); j++) {
fout << f.index[j] + 1 << "/" << vtc << " ";
vtc ++;
}
fout << "\n";
getline(fin,tmp);
}
cout << "read " << facecount << " faces" << "\n";
}
}
}