208 lines
5.6 KiB
C++
208 lines
5.6 KiB
C++
#include<hgl/graph/SceneDB.h>
|
|
#include<hgl/graph/SceneNode.h>
|
|
#include<hgl/graph/Material.h>
|
|
#include<hgl/graph/Mesh.h>
|
|
#include<hgl/io/FileInputStream.h>
|
|
#include<hgl/io/DataInputStream.h>
|
|
#include<hgl/filesystem/FileSystem.h>
|
|
#include<hgl/log/LogInfo.h>
|
|
|
|
namespace hgl
|
|
{
|
|
namespace graph
|
|
{
|
|
bool LoadMaterialFile(MaterialData &md,const OSString &filename);
|
|
bool LoadMeshFile(MeshFileHeader &md,const OSString &filename,MaterialData *md_list);
|
|
|
|
namespace
|
|
{
|
|
class SceneLoader
|
|
{
|
|
SceneDB *db;
|
|
SceneNode *root_node;
|
|
|
|
OSString main_filename;
|
|
|
|
uint32 tex_count=0;
|
|
|
|
private:
|
|
|
|
uint32 mtl_count=0;
|
|
MaterialData *md_list;
|
|
|
|
void LoadMaterial()
|
|
{
|
|
md_list=new MaterialData[mtl_count];
|
|
|
|
for(int i=0;i<mtl_count;i++)
|
|
LoadMaterialFile(md_list[i],main_filename+OS_TEXT(".")+OSString(i)+OS_TEXT(".material"));
|
|
}
|
|
|
|
private:
|
|
|
|
uint32 mesh_count=0;
|
|
MeshData *mesh_list;
|
|
|
|
void LoadMesh()
|
|
{
|
|
mesh_list=new MeshData[mesh_count];
|
|
|
|
for(int i=0;i<mesh_count;i++)
|
|
LoadMeshFile(mesh_list[i],main_filename+OS_TEXT(".")+OSString(i)+OS_TEXT(".mesh"),md_list);
|
|
}
|
|
|
|
private:
|
|
|
|
void AddMesh(SceneNode *node,const uint32 *mesh_index,const uint32 count)
|
|
{
|
|
//for(int i=0;i<count;i++)
|
|
// node->Add(mesh_list[mesh_index[i]]);
|
|
}
|
|
|
|
bool LoadScene(SceneNode *node,io::DataInputStream *dis)
|
|
{
|
|
UTF8String node_name;
|
|
|
|
if(!dis->ReadUTF8String(node_name))
|
|
RETURN_FALSE;
|
|
|
|
//bounding box
|
|
{
|
|
float box[6];
|
|
|
|
if(dis->ReadFloat(box,6)!=6)
|
|
RETURN_FALSE;
|
|
|
|
vec bb_min(box[0],box[1],box[2],1);
|
|
vec bb_max(box[3],box[4],box[5],1);
|
|
|
|
AABB bb(bb_min,bb_max);
|
|
|
|
node->SetBoundingBox(bb);
|
|
}
|
|
|
|
//matrix
|
|
{
|
|
Matrix4f mat;
|
|
|
|
if(dis->ReadFloat((float *)&mat,16)!=16)
|
|
RETURN_FALSE;
|
|
|
|
node->SetLocalMatrix(mat);
|
|
}
|
|
|
|
//mesh
|
|
{
|
|
uint32 count;
|
|
|
|
if(!dis->ReadUint32(count))
|
|
RETURN_FALSE;
|
|
|
|
uint32 *index=new uint32[count];
|
|
|
|
if(dis->ReadUint32(index,count)!=count)
|
|
{
|
|
delete[] index;
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
AddMesh(node,index,count);
|
|
|
|
delete[] index;
|
|
}//mesh
|
|
|
|
//children
|
|
{
|
|
uint32 children_count;
|
|
|
|
if(!dis->ReadUint32(children_count))
|
|
RETURN_FALSE;
|
|
|
|
for(uint32 i=0;i<children_count;i++)
|
|
{
|
|
SceneNode *sub_node=new SceneNode;
|
|
|
|
if(!LoadScene(sub_node,dis))
|
|
{
|
|
delete sub_node;
|
|
RETURN_FALSE;
|
|
}
|
|
|
|
node->Add(sub_node);
|
|
}
|
|
}//children
|
|
|
|
return(true);
|
|
}
|
|
|
|
public:
|
|
|
|
SceneLoader(SceneDB *sdb,SceneNode *rn)
|
|
{
|
|
db=sdb;
|
|
root_node=rn;
|
|
}
|
|
|
|
bool Load(const OSString &mn,io::DataInputStream *dis)
|
|
{
|
|
main_filename=mn;
|
|
|
|
uint8 flag[6],ver;
|
|
|
|
if(dis->ReadFully(flag,6)!=6)
|
|
RETURN_FALSE;
|
|
|
|
if(memcmp(flag,"SCENE\x1A",6))
|
|
RETURN_FALSE;
|
|
|
|
if(!dis->ReadUint8(ver))
|
|
RETURN_FALSE;
|
|
|
|
if(ver!=1)
|
|
RETURN_FALSE;
|
|
|
|
if(!dis->ReadUint32(mtl_count))
|
|
RETURN_FALSE;
|
|
|
|
if(!dis->ReadUint32(tex_count))
|
|
RETURN_FALSE;
|
|
|
|
// LoadTextures();
|
|
LoadMaterial();
|
|
|
|
if(!dis->ReadUint32(mesh_count))
|
|
RETURN_FALSE;
|
|
|
|
LoadMesh();
|
|
|
|
return LoadScene(root_node,dis);
|
|
}
|
|
};//class SceneLoader
|
|
}//namespace
|
|
|
|
SceneNode *LoadScene(const OSString &fullname,SceneDB *db)
|
|
{
|
|
io::OpenFileInputStream fis(fullname);
|
|
|
|
if(!fis)
|
|
return(nullptr);
|
|
|
|
SceneNode *root=new SceneNode;
|
|
io::LEDataInputStream *dis=new io::LEDataInputStream(&fis);
|
|
|
|
SceneLoader sl(db,root);
|
|
|
|
const OSString filename=filesystem::ClipFileMainname(fullname);
|
|
|
|
if(!sl.Load(filename,dis))
|
|
{
|
|
delete root;
|
|
root=nullptr;
|
|
}
|
|
|
|
delete dis;
|
|
return root;
|
|
}
|
|
}//namespace graph
|
|
}//namespace hgl
|