#include <string>
#include <vector>
using namespace std;
//3つのベクトル
struct Vector3f{
float x;
float y;
float z;
};
//4つのベクトル
struct Vector4f{
float x;
float y;
float z;
float w;
};
//4つの反射
struct Reflection4{
float diffuse;
float ambient;
float emission;
float specular;
};
//4つのカラー
struct Color4{
float r;
float g;
float b;
float a;
};
//UV座標
struct UV{
float u;//u値
float v;//v値
};
//面情報構造体
struct TRIANGLE{
int MaterialID;//マテリアルNo.
int Index[3];//インデックス
UV uv[3];//UV情報
}tri;
struct QUADRILATERAL{
int MaterialID;//マテリアルNo.
int Index[4];//インデックス
UV uv[4];//UV情報
}quad;
//オブジェクト構造体
struct OBJECT{
string Name;//オブジェクト名
vector<Vector3f> Vertex;//頂点データ
vector<TRIANGLE> Triangle;//3角面データ
vector<QUADRILATERAL> Quadrilateral;//4角面データ
}obj;
//マテリアル構造体
struct MATERIAL{
int MaterialID;//ID
string MaterialName;//マテリアル名
Color4 Color;//カラー
Reflection4 ReflectionColor;//反射
float Power;//shiness
string TextureName;//テクスチャ名
}mtl;
//モデルクラス
class MODEL{
protected:
FILE* fp;//ファイルポインタ
char buf[255];//読み込み用バッファ
string str;
void Vertex_Set();//頂点情報セット
void Material_Set();//マテリアル情報セット
void Face_Set();//面情報セット
string Split(string* str,char str1,char str2);//文字列分離
public:
MODEL();
MODEL(char* FileName);
vector<MATERIAL> Material;//マテリアル
vector<OBJECT> Object;//オブジェクトデータ
bool MQO_Load(char* FileName);//ロード
void PrintParam();
};
MODEL::MODEL(){
}
MODEL::MODEL(char* FileName){
MQO_Load(FileName);
}
//文字列分離
string MODEL::Split(string *str, char str1, char str2){
string::size_type start = str->find(str1);
string::size_type end = str->rfind(str2);
return str->substr(start+1,end-start-1);
}
//パラメータをプリント
void MODEL::PrintParam(){
printf("%s\n",Object[0].Name.c_str());
for(int i=0;i<(signed)Object[0].Vertex.size();i++){
printf("%.4f %.4f
%.4f\n",Object[0].Vertex[i].x,Object[0].Vertex[i].y,Object[0].Vertex[i].z);
}
printf("%.5f\n",Object[0].Triangle[0].uv[0].u);
printf("%s\n",Material[0].MaterialName.c_str());
printf("%f %f %f %f\n",Material[0].Color.r, Material[0].Color.g,
Material[0].Color.b, Material[0].Color.a);
printf("%f\n", Material[0].ReflectionColor.diffuse);
printf("%f\n", Material[0].ReflectionColor.ambient);
printf("%f\n", Material[0].ReflectionColor.emission);
printf("%f\n", Material[0].ReflectionColor.specular);
printf("%s\n", Material[0].TextureName.c_str());
printf("%d\n", Object.size());
printf("読み込み成功\n");
}
//マテリアルセット
void MODEL::Material_Set(){
Material.push_back(mtl);
fscanf_s(fp, "%d",
&Material[Material.size()-1].MaterialID);//マテリアルナンバー格納
fscanf_s(fp, "%s", buf,255);//"{"を読み飛ばす
fscanf_s(fp, "%s", buf,255);//マテリアル名格納
str=buf;
Material[Material.size()-1].MaterialName=Split(&str,'\"','\"');//""を除去
fgets(buf,255,fp);
char* buf2;
if((buf2 = strstr(buf,"col(")) != NULL ){//マテリアルカラー格納
sscanf_s(buf2,"col(%f %f %f %f)", &Material[Material.size()-1].Color.r,
&Material[Material.size()-1].Color.g,
&Material[Material.size()-1].Color.b,
&Material[Material.size()-1].Color.a);
}
if((buf2 = strstr(buf,"dif(")) != NULL ){//ディフューズ格納
sscanf_s(buf2,"dif(%f)",
&Material[Material.size()-1].ReflectionColor.diffuse);
}
if((buf2 = strstr(buf,"amb(")) != NULL ){//アンビエント格納
sscanf_s(buf2,"amb(%f)",
&Material[Material.size()-1].ReflectionColor.ambient);
}
if((buf2 = strstr(buf,"emi(")) != NULL ){//エミッション格納
sscanf_s(buf2,"emi(%f)",
&Material[Material.size()-1].ReflectionColor.emission);
}
if((buf2 = strstr(buf,"spc(")) != NULL ){//スペキュラー格納
sscanf_s(buf2,"spc(%f)",
&Material[Material.size()-1].ReflectionColor.specular);
}
if((buf2 = strstr(buf,"power(")) != NULL ){//shiness格納
sscanf_s(buf2,"power(%f)", &Material[Material.size()-1].Power);
}
if((buf2 = strstr(buf,"tex(")) != NULL ){//テクスチャ名格納
sscanf_s(buf2,"tex(%[^)])",buf,255);
str=buf;
Material[Material.size()-1].TextureName=Split(&str,'\"','\"');//""を除去
}
}
//頂点情報セット
void MODEL::Vertex_Set(){
int Vertex_Max;
Vector3f v;
fscanf_s(fp, "%d", &Vertex_Max);//頂点数取得
fscanf_s(fp, "%s", buf,255);//"{"を読み飛ばす
for(int i=0;i<Vertex_Max;i++){
fscanf_s(fp,"%f %f %f",&v.x,&v.y,&v.z);
Object[Object.size()-1].Vertex.push_back(v);
}
fscanf_s(fp, "%s", buf,255);//"}"を読み飛ばす
fscanf_s(fp, "%s", buf,255);
}
//面情報セット
void MODEL::Face_Set(){
int Face_Max;
int Face;
char* buf2;
fscanf_s(fp, "%d", &Face_Max);//面数取得
fscanf_s(fp, "%s", buf,255);//"{"を読み飛ばす
for(int i=0;i<Face_Max;i++){
fscanf_s(fp, "%d", &Face);
if(Face==3){
Object[Object.size()-1].Triangle.push_back(tri);
fgets(buf,255,fp);
if((buf2 = strstr(buf,"V(")) != NULL ){
sscanf_s(buf2,"V(%d %d %d)",
&Object[Object.size()-1].Triangle[Object[Object.size()-1].Triangle.size()-1].Index[0],
&Object[Object.size()-1].Triangle[Object[Object.size()-1].Triangle.size()-1].Index[1],
&Object[Object.size()-1].Triangle[Object[Object.size()-1].Triangle.size()-1].Index[2]);
}
if((buf2 = strstr(buf,"M(")) != NULL ){
sscanf_s(buf2,"M(%d)",
&Object[Object.size()-1].Triangle[Object[Object.size()-1].Triangle.size()-1].MaterialID);
}
if((buf2 = strstr(buf,"UV(")) != NULL ){
sscanf_s(buf2,"UV(%f %f %f %f %f %f)",
&Object[Object.size()-1].Triangle[Object[Object.size()-1].Triangle.size()-1].uv[0].u,
&Object[Object.size()-1].Triangle[Object[Object.size()-1].Triangle.size()-1].uv[0].v,
&Object[Object.size()-1].Triangle[Object[Object.size()-1].Triangle.size()-1].uv[1].u,
&Object[Object.size()-1].Triangle[Object[Object.size()-1].Triangle.size()-1].uv[1].v,
&Object[Object.size()-1].Triangle[Object[Object.size()-1].Triangle.size()-1].uv[2].u,
&Object[Object.size()-1].Triangle[Object[Object.size()-1].Triangle.size()-1].uv[2].v);
}
}
if(Face==4){
Object[Object.size()-1].Quadrilateral.push_back(quad);
fgets(buf,255,fp);
if((buf2 = strstr(buf,"V(")) != NULL ){
sscanf_s(buf2,"V(%d %d %d %d)",
&Object[Object.size()-1].Quadrilateral[Object[Object.size()-1].Quadrilateral.size()-1].Index[0],
&Object[Object.size()-1].Quadrilateral[Object[Object.size()-1].Quadrilateral.size()-1].Index[1],
&Object[Object.size()-1].Quadrilateral[Object[Object.size()-1].Quadrilateral.size()-1].Index[2],
&Object[Object.size()-1].Quadrilateral[Object[Object.size()-1].Quadrilateral.size()-1].Index[3]);
}
if((buf2 = strstr(buf,"M(")) != NULL ){
sscanf_s(buf2,"M(%d)",
&Object[Object.size()-1].Quadrilateral[Object[Object.size()-1].Quadrilateral.size()-1].MaterialID);
}
if((buf2 = strstr(buf,"UV(")) != NULL ){
sscanf_s(buf2,"UV(%f %f %f %f %f %f %f %f)",
&Object[Object.size()-1].Quadrilateral[Object[Object.size()-1].Quadrilateral.size()-1].uv[0].u,
&Object[Object.size()-1].Quadrilateral[Object[Object.size()-1].Quadrilateral.size()-1].uv[0].v,
&Object[Object.size()-1].Quadrilateral[Object[Object.size()-1].Quadrilateral.size()-1].uv[1].u,
&Object[Object.size()-1].Quadrilateral[Object[Object.size()-1].Quadrilateral.size()-1].uv[1].v,
&Object[Object.size()-1].Quadrilateral[Object[Object.size()-1].Quadrilateral.size()-1].uv[2].u,
&Object[Object.size()-1].Quadrilateral[Object[Object.size()-1].Quadrilateral.size()-1].uv[2].v,
&Object[Object.size()-1].Quadrilateral[Object[Object.size()-1].Quadrilateral.size()-1].uv[3].u,
&Object[Object.size()-1].Quadrilateral[Object[Object.size()-1].Quadrilateral.size()-1].uv[3].v);
}
}
}
fscanf_s(fp, "%s", buf,255);//"}"を読み飛ばす
fscanf_s(fp, "%s", buf,255);
}
//メタセコイアファイル読み込み
bool MODEL::MQO_Load(char* FileName){
if(fopen_s(&fp,FileName, "r")!=0){return false;}
while (!feof(fp)) {
fscanf_s(fp, "%s", buf,255);
if (!strcmp(buf,"Material")){Material_Set();}
if (!strcmp(buf,"Object")){
Object.push_back(obj);
fscanf_s(fp, "%s", buf,255);
Object[Object.size()-1].Name=buf;
while (!feof(fp)) {
fscanf_s(fp, "%s", buf,255);
if (!strcmp(buf,"vertex")){Vertex_Set();}
if (!strcmp(buf,"face")){Face_Set();}
if (!strcmp(buf,"}"))break;
}
}
}
fclose(fp);
return true;
}
MODEL *model;
void main()
{
model=new MODEL("sample.mqo");
model->PrintParam();
getchar();
}
|