Hi.
I'm making my own little game for Play Station Portable, and i'd love to use the model loader source on it.
I got a copy of LTE engine for PSP, then i tried to understand the code and isolate the parts i want. But i'm not a very skilled C programmer, so the engine was too much for me.
All the nodes, scenes etc, are very confusing, so I'd like to "rip" just the code for .MD2 and/or .X loader, to use animated models in my game, without the rest of the engine.
To be more specific, i'll just use something like this pseudocode:
"LoadModel()"
"RenderModel(Frame_interval,speed)"
If somebody helps me i'd really apreciate it. Of course I'll credit the engine and people.
Thanks a lot.
Using part of the engine source (MD2 and X model loader)
Re: Using part of the engine source (MD2 and X model loader)
How will you do the animations then without the engine? Much of what the loader does is to create the animation data from file in the internal format needed by Irrlicht. Similar for material data, mesh-data and so on. If you don't use the engine then it doesn't really make much sense to use the loader.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Re: Using part of the engine source (MD2 and X model loader)
That's what i saw...CuteAlien wrote:How will you do the animations then without the engine? Much of what the loader does is to create the animation data from file in the internal format needed by Irrlicht. Similar for material data, mesh-data and so on. If you don't use the engine then it doesn't really make much sense to use the loader.
I found a md2 loader with all needed code in one file. But this code did not load the face normals, so the objects can't use lights.
This Irrlicht has all code in many different files, so i guess it is nearly impossible to use the object loader and renderer without all the engine... unless I could merge these two functions...
1 -MD2 loader from "resonate" a 2008 PSP homebrew Game, does not load object normals. But it works with just 3 or 4 more functions inside the same file (image load, animation...):
Code: Select all
struct AnimMesh *md2Load(const char *filename)
{
struct AnimMesh *mesh=0;
MD2Model m;
memset(&m,0,sizeof(MD2Model));
FILE *file=fopen(filename,"rb");
if(!file) return 0;
MD2Header header;
fread(&header,sizeof(header),1,file);
// Copy the header attributes.
m.frameCount=header.numFrames;
m.glcmdCount=header.numGlcmds;
m.vertexCount=header.numVertices;
m.skinCount=header.numSkins;
m.texCoordCount=header.numSt;
m.triangleCount=header.numTris;
m.skinWidth=header.skinwidth;
m.skinHeight=header.skinheight;
fseek(file,header.offsetSkins,SEEK_SET);
m.skins=(MD2Skin *)malloc(sizeof(MD2Skin)*header.numSkins);
fread(m.skins,sizeof(MD2Skin),header.numSkins,file);
fseek(file,header.offsetSt,SEEK_SET);
m.texCoords=(MD2TexCoord *)malloc(sizeof(MD2TexCoord)*header.numSt);
fread(m.texCoords,sizeof(MD2TexCoord),header.numSt,file);
fseek(file,header.offsetTris,SEEK_SET);
m.triangles=(MD2Triangle *)malloc(sizeof(MD2Triangle)*header.numTris);
fread(m.triangles,sizeof(MD2Triangle),header.numTris,file);
fseek(file,header.offsetFrames,SEEK_SET);
m.frames=(MD2Frame *)malloc(sizeof(MD2Frame)*header.numFrames);
int i;
for(i=0;i<m.frameCount;i++) {
fread(m.frames+i,sizeof(MD2Frame)-4,1,file);
m.frames[i].verts=(MD2Vertex *)malloc(sizeof(MD2Vertex)*m.vertexCount);
fread(m.frames[i].verts,sizeof(MD2Vertex),m.vertexCount,file);
}
fseek(file,header.offsetGlcmds,SEEK_SET);
m.glcmds=(int *)malloc(sizeof(int)*header.numGlcmds);
fread(m.glcmds,sizeof(int),header.numGlcmds,file);
fclose(file);
// Convert to AnimMesh format
mesh=(struct AnimMesh *)malloc(sizeof(struct AnimMesh));
// mesh->texture=loadCell(m.skins[0].name);
mesh->texture=0;
mesh->frameCount=m.frameCount;
mesh->polyCount=m.triangleCount;
mesh->skinWidth=m.skinWidth;
mesh->skinHeight=m.skinHeight;
mesh->frames=malloc(mesh->frameCount*sizeof(struct AnimFrame));
for(i=0;i<mesh->frameCount;i++) {
frameToAnimMesh(&m,mesh,i);
}
// Clean up
if(m.skins) free(m.skins); m.skins=0;
if(m.texCoords) free(m.texCoords); m.texCoords=0;
if(m.triangles) free(m.triangles); m.triangles=0;
for(i=0;i<m.frameCount;i++) {
if(m.frames[i].verts) free(m.frames[i].verts);
}
if(m.frames) free(m.triangles); m.triangles=0;
if(m.glcmds) free(m.glcmds); m.glcmds=0;
return mesh;
}
Code: Select all
bool CAnimatedMeshMD2::loadFile(io::IReadFile* file)
{
if (!file)
return false;
s8* frames = 0;
file->read(&header, sizeof(SMD2Header));
#ifdef PPC
printf("" "PPC è attivo\n");
header.magic = OSReadSwapInt32(&header.magic,0);
header.version = OSReadSwapInt32(&header.version,0);
header.skinWidth = OSReadSwapInt32(&header.skinWidth,0);
header.skinHeight = OSReadSwapInt32(&header.skinHeight,0);
header.frameSize = OSReadSwapInt32(&header.frameSize,0);
header.numSkins = OSReadSwapInt32(&header.numSkins,0);
header.numVertices = OSReadSwapInt32(&header.numVertices,0);
header.numTexcoords = OSReadSwapInt32(&header.numTexcoords,0);
header.numTriangles = OSReadSwapInt32(&header.numTriangles,0);
header.numGlCommands = OSReadSwapInt32(&header.numGlCommands,0);
header.numFrames = OSReadSwapInt32(&header.numFrames,0);
header.offsetSkins = OSReadSwapInt32(&header.offsetSkins,0);
header.offsetTexcoords = OSReadSwapInt32(&header.offsetTexcoords,0);
header.offsetTriangles = OSReadSwapInt32(&header.offsetTriangles,0);
header.offsetFrames = OSReadSwapInt32(&header.offsetFrames,0);
header.offsetGlCommands = OSReadSwapInt32(&header.offsetGlCommands,0);
header.offsetEnd = OSReadSwapInt32(&header.offsetEnd,0);
#endif
if (header.magic != MD2_MAGIC_NUMBER || header.version != MD2_VERSION)
{
os::Printer::log("MD2 Loader: Wrong file header", file->getFileName(), ELL_WARNING);
return false;
}
// create Memory for indices and frames
Indices.reallocate(header.numTriangles);
//FrameList = new core::array<video::S3DVertex>[header.numFrames];
FrameCount = header.numFrames;
s32 i = 0;
// read TextureCoords
file->seek(header.offsetTexcoords, false);
textureCoords = new SMD2TextureCoordinate[header.numTexcoords];
if (!file->read(textureCoords, sizeof(SMD2TextureCoordinate)*header.numTexcoords))
{
os::Printer::log("MD2 Loader: Error reading TextureCoords.", file->getFileName(), ELL_ERROR);
return false;
}
// read Triangles
file->seek(header.offsetTriangles, false);
triangles = new SMD2Triangle[header.numTriangles];
if (!file->read(triangles, header.numTriangles *sizeof(SMD2Triangle)))
{
os::Printer::log("MD2 Loader: Error reading triangles.", file->getFileName(), ELL_ERROR);
return false;
}
// read Vertices
s8 buffer[MD2_MAX_VERTS*4+128];
frame = (SMD2Frame*)buffer;
vertices = new core::array< core::vector3df >[header.numFrames];
normals = new core::array< core::vector3df >[header.numFrames];
file->seek(header.offsetFrames, false);
for (i = 0; i<header.numFrames; ++i)
{
// read vertices
vertices[i].reallocate(header.numVertices);
file->read(frame, header.frameSize);
// store frame data
SFrameData fdata;
fdata.begin = i;
fdata.end = i;
fdata.fps = 7;
if (frame->name[0])
{
for (s32 s = 0; frame->name[s]!=0 && (frame->name[s] < '0' ||
frame->name[s] > '9'); ++s)
fdata.name += frame->name[s];
if (!FrameData.empty() && FrameData[FrameData.size()-1].name == fdata.name)
++FrameData[FrameData.size()-1].end;
else
FrameData.push_back(fdata);
}
// add vertices
for (s32 j=0; j<header.numVertices; ++j)
{
core::vector3df v;
v.X = (f32)frame->vertices[j].vertex[0] * frame->scale[0] + frame->translate[0];
v.Z = (f32)frame->vertices[j].vertex[1] * frame->scale[1] + frame->translate[1];
v.Y = (f32)frame->vertices[j].vertex[2] * frame->scale[2] + frame->translate[2];
vertices[i].push_back(v);
s32 normalidx = frame->vertices[j].lightNormalIndex;
if (normalidx > 0 && normalidx < Q2_VERTEX_NORMAL_TABLE_SIZE)
{
v.X = Q2_VERTEX_NORMAL_TABLE[normalidx][0];
v.Y = Q2_VERTEX_NORMAL_TABLE[normalidx][1];
v.Z = Q2_VERTEX_NORMAL_TABLE[normalidx][2];
}
normals[i].push_back(v);
}
// calculate bounding boxes
if (header.numVertices)
{
core::aabbox3d<f32> box;
box.reset(vertices[i][0]);
for (s32 j=1; j<header.numVertices; ++j)
box.addInternalPoint(vertices[i][j]);
BoxList.push_back(box);
}
}
// put triangles into frame list
dmaxs = 1.0f/(header.skinWidth);
dmaxt = 1.0f/(header.skinHeight);
// create indices
Indices.reallocate(header.numVertices);
s32 count = header.numTriangles*3;
for (s32 n=0; n<count; n+=3)
{
Indices.push_back(n);
Indices.push_back(n+1);
Indices.push_back(n+2);
}
//calculateNormals();
video::S3DVertex vtx;
vtx.Color = video::SColor(255,255,255,255);
// reallocate interpolate buffer
if (header.numFrames)
{
core::array<video::S3DVertex> p = getFrameList(0);
InterpolateBuffer = new core::array<video::S3DVertex>;
InterpolateBuffer->set_used(p.size());
s32 count = p.size();
for (i=0; i<count; ++i)
{
InterpolateBuffer->pointer()[i].TCoords = p.pointer()[i].TCoords;
InterpolateBuffer->pointer()[i].Color = vtx.Color.toOpenGLColor();
}
}
TriangleCount = Indices.size() / 3;
// return
calculateBoundingBox();
return true;
}
Last edited by Mills on Sun Aug 09, 2015 9:30 pm, edited 1 time in total.
Re: Using part of the engine source (MD2 and X model loader)
You can compute normals yourself
Junior Irrlicht Developer.
Real value in social networks is not about "increasing" number of followers, but about getting in touch with Amazing people.
- by Me
Real value in social networks is not about "increasing" number of followers, but about getting in touch with Amazing people.
- by Me
Re: Using part of the engine source (MD2 and X model loader)
Hi again, MD2 models did not work well on PSP... so now i'm foccused on .X models
I just want to know, where is the source with the function to load animated models in .X format?
Thanks again.
I just want to know, where is the source with the function to load animated models in .X format?
Thanks again.
Re: Using part of the engine source (MD2 and X model loader)
The source is in CXMeshFileLoader.cpp/.h
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm