Files
wagic/JGE/src/JOBJModel.cpp
jean.chalard ddf04e14e8 J :
* Update for linux support.
2008-11-05 13:38:39 +00:00

223 lines
5.3 KiB
C++

//-------------------------------------------------------------------------------------
//
// JGE++ is a hardware accelerated 2D game SDK for PSP/Windows.
//
// Licensed under the BSD license, see LICENSE in JGE root for details.
//
// Copyright (c) 2007 James Hui (a.k.a. Dr.Watson) <jhkhui@gmail.com>
//
//-------------------------------------------------------------------------------------
#include "../include/JTypes.h"
#include "../include/JFileSystem.h"
#include "../include/JRenderer.h"
#include "../include/JOBJModel.h"
JOBJModel::JOBJModel()
{
mPolygons = NULL;
mTexture = NULL;
}
JOBJModel::~JOBJModel()
{
if (mPolygons)
delete [] mPolygons;
if (mTexture)
delete mTexture;
}
int JOBJModel::ReadLine(char *output, const char *buffer, int start, int size)
{
int index = 0;
while (start < size && buffer[start] != '\n' && buffer[start] != '\r')
output[index++] = buffer[start++];
while ((start < size && buffer[start] == '\n') || buffer[start] == '\r')
start++;
output[index] = 0;
return start;
}
bool JOBJModel::Load(const char *modelName, const char *textureName)
{
JFileSystem* fileSys = JFileSystem::GetInstance();
if (!fileSys->OpenFile(modelName))
return false;
int size = fileSys->GetFileSize();
char *buffer = new char[size];
fileSys->ReadFile(buffer, size);
fileSys->CloseFile();
Vector3D vert;
vector<Face> faceList;
vector<Vector3D> normalList;
vector<Vector3D> texList;
vector<Vector3D> vertList;
normalList.reserve(32);
texList.reserve(32);
vertList.reserve(32);
faceList.reserve(32);
int filePtr = 0;
char tmpLine[256];
char s1[256];
int count;
while (filePtr < size)
{
filePtr = ReadLine(tmpLine, buffer, filePtr, size);
{
if ((tmpLine[0] == '#') || (strlen(tmpLine) < 3))
{
}
else if (tmpLine[0] == 'v')
{
count = sscanf(tmpLine, "%s %f %f %f", s1, &vert.x, &vert.y, &vert.z);
if (count == 4)
{
if (strcmp(s1, "vn") == 0)
normalList.push_back(vert);
else if (strcmp(s1, "vt") == 0)
texList.push_back(vert);
else if (strcmp(s1, "v") == 0)
vertList.push_back(vert);
}
else if (count == 3)
{
if (strcmp(s1, "vt") == 0)
texList.push_back(vert);
}
}
else if (tmpLine[0] == 'f')
{
Face face;
face.mVertCount = 0;
char *p = strchr(tmpLine, ' ');
char *pNext = p;
int vertIdx, texIdx, norIdx;
while (p != NULL)
{
while (((*p) == ' ') || ((*p) == '\n') || ((*p) == '\t'))
++p;
strcpy(s1, p);
count = sscanf(s1, "%d/%d/%d", &vertIdx, &texIdx, &norIdx);
if (count == 3)
{
if (face.mVertCount < 4)
{
face.mVertIdx[face.mVertCount] = vertIdx - 1;
face.mTexIdx[face.mVertCount] = texIdx - 1;
face.mNormalIdx[face.mVertCount] = norIdx - 1;
face.mVertCount++;
}
}
else if (count == 2)
{
if (face.mVertCount < 4)
{
face.mVertIdx[face.mVertCount] = vertIdx - 1;
face.mTexIdx[face.mVertCount] = texIdx - 1;
face.mNormalIdx[face.mVertCount] = 0;
face.mVertCount++;
}
}
else if (count == 1)
{
if (face.mVertCount < 4)
{
face.mVertIdx[face.mVertCount] = vertIdx - 1;
face.mTexIdx[face.mVertCount] = 0;
face.mNormalIdx[face.mVertCount] = 0;
face.mVertCount++;
}
}
pNext = strchr(p, ' ');
p = pNext;
}
if (face.mVertCount == 3) // we do triangles only ;)
faceList.push_back(face);
}
else if (tmpLine[0] == 'g')
{
}
else if (tmpLine[0] == 'u')
{
}
}
}
mPolycount = faceList.size();
mPolygons = new Vertex3D[mPolycount*3];
int idx = 0;
for (int i=0;i<mPolycount;i++)
{
for (int j=0;j<3;j++)
{
mPolygons[idx].u = texList[faceList[i].mTexIdx[j]].x;
mPolygons[idx].v = 1.0f-texList[faceList[i].mTexIdx[j]].y;
mPolygons[idx].x = vertList[faceList[i].mVertIdx[j]].x;
mPolygons[idx].y = vertList[faceList[i].mVertIdx[j]].y;
mPolygons[idx].z = vertList[faceList[i].mVertIdx[j]].z;
idx++;
}
/*
mPolygons[idx].u = texList[faceList[i].mTexIdx[0]].x;
mPolygons[idx].v = 1.0-texList[faceList[i].mTexIdx[0]].y;
mPolygons[idx].x = vertList[faceList[i].mVertIdx[0]].x;
mPolygons[idx].y = vertList[faceList[i].mVertIdx[0]].y;
mPolygons[idx].z = vertList[faceList[i].mVertIdx[0]].z;
idx++;
mPolygons[idx].u = texList[faceList[i].mTexIdx[1]].x;
mPolygons[idx].v = 1.0-texList[faceList[i].mTexIdx[1]].y;
mPolygons[idx].x = vertList[faceList[i].mVertIdx[1]].x;
mPolygons[idx].y = vertList[faceList[i].mVertIdx[1]].y;
mPolygons[idx].z = vertList[faceList[i].mVertIdx[1]].z;
idx++;
mPolygons[idx].u = texList[faceList[i].mTexIdx[2]].x;
mPolygons[idx].v = 1.0-texList[faceList[i].mTexIdx[2]].y;
mPolygons[idx].x = vertList[faceList[i].mVertIdx[2]].x;
mPolygons[idx].y = vertList[faceList[i].mVertIdx[2]].y;
mPolygons[idx].z = vertList[faceList[i].mVertIdx[2]].z;
idx++;
*/
}
if (textureName != NULL)
mTexture = JRenderer::GetInstance()->LoadTexture(textureName);
return true;
}
void JOBJModel::Render()
{
JRenderer::GetInstance()->RenderTriangles(mTexture, mPolygons, 0, mPolycount);
}